From 78726006f2bbf331427637376b1ee9aa6faf73bb Mon Sep 17 00:00:00 2001 From: Kyle Brown Date: Tue, 2 Aug 2022 10:36:37 -0400 Subject: [PATCH 1/2] Typed Main Proposal Add a Typed Main proposal to the component model. --- design/mvp/TypedMain.md | 115 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 design/mvp/TypedMain.md diff --git a/design/mvp/TypedMain.md b/design/mvp/TypedMain.md new file mode 100644 index 00000000..2d318035 --- /dev/null +++ b/design/mvp/TypedMain.md @@ -0,0 +1,115 @@ +# Typed Main + +Previous WASI Command APIs were not able to strongly type the resource and data inputs to commands and instead relied on functions for reading command line arguments and environment variables. + +Typed Main enables components to define value imports for their arguments (including file resources) and environment variables allowing the host to parse and validate them for the component. + +This proposal defines a way to infer the command line arguments names, ordering, etc. from the component type (represented here in [WIT](https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md)) and optionally augmenting this with annotated info (represented here as [Structured Annotations](https://github.com/WebAssembly/component-model/issues/58)). The anotation information will be encoded in a custom section in a not-yet-specified way. + +## Arguments +* Value imports are can be supplied as positional arguments in the order they are defined +* Value imports can be supplied as long-form named arguments with their defined name +* The ordering of named arguments with respect to each other and positional arguments is not constrained +* If a named argument is present, parsing of positional argument skips over it to the next position + +```rust +input: string +pattern: string +replace: string +``` + +### Usage +``` +$ replace "some-thing" "-" "_" +$ replace --input "some-thing" --pattern "-" --replace "_" +$ replace --pattern "-" --replace "_" "some-thing" +``` + +## File Preopen Arguments +* If the type of a value import is a WASI file, the host reads the corresponding argument as a path and preopens it. +* The preopen must occur even for file paths which do not exist (as long as their parent does), so that output file paths can be supported. + +```rust +import { file } from ... + +input: file +output: file +``` + +### Usage +```bash +$ copy ./input.txt --output ./output.txt +``` + +## Optional Arguments +* Value imports with type `option` are optional arguments +* If an optional argument is not provided, the value import takes value `none` +* All arguments defined after an optional argument must be optional + +```rust +import { file } from ... + +input: file +output: option +``` + +### Usage +```bash +$ foo ./input.txt ./output.txt +$ foo ./input.txt +``` + +## Flags +* Value imports with type `bool` inferred to be flags. +* Flags have value `true` if present and `false` if absent. +* By default, flags are "long" + * Equivalent to annotation `@flag(long)` + * Specified in long form with no associated value e.g. `--foobar` + * Name is inferred to be the value import name + * Name can be explicitly set `@flag(long = "foobar")` + * Does not support grouping +* Flags can annotated as "short" + * Using annotation `@flag(short)` + * Specified in short form with no associated value e.g.`-f` + * Name is inferred to be first character of value import name + * Name can be explicitly set `@flag(short = "f")` + * Supports grouping `-a -b -c` = `-abc` +* Flag can be short and long `@flag(short, long)`, value `true` if either are present + +```rust +@flag(short) +help: bool + +verbose: bool + +@flag(short = "x", long) +execute: bool +``` + +### Usage +```bash +$ foo -h +$ foo --verbose +$ foo -x +$ foo --execute -x --verbose +``` + +## Short Named Arguments +* By default named arguments are "long" (inferred as `@arg(pos, named, long)`). +* By annotating them with with the `short` parameter, they can be used in short form e.g. `-i` +* Name inference and manual assignment works the same as flags + +```rust +import { file } from ... + +input: file + +@arg(named, short, long) +output: option +``` + +### Usage +```bash +$ foo ./input.txt --output ./output.txt +$ foo ./input.txt -o ./output.txt +``` From c24f61b3d697aba7ea5726a9a2f771c3b6101b9d Mon Sep 17 00:00:00 2001 From: Kyle Brown Date: Wed, 3 Aug 2022 10:18:35 -0400 Subject: [PATCH 2/2] Render Luke's suggestions --- design/mvp/{TypedMain.md => CLIEmbedding.md} | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename design/mvp/{TypedMain.md => CLIEmbedding.md} (73%) diff --git a/design/mvp/TypedMain.md b/design/mvp/CLIEmbedding.md similarity index 73% rename from design/mvp/TypedMain.md rename to design/mvp/CLIEmbedding.md index 2d318035..0f55c831 100644 --- a/design/mvp/TypedMain.md +++ b/design/mvp/CLIEmbedding.md @@ -1,10 +1,10 @@ # Typed Main -Previous WASI Command APIs were not able to strongly type the resource and data inputs to commands and instead relied on functions for reading command line arguments and environment variables. +A high-level goal of the component model is the ability to run a single component portably on various hosts. One such embedding is a classic Unix-style Command-Line Interface (CLI) accepting positional/named arguments. -Typed Main enables components to define value imports for their arguments (including file resources) and environment variables allowing the host to parse and validate them for the component. +This document describes how a component can be generically interpreted by a component-enabled CLI to allow components to be directly instantiated and invoked from the command line in an idiomatic manner, corresponding to use case #2 of [invoking component exports](https://github.com/WebAssembly/component-model/blob/main/design/high-level/UseCases.md#invoking-component-exports-from-the-host). It also defines annotations which can be used to extend the default interpretation of a component to specify CLI-specific features (e.g. short flag names). -This proposal defines a way to infer the command line arguments names, ordering, etc. from the component type (represented here in [WIT](https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md)) and optionally augmenting this with annotated info (represented here as [Structured Annotations](https://github.com/WebAssembly/component-model/issues/58)). The anotation information will be encoded in a custom section in a not-yet-specified way. +The component type is specified here in terms of a [`*.wit`](https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md) interface and annotations as [Structured Annotations](https://github.com/WebAssembly/component-model/issues/58). ## Arguments * Value imports are can be supplied as positional arguments in the order they are defined