Skip to content

Commit 0455e35

Browse files
Jon Sequeirajonsequitur
authored andcommitted
add docs content from wiki
1 parent dc222b2 commit 0455e35

14 files changed

+992
-1
lines changed

README.md

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,34 @@ Package | Version
1616

1717
Daily builds are available if you add this feed to your nuget.config: https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet5/nuget/v3/index.json.
1818

19+
## Documentation
20+
21+
### Getting started
22+
23+
[Syntax Concepts and Parser](docs/Syntax-Concepts-and-Parser)
24+
25+
#### Features
26+
* [Suggestions (tab completion)](docs/Features-overview#Suggestions)
27+
* [Help](docs/Features-overview#Help)
28+
* [Version option](docs/Features-overview#version-option)
29+
* [Parse preview](docs/Features-overview#parse-preview)
30+
* [Debugging](docs/Features-overview#debugging)
31+
* [Response files](docs/Features-overview#Response-files)
32+
* [Termination handling](docs/Process-termination-handling)
33+
34+
#### Your first app
35+
* [System.CommandLine](docs/Your-first-app-with-System-CommandLine)
36+
* [System.CommandLine.DragonFruit](docs/Your-first-app-with-System-CommandLine-DragonFruit)
37+
38+
#### How to...
39+
40+
* [Add a subcommand (or verb)](docs/How-To#Add-a-subcommand)
41+
* [Add an alias to an option or command](docs/How-To#Add-an-alias-to-an-option-or-command)
42+
* [Call a method](docs/How-To#Call-a-method)
43+
* [Pass parameters to a method](docs/How-To#Pass-parameters-to-a-method)
44+
* [Argument validation and binding](docs/How-To#Argument-validation-and-binding)
45+
* [Middleware Pipeline](docs/How-To#Middleware-Pipeline)
46+
1947
## Interactive tutorials
2048

2149
You can try out `System.CommandLine` using an interactive tutorial that showcases its features and APIs, powered by Try .NET.
@@ -46,7 +74,7 @@ This project has adopted the code of conduct defined by the [Contributor Covenan
4674

4775
## Contributing
4876

49-
See the [Contributing guide](CONTRIBUTING.md) for developer documentation.
77+
See the [Contributing guide](CONTRIBUTING) for developer documentation.
5078

5179
## License
5280

docs/DragonFruit-overview.md

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
# What is DragonFruit?
2+
3+
The entry point for a normal .NET console application looks like this:
4+
5+
```csharp
6+
static void Main(string[] args)
7+
{
8+
Console.WriteLine("Hello World!");
9+
}
10+
```
11+
12+
Interpreting the `string[]` arguments into behaviors has been left as a task for the developer. Did the user ask for help? Did they pass invalid input? Can the input be converted to the types that you need if they're not `string`? These problems are not solved for you.
13+
14+
What if you could declare a strongly-typed `Main` method? This was the question that led to the creation of the experimental app model called "DragonFruit", which allows you to create an entry point with multiple parameters of various types and using default values, like this:
15+
16+
```csharp
17+
static void Main(int intOption = 42, bool boolOption = false, FileInfo fileOption = null)
18+
{
19+
Console.WriteLine($"The value of intOption is: {intOption}");
20+
Console.WriteLine($"The value of boolOption is: {boolOption}");
21+
Console.WriteLine($"The value of fileOption is: {fileOption?.FullName ?? "null"}");
22+
}
23+
```
24+
25+
DragonFruit handles help requests, parsing errors, argument binding, and more for you.
26+
27+
```console
28+
> ./myapp # or: > dotnet run
29+
The value of intOption is: 42
30+
The value of boolOption is: False
31+
The value of fileOption is: null
32+
```
33+
34+
You don't need to write any special code to get help support.
35+
36+
```console
37+
> ./myapp -h # or: dotnet run -- -h
38+
Usage:
39+
myapp [options]
40+
41+
Options:
42+
--int-option intOption
43+
--bool-option boolOption
44+
--file-option fileOption
45+
```
46+
47+
If you want more informative help, you can add it using standard XML comments:
48+
49+
```csharp
50+
/// <summary>
51+
/// My example app
52+
/// </summary>
53+
/// <param name="intOption">An option whose argument will bind to an int</param>
54+
/// <param name="boolOption">An option whose argument will bind to a bool</param>
55+
/// <param name="fileOption">An option whose argument will bind to a FileInfo</param>
56+
static void Main(int intOption = 42, bool boolOption = false, FileInfo fileOption = null)
57+
{
58+
Console.WriteLine($"The value of intOption is: {intOption}");
59+
Console.WriteLine($"The value of boolOption is: {boolOption}");
60+
Console.WriteLine($"The value of fileOption is: {fileOption?.FullName ?? "null"}");
61+
}
62+
```
63+
64+
The text of those comments will be shown when a user requests help.
65+
66+
```console
67+
> dotnet run -- -h
68+
Usage:
69+
myapp [options]
70+
71+
Options:
72+
--int-option An option whose argument will bind to an int
73+
--bool-option An option whose argument will bind to a bool
74+
--file-option An option whose argument will bind to a FileInfo
75+
```
76+
77+
## Arguments
78+
79+
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.
80+
81+
```csharp
82+
static void Main(int intOption = 42, string[] args = null)
83+
{
84+
Console.WriteLine($"The value of intOption is: {intOption}");
85+
86+
foreach (var arg in args)
87+
{
88+
Console.WriteLine(arg);
89+
}
90+
}
91+
```
92+
93+
```console
94+
> myapp -h
95+
Usage:
96+
myapp [options] <args>
97+
98+
Arguments:
99+
<args>
100+
101+
Options:
102+
--int-option <INT-OPTION> intOption
103+
--version Display version information
104+
```
105+
106+
The argument follows the same conventions for arity as described in [arguments](Syntax-Concepts-and-Parser#Arguments-and-arity).
107+
108+
You can try out DragonFruit by installing the latest preview [package](https://www.nuget.org/packages/System.CommandLine.DragonFruit).

docs/Features-overview.md

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
`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.
2+
3+
# Suggestions
4+
5+
Programs written using `System.CommandLine` have built-in support for tab completion.
6+
7+
![t-rex-suggestions](https://user-images.githubusercontent.com/547415/50387753-ef4c1280-06b8-11e9-90c8-89466d0bb406.gif)
8+
9+
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`.
10+
11+
# Help
12+
13+
Command line applications typically have a way to get help, in order to understand the available options and their usage.
14+
15+
```console
16+
> myapp -h
17+
Usage:
18+
myapp [options]
19+
20+
Options:
21+
--int-option An option whose argument is parsed as an int
22+
--bool-option An option whose argument is parsed as a bool
23+
--file-option An option whose argument is parsed as a FileInfo
24+
--version Display version information
25+
```
26+
27+
Users might be accustomed to different prefixes in different ecosystems, especially if your app targets .NET Core and is used cross-platform, so apps built on `System.CommandLine` understand many different ways of requesting help. The following are all equivalent:
28+
29+
```console
30+
> myapp -h
31+
> myapp /h
32+
> myapp --help
33+
> myapp -?
34+
> myapp /?
35+
```
36+
37+
# Version option
38+
39+
Providing a way to check the version of your app is helpful to your users.
40+
41+
`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:
42+
43+
```console
44+
> myapp --version
45+
1.0.0
46+
```
47+
48+
# Parse preview
49+
50+
Both users and developers often find it useful to see how an app will interpret a given input. One of the default features of a `System.CommandLine` app is the `[parse]` directive, which lets you preview a parse:
51+
52+
```console
53+
> myapp [parse] --int-option not-an-int --file-option file.txt
54+
[ myapp ![ --int-option <not-an-int> ] [ --file-option <file.txt> ] *[ --bool-option <False> ] ]
55+
```
56+
57+
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:
58+
59+
* Commands (`myapp`), their child options, and the arguments to those options are grouped using square brackets.
60+
* 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.
61+
* 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.
62+
63+
# Debugging
64+
65+
When you're developing your app and you find that the parse preview isn't enough to explain something that's happening internally, the `[debug]` directive might help you. Set a breakpoint inside your code, prepend your command line input with `"[debug]"`, and hit `enter`:
66+
67+
```console
68+
> myapp [debug] --file-option does-not-exist.txt
69+
Attach your debugger to process 14160 (myapp).
70+
```
71+
72+
Once you've attached your debugger to the specified process, execution will proceed to your breakpoint.
73+
74+
# Response files
75+
76+
Passing command line arguments via response files is helpful for very long command lines or for composing a command line from multiple sources. Here's an example:
77+
78+
```console
79+
> myapp @c:\config\settings.rsp
80+
```
81+
82+
One or more response files can be specified in this way. Arguments and options are read from the file and expanded in-place as if they had been entered directly on the command line.
83+
84+
# Adaptive rendering
85+
86+
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.
87+
88+
`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.
89+
90+
The following are examples of output rendered by the same view code in these three different contexts.
91+
92+
In PowerShell on Windows with ANSI mode enabled:
93+
94+
![ansi](https://user-images.githubusercontent.com/547415/50388667-575b2280-06d2-11e9-91ae-36e8ffabbf8a.png)
95+
96+
In PowerShell with ANSI mode disabled:
97+
98+
![non-ansi](https://user-images.githubusercontent.com/547415/50388673-85d8fd80-06d2-11e9-844b-4690e4b4ab5a.png)
99+
100+
Redirected to a text file:
101+
102+
```
103+
Directory: C:\dev\command-line-api\build
104+
105+
Name Created Modified
106+
build.ps1 10/6/2018 10:56 AM 11/4/2018 7:10 PM
107+
build.sh 10/6/2018 10:56 AM 11/4/2018 7:10 PM
108+
cibuild.cmd 10/6/2018 10:56 AM 10/6/2018 10:56 AM
109+
cibuild.sh 10/6/2018 10:56 AM 10/6/2018 10:56 AM
110+
NuGet.props 10/6/2018 10:56 AM 10/6/2018 10:56 AM
111+
SignToolData.json 10/6/2018 10:56 AM 11/19/2018 1:56 PM
112+
Toolset.proj 10/6/2018 10:56 AM 10/6/2018 10:56 AM
113+
Versions.props 10/6/2018 10:56 AM 11/19/2018 1:56 PM
114+
115+
```
116+
117+
The raw text written to standard out in the first example is this:
118+
119+
```console
120+
\u001b[1;1H\u001b[39m\u001b[49m\u001b[2;1HDirectory: \u001b[38;2;235;30;180mC:\dev\command-line-api\build\u001b[39m\u001b[39m\u001b[49m\u001b[3;1H\u001b[39m\u001b[49m\u001b[4;1H\u001b[4mName\u001b[24m\u001b[39m\u001b[49m \u001b[4;20H\u001b[4mCreated\u001b[24m\u001b[39m\u001b[49m \u001b[4;40H\u001b[4mModified\u001b[24m\u001b[39m\u001b[49m \u001b[5;1H\u001b[37mbuild.ps1\u001b[39m\u001b[39m\u001b[49m \u001b[5;20H10/6/2018 \u001b[90m10:56 AM\u001b[39m\u001b[49m \u001b[5;40H11/4/2018 \u001b[90m7:10 PM\u001b[39m\u001b[49m \u001b[6;1H\u001b[37mbuild.sh\u001b[39m\u001b[39m\u001b[49m \u001b[6;20H10/6/2018 \u001b[90m10:56 AM\u001b[39m\u001b[49m \u001b[6;40H11/4/2018 \u001b[90m7:10 PM\u001b[39m\u001b[49m \u001b[7;1H\u001b[37mcibuild.cmd\u001b[39m\u001b[39m\u001b[49m \u001b[7;20H10/6/2018 \u001b[90m10:56 AM\u001b[39m\u001b[49m \u001b[7;40H10/6/2018 \u001b[90m10:56 AM\u001b[39m\u001b[49m\u001b[8;1H\u001b[37mcibuild.sh\u001b[39m\u001b[39m\u001b[49m \u001b[8;20H10/6/2018 \u001b[90m10:56 AM\u001b[39m\u001b[49m \u001b[8;40H10/6/2018 \u001b[90m10:56 AM\u001b[39m\u001b[49m\u001b[9;1H\u001b[37mNuGet.props\u001b[39m\u001b[39m\u001b[49m \u001b[9;20H10/6/2018 \u001b[90m10:56 AM\u001b[39m\u001b[49m \u001b[9;40H10/6/2018 \u001b[90m10:56 AM\u001b[39m\u001b[49m\u001b[10;1H\u001b[37mSignToolData.json\u001b[39m\u001b[39m\u001b[49m \u001b[10;20H10/6/2018 \u001b[90m10:56 AM\u001b[39m\u001b[49m \u001b[10;40H11/19/2018 \u001b[90m1:56 PM\u001b[39m\u001b[49m\u001b[11;1H\u001b[37mToolset.proj\u001b[39m\u001b[39m\u001b[49m \u001b[11;20H10/6/2018 \u001b[90m10:56 AM\u001b[39m\u001b[49m \u001b[11;40H10/6/2018 \u001b[90m10:56 AM\u001b[39m\u001b[49m\u001b[12;1H\u001b[37mVersions.props\u001b[39m\u001b[39m\u001b[49m \u001b[12;20H10/6/2018 \u001b[90m10:56 AM\u001b[39m\u001b[49m \u001b[12;40H11/19/2018 \u001b[90m1:56 PM\u001b[39m\u001b[49m
121+
122+
```
123+
124+
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.
125+
126+
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.
127+
128+
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).
129+
130+
## Rendering directives
131+
132+
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#directives).
133+
134+
The following example will output ANSI to a text file.
135+
136+
```console
137+
> .\RenderingPlayground.exe [output:ansi] --sample dir > sample.txt
138+
```
139+
140+
(The parameter for the output directive is case-insensitive.)
141+
142+
The supported output modes are:
143+
144+
* `Ansi`: Output is rendered using ANSI escape sequences. In-place re-rendering is supported.
145+
* `NonAnsi`: Output is rendered using `System.Console` cursor positioning. In-place re-rendering is supported.
146+
* `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.

docs/Functional-goals.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Functional goals
2+
3+
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.
4+
5+
## Goals for the end user's experience
6+
7+
* Help should be clear and consistent
8+
* I should not have to know the right syntax to get help. Just make all variations work.
9+
* Tab suggestion should just work with as little setup as possible.
10+
11+
## Goals for the programmer's experience
12+
13+
* Help
14+
* Creating some version of help should be automated, requiring no work.
15+
* Help should be informative if descriptions are supplied.
16+
* Help localization should be straightforward.
17+
18+
* Tab suggestion
19+
* It should just work with no effort on the programmer's part.
20+
* It should provide support for enums.
21+
* It should have a mechanism for dynamic values.
22+
* It should stay out of the way of shell suggestions for files and folders.
23+
* Dynamic suggestions should be extensible for other things I might do.
24+
25+
* Validation
26+
* If there are parse errors, it should fail before my application code is called.
27+
* It should check the number and type of arguments.
28+
* It should generally fail if there are unmatched tokens, but I should be able to allow it to pass through.
29+
* It should provide default responses for the user on validation issues.
30+
* I should be able to customize the validation messages.
31+
32+
* Debugging and testing
33+
* I should not have to turn a string into an array to interact programmatically.
34+
* I should be able to get a visualization of how a string is parsed.
35+
* It should be easy to test parsing in isolation from the application.
36+
* It should be easy to test the application in isolation from parsing.
37+
* I should be able to specify at the command line that I want to attach a debugger.
38+
39+
* Acting on parser results
40+
* Argument results should be strongly typed.
41+
* For advanced scenarios, I can alter and re-parse input.
42+
* It should be simple for me to manage exceptions, output, and exit codes.
43+
44+
* Rendering
45+
* Provide ways to reason about layout rather than just text.
46+
* Hide Windows/Linux/Mac differences for me.
47+
* Take advantage of new Windows 10 console capabilities.
48+
* Hide non-ANSI/ANSI differences for me.
49+
* Make output look correct when redirected to a file.
50+
51+
* Extensibility
52+
* I can compose cross-cutting behaviors using packages.

0 commit comments

Comments
 (0)