Skip to content

Commit

Permalink
Docs improvements (#979)
Browse files Browse the repository at this point in the history
* docs updates

* add linux-x64 rid to dotnet-suggest
  • Loading branch information
jonsequitur authored Jul 21, 2020
1 parent 4c1f1df commit f2556ca
Show file tree
Hide file tree
Showing 25 changed files with 374 additions and 214 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ Next, install the `dotnet try` global tool:
Finally, launch the `dotnet try` pointing to the tutorial directory inside the cloned repository:

```console
> dotnet try <PATH_TO_COMMAND_LINE_API_REPO>/samples/tutorial
> dotnet try <PATH_TO_COMMAND_LINE_API_REPO>/docs
```

## Code of Conduct
Expand Down
3 changes: 2 additions & 1 deletion docs/DragonFruit-overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ Options:

## Arguments

In addition to [options](Syntax-Concepts-and-Parser#Options) as shown in the examples above, DragonFruit also supports [arguments](Syntax-Concepts-and-Parser#Arguments). By convention, if you name a parameter in the `Main` method `args`, `argument`, or `arguments`, it will be exposed as an argument rather than an option.
In addition to [options](Syntax-Concepts-and-Parser#Options) as shown in the examples above, DragonFruit also supports [arguments](Syntax-Concepts-and-Parser#Arguments). By convention, if you name a parameter in the `Main` method `args`, `argument`, or `arguments`, it will be exposed as an argument rather than an option.

```csharp
static void Main(int intOption = 42, string[] args = null)
Expand Down Expand Up @@ -106,3 +106,4 @@ Options:
The argument follows the same conventions for arity as described in [arguments](Syntax-Concepts-and-Parser.md#Arguments-and-arity).

You can try out DragonFruit by installing the latest preview [package](https://www.nuget.org/packages/System.CommandLine.DragonFruit).

27 changes: 14 additions & 13 deletions docs/Features-overview.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
`System.CommandLine` provides a set of default features for both people using it to develop apps and for the users of those apps. This is a quick overview of some of those features.
`System.CommandLine` provides a set of default features for both people using it to develop apps and for the users of those apps. This is a quick overview of some of those features.

# Suggestions

Programs written using `System.CommandLine` have built-in support for tab completion.
Programs written using `System.CommandLine` have built-in support for tab completion.

![t-rex-suggestions](https://user-images.githubusercontent.com/547415/50387753-ef4c1280-06b8-11e9-90c8-89466d0bb406.gif)

To enable it, the end user has to take a few steps once per shell, outlined [here](dotnet-suggest). Once this is done, completions will work for all apps written using `System.CommandLine`.
To enable it, the end user has to take a few steps once per shell, outlined [here](dotnet-suggest.md). Once this is done, completions will work for all apps written using `System.CommandLine`.

# Help

Expand Down Expand Up @@ -38,7 +38,7 @@ Users might be accustomed to different prefixes in different ecosystems, especia

Providing a way to check the version of your app is helpful to your users.

`System.CommandLine` provides this by default. In the [help](Features-overview#Help) example you might have noticed an option, `--version`, that was not explicitly configured in the sample code. When you run your program with this option, you'll see something like this:
`System.CommandLine` provides this by default. In the [help](Features-overview.md#Help) example you might have noticed an option, `--version`, that was not explicitly configured in the sample code. When you run your program with this option, you'll see something like this:

```console
> myapp --version
Expand All @@ -56,7 +56,7 @@ Both users and developers often find it useful to see how an app will interpret

The `[parse]` directive tells the parser to parse the input and return a diagram of the result. Some things worth noting in the above example:

* Commands (`myapp`), their child options, and the arguments to those options are grouped using square brackets.
* Commands (`myapp`), their child options, and the arguments to those options are grouped using square brackets.
* For the option result `![ --int-option <not-an-int> ]`, the `!` indicates a parsing error. `not-an-int` could not be parsed to the expected type.
* For the option result `*[ --bool-option <False> ]`, the `*` indicates that a value was not specified on the command line, so the parser's configured default was used. `False` is the effective value for this option.

Expand All @@ -83,17 +83,17 @@ One or more response files can be specified in this way. Arguments and options a

# Adaptive rendering

ANSI terminals support a variety of features by including ANSI escape sequences in standard input and output. These sequences can control the cursor, set text attributes and colors, and more. Windows [recently joined](https://blogs.msdn.microsoft.com/commandline/2018/06/27/windows-command-line-the-evolution-of-the-windows-command-line/) Linux and Mac in supporting these features. This is a capability of the new Windows Terminal and can be enabled programmatically in the Windows 10 Console.
Many terminals support a variety of features by including [virtual terminal (VT) escape sequences](https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences) in standard input and output. These sequences can control the cursor, set text attributes and colors, and more. Windows [recently joined](https://blogs.msdn.microsoft.com/commandline/2018/06/27/windows-command-line-the-evolution-of-the-windows-command-line/) Linux and Mac in supporting these features. This is a capability of the new Windows Terminal and can also be enabled programmatically in the Windows 10 Console.

`System.Console.Rendering` adds support for detecting terminal settings and enabling the Window 10 Console's ANSI mode on demand. It also provides an API that can write output that looks correct based on those settings as well as when output is redirected, as is commonly the case on a build server or when your command line app is called by another command line app.

The following are examples of output rendered by the same view code in these three different contexts.

In PowerShell on Windows with ANSI mode enabled:
In PowerShell on Windows with VT mode enabled:

![ansi](https://user-images.githubusercontent.com/547415/50388667-575b2280-06d2-11e9-91ae-36e8ffabbf8a.png)

In PowerShell with ANSI mode disabled:
In PowerShell with VT mode disabled:

![non-ansi](https://user-images.githubusercontent.com/547415/50388673-85d8fd80-06d2-11e9-844b-4690e4b4ab5a.png)

Expand Down Expand Up @@ -121,13 +121,13 @@ The raw text written to standard out in the first example is this:

```

In ANSI mode, the Windows Console interprets these escape sequences into cursor movements and colors. As you can see in the first example above, ANSI mode enables the display of RGB colors and underlining that are not supported otherwise on Windows. Most Linux and macOS terminals as well as the Windows Terminal support this form of rendering by default.

The examples above build the table structure by positioning the cursor for each cell and then writing the content. In an ANSI-capable terminal, this is done using ANSI escape sequences such as `\u001b[1;1H`. The equivalent `System.Console` call, which is needed in non-ANSI terminals, looks like this: `Console.SetCursorPosition(0, 0)`. Meanwhile, the third example renders the layout using spaces and newlines, since there is no cursor when output is redirected.
In VT mode, the Windows Console interprets these escape sequences into cursor movements and colors. As you can see in the first example above, VT mode enables the display of RGB colors and underlining that are not supported otherwise on Windows. Most Linux and macOS terminals as well as the Windows Terminal support this form of rendering by default.

Providing a common API across these very different modes so that you don't have to write the code three times is a major goal of `System.CommandLine.Rendering`. The API is still very rough but you can explore these capabilities in the `RenderingPlayground` [sample](https://github.com/dotnet/command-line-api/tree/master/samples/RenderingPlayground).
The examples above build the table structure by positioning the cursor for each cell and then writing the content. In a VT-capable terminal, this is done using ANSI escape sequences such as `\u001b[1;1H`. The equivalent `System.Console` call, which is needed in terminals that don't render VT codes, looks like this: `Console.SetCursorPosition(0, 0)`. Meanwhile, the third example renders the layout using spaces and newlines, since there is no cursor when output is redirected.

## Rendering directives
Providing a common API across these very different modes so that you don't have to write the code three times is a major goal of `System.CommandLine.Rendering`. The API is still very rough but you can explore these capabilities in the `RenderingPlayground` [sample](https://github.com/dotnet/command-line-api/tree/master/samples/RenderingPlayground).

## Rendering directives

Output modes can also be specified directly. If you know that you want a specific form of output, you can bypass the mode detection of `System.CommandLine.Rendering` and use a [directive](Syntax-Concepts-and-Parser.md#directives).

Expand All @@ -144,3 +144,4 @@ The supported output modes are:
* `Ansi`: Output is rendered using ANSI escape sequences. In-place re-rendering is supported.
* `NonAnsi`: Output is rendered using `System.Console` cursor positioning. In-place re-rendering is supported.
* `PlainText`: Output is rendered with additional whitespace so that, for example, if redirected to a text file, the layout will look correct. In-place re-rendering is not supported.

66 changes: 37 additions & 29 deletions docs/Functional-goals.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Functional goals

The high level goals for `System.CommandLine` support our idea that creating great command line experiences for your users can be easy. We have not yet met all of these goals.
The high level goals for `System.CommandLine` support our idea that creating great command line experiences for your users can be easy. We have not yet met all of these goals.

## Goals for the end user's experience

Expand All @@ -11,42 +11,50 @@ The high level goals for `System.CommandLine` support our idea that creating gre
## Goals for the programmer's experience

* Help
* Creating some version of help should be automated, requiring no work.
* Help should be informative if descriptions are supplied.
* Help localization should be straightforward.

* Creating some version of help should be automated, requiring no work.
* Help should be informative if descriptions are supplied.
* Help localization should be straightforward.

* Tab suggestion
* It should just work with no effort on the programmer's part.
* It should provide support for enums.
* It should have a mechanism for dynamic values.
* It should stay out of the way of shell suggestions for files and folders.
* Dynamic suggestions should be extensible for other things I might do.

* It should just work with no effort on the programmer's part.
* It should provide support for enums.
* It should have a mechanism for dynamic values.
* It should stay out of the way of shell suggestions for files and folders.
* Dynamic suggestions should be extensible for other things I might do.

* Validation
* If there are parse errors, it should fail before my application code is called.
* It should check the number and type of arguments.
* It should generally fail if there are unmatched tokens, but I should be able to allow it to pass through.
* It should provide default responses for the user on validation issues.
* I should be able to customize the validation messages.


* If there are parse errors, it should fail before my application code is called.
* It should check the number and type of arguments.
* It should generally fail if there are unmatched tokens, but I should be able to allow it to pass through.
* It should provide default responses for the user on validation issues.
* I should be able to customize the validation messages.

* Debugging and testing
* I should not have to turn a string into an array to interact programmatically.
* I should be able to get a visualization of how a string is parsed.
* It should be easy to test parsing in isolation from the application.
* It should be easy to test the application in isolation from parsing.
* I should be able to specify at the command line that I want to attach a debugger.

* I should not have to turn a string into an array to interact programmatically.
* I should be able to get a visualization of how a string is parsed.
* It should be easy to test parsing in isolation from the application.
* It should be easy to test the application in isolation from parsing.
* I should be able to specify at the command line that I want to attach a debugger.

* Acting on parser results
* Argument results should be strongly typed.
* For advanced scenarios, I can alter and re-parse input.
* It should be simple for me to manage exceptions, output, and exit codes.

* Argument results should be strongly typed.
* For advanced scenarios, I can alter and re-parse input.
* It should be simple for me to manage exceptions, output, and exit codes.

* Rendering
* Provide ways to reason about layout rather than just text.
* Hide Windows/Linux/Mac differences for me.
* Take advantage of new Windows 10 console capabilities.
* Hide non-ANSI/ANSI differences for me.
* Make output look correct when redirected to a file.

* Provide ways to reason about layout rather than just text.
* Hide Windows/Linux/Mac differences for me.
* Take advantage of new Windows 10 console capabilities.
* Hide non-ANSI/ANSI differences for me.
* Make output look correct when redirected to a file.

* Extensibility
* I can compose cross-cutting behaviors using packages.

* I can compose cross-cutting behaviors using packages.

9 changes: 5 additions & 4 deletions docs/History.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# History

The new `System.CommandLine`'s lineage can be traced through the experiences of various teams at Microsoft building .NET command line applications. Some of its ideas have been expressed in the `dotnet` CLI and `CommandLineUtils` originally created in ASP.NET with a [popular fork](https://github.com/natemcmaster/CommandLineUtils) by @natemcmaster.
The new `System.CommandLine`'s lineage can be traced through the experiences of various teams at Microsoft building .NET command line applications. Some of its ideas have been expressed in the `dotnet` CLI and `CommandLineUtils` originally created in ASP.NET with a [popular fork](https://github.com/natemcmaster/CommandLineUtils) by @natemcmaster.

This project is called the "new" `System.CommandLine` because Microsoft also had a `System.CommandLine` project in CoreFxLab that has been retired because it did not meet the current needs.

Expand All @@ -10,16 +10,17 @@ The addition of global tools to the `dotnet` ecosystem meant the creation of mor

Parsing is a deceptively complex problem. With folks on the team that have been involved in writing complex and successful CLIs, we can work in the other direction, focusing first on a solid core and then working outward toward the functionality and API surface. We're building the foundation that the folks who wrote and worked on the `dotnet` CLI wish they had been able to use. We ran this part of the project in private to ensure the core was solid, and as an all-volunteer effort this phase took painfully long.

The next layer, the API over the core functionality, has undergone a rewrite, and we are fairly happy with how you explicitly define your CLI. Explicitly defining a syntax feels like too much work for many scenarios and we've put a lot of thought and discussion into the idea of "app models" that infer the structure of your CLI from something that is natural to write.
The next layer, the API over the core functionality, has undergone a rewrite, and we are fairly happy with how you explicitly define your CLI. Explicitly defining a syntax feels like too much work for many scenarios and we've put a lot of thought and discussion into the idea of "app models" that infer the structure of your CLI from something that is natural to write.

App models have two aspects: defining the CLI's structure and bridging between parse results and your application.
App models have two aspects: defining the CLI's structure and bridging between parse results and your application.

As an example, one approach is to bind to a method, which is executed with parameters matching the options and arguments your user provided. This method binding works well when mapped one-to-one between the command and the invoked method. You can find this as the basis for the experimental "DragonFruit" model. DragonFruit takes this idea one step furher by wrapping your `Program.Main` entry point and just letting your `Main` method have normal parameters that just happen to be able to be of types other than `string`. We have not yet found a way we like to do subcommands with the DragonFruit model.

Other approaches to binding include binding to classes. A fundamental aspect of `System.CommandLine` is top-level support for app models and binders. These may reside outside `System.CommandLine` and we hope it will be a framework that people with other ideas can build on. The goal is that app models will interoperate with one another allowing many choices for programmers.

## Rendering

We've also done preliminary work on rendering. This is another area where `System.Console` is showing its age. In particular, `System.Console` does not supporting ANSI terminals easily. While `ncurses` has long addressed differing terminal capabilities in the non-Windows world, .NET programmers could benefit from something that works consistently on Windows, Linux, and Mac.
We've also done preliminary work on rendering. This is another area where `System.Console` is showing its age. In particular, `System.Console` does not supporting ANSI terminals easily. While `ncurses` has long addressed differing terminal capabilities in the non-Windows world, .NET programmers could benefit from something that works consistently on Windows, Linux, and Mac.

And with the new Windows Terminal and Windows 10 bringing [virtual terminal capabilities](https://blogs.msdn.microsoft.com/commandline/2018/06/27/windows-command-line-the-evolution-of-the-windows-command-line/) to the Windows console, we think there's an opportunity for .NET APIs that these benefits to users.

Loading

0 comments on commit f2556ca

Please sign in to comment.