New doc theme (#387)

This commit is contained in:
Phil Scott
2021-04-24 16:20:59 -04:00
committed by GitHub
parent b568098d5e
commit 2a9fbb1ee9
145 changed files with 197984 additions and 8746 deletions

View File

@ -17,7 +17,7 @@ app.Configure(config =>
});
```
# Multiple Commands
## Multiple Commands
In the previous example we have a single command that is configured. For complex command line applications, it is common for them to have multiple commands (or verbs) defined. Examples of applications like this are `git`, `dotnet` and `gh`. For example, git would have an `commit` command and along with other commits like `add` or `rebase`. Each with their own settings and validation. With `Spectre.Console.Cli` we use the `Configure` method to add these commands.
@ -37,7 +37,7 @@ This configuration would allow users to run `app.exe add`, `app.exe commit`, or
For more complex command hierarchical configurations, they can also be composed via inheritance and branching. See [Composing Commands](./composing).
# Customizing Command Configurations
## Customizing Command Configurations
The `Configure` method is also used to change how help for the commands is generated. This configuration will give our command an additional alias of `file-size` and a description to be used when displaying the help. Additional, an example is specified that will be parsed and displayed for users asking for help. Multiple examples can be provided. Commands can also be marked as hidden. With this option they are still executable, but will not be displayed in help screens.
@ -53,7 +53,7 @@ app.Configure(config =>
});
```
# Dependency Injection
## Dependency Injection
`CommandApp` takes care of instantiating commands upon execution. If given a custom type registrar, it will use that to resolve services defined in the command constructor.
@ -73,7 +73,7 @@ return app.Run(args);
`TypeRegistrar` is a custom class that must be created by the user. This [example using `Microsoft.Extensions.DependencyInjection` as the container](https://github.com/spectreconsole/spectre.console/tree/main/examples/Cli/Injection) provides an example `TypeRegistrar` and `TypeResolver` that can be added to your application with small adjustments for your DI container.
# Interception
## Interception
`CommandApp` also provides a `SetInterceptor` configuration. An interceptor is ran before all commands are executed. This is typically used for configuring logging or other infrastructure concerns.

View File

@ -22,7 +22,7 @@ public class HelloCommand : Command<HelloCommand.Settings>
}
```
# Configuring.
## Configuring
Commands are configured via the [`CommandApp`](commandApp)'s `Configure` method.
@ -42,11 +42,11 @@ app.Configure(config =>
* `WithDescription` is used by the help renderer to give commands a description when displaying help.
* `WithExample` is used by the help renderer to provide examples to the user for running the commands. The parameters is a string array that matches the values passed in `Main(string[] args)`.
# Dependency Injection.
## Dependency Injection
Constructor injection is supported on commands. See the [`CommandApp`](commandApp) documentation for further information on configuring `Spectre.Console` for your container.
# Validation.
## Validation
While the settings can validate themselves, the command also provides a validation. For example, `IFileSystem` might be injected into the command which we want to use to validate that a path passed in exists.

View File

@ -103,7 +103,7 @@ namespace MyApp
}
```
# So why this way?
## So why this way?
Now you might wonder, why do things like this? Well, for starters the different parts
of the application are separated, while still having the option to share things like options,

View File

@ -6,20 +6,13 @@ Order: 1
opinionated in what it does, it tries to follow established industry conventions, and draws
its inspiration from applications you use everyday.
# How does it work?
## How does it work?
A `Spectre.Console.Cli` app will be comprised of Commands and a matching Setting specification. The settings file will be the model for the command parameters. Upon execution, `Spectre.Console.Cli` will parse the `args[]` passed into your application and match them to the appropriate settings file giving you a strongly typed object to work with.
The following example demonstrates these concepts coming together.
```csharp
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using Spectre.Console;
using Spectre.Console.Cli;
var app = new CommandApp<FileSizeCommand>();
return app.Run(args);
@ -57,7 +50,7 @@ internal sealed class FileSizeCommand : Command<FileSizeCommand.Settings>
.Sum(fileInfo => fileInfo.Length);
AnsiConsole.MarkupLine(
$"Total file size for [green]{searchPattern}[/] files in [green]{searchPath}[/]: [blue]{totalFileSize:N0}[/] bytes");
$"Total file size for [green]{searchPattern}[/] files in [green]{searchPath}[/]: [blue]{totalFileSize:N0}[/] bytes"); $"Total file size for [green]{searchPattern}[/] files in [green]{searchPath}[/]: [blue]{totalFileSize:N0}[/] bytes");
return 0;
}

View File

@ -1,8 +1,8 @@
Title: CLI
Title: Spectre.Console.Cli
Order: 10
---
<h1>Sections</h1>
<p>Spectre.Console.Cli is a modern library for parsing command line arguments. While it's extremely opinionated in what it does, it tries to follow established industry conventions, and draws its inspiration from applications you use everyday.</p>
<ul>
@foreach (IDocument child in OutputPages.GetChildrenOf(Document))

View File

@ -0,0 +1,121 @@
Title: Introduction
Order: 1
---
`Spectre.Console.Cli` is a modern library for parsing command line arguments. While it's extremely
opinionated in what it does, it tries to follow established industry conventions, and draws
its inspiration from applications you use everyday.
## How does it work?
The underlying philosophy behind `Spectre.Console.Cli` is to rely on the .NET type system to
declare the commands, but tie everything together via composition.
Imagine the following command structure:
* dotnet *(executable)*
* add `[PROJECT]`
* package `<PACKAGE_NAME>` --version `<VERSION>`
* reference `<PROJECT_REFERENCE>`
For this I would like to implement the commands (the different levels in the tree that
executes something) separately from the settings (the options, flags and arguments),
which I want to be able to inherit from each other.
## Specify the settings
We start by creating some settings that represents the options, flags and arguments
that we want to act upon.
```csharp
public class AddSettings : CommandSettings
{
[CommandArgument(0, "[PROJECT]")]
public string Project { get; set; }
}
public class AddPackageSettings : AddSettings
{
[CommandArgument(0, "<PACKAGE_NAME>")]
public string PackageName { get; set; }
[CommandOption("-v|--version <VERSION>")]
public string Version { get; set; }
}
public class AddReferenceSettings : AddSettings
{
[CommandArgument(0, "<PROJECT_REFERENCE>")]
public string ProjectReference { get; set; }
}
```
## Specify the commands
Now it's time to specify the commands that act on the settings we created
in the previous step.
```csharp
public class AddPackageCommand : Command<AddPackageSettings>
{
public override int Execute(CommandContext context, AddPackageSettings settings)
{
// Omitted
return 0;
}
}
public class AddReferenceCommand : Command<AddReferenceSettings>
{
public override int Execute(CommandContext context, AddReferenceSettings settings)
{
// Omitted
return 0;
}
}
```
You can use `AsyncCommand` if you need async support.
## Let's tie it together
Now when we have our commands and settings implemented, we can compose a command tree
that tells the parser how to interpret user input.
```csharp
using Spectre.Console.Cli;
namespace MyApp
{
public static class Program
{
public static int Main(string[] args)
{
var app = new CommandApp();
app.Configure(config =>
{
config.AddBranch<AddSettings>("add", add =>
{
add.AddCommand<AddPackageCommand>("package");
add.AddCommand<AddReferenceCommand>("reference");
});
});
return app.Run(args);
}
}
}
```
## So why this way?
Now you might wonder, why do things like this? Well, for starters the different parts
of the application are separated, while still having the option to share things like options,
flags and arguments between them.
This make the resulting code very clean and easy to navigate, not to mention to unit test.
And most importantly at all, the type system guides me to do the right thing. I can't configure
commands in non-compatible ways, and if I want to add a new top-level `add-package` command
(or move the command completely), it's just a single line to change. This makes it easy to
experiment and makes the CLI experience a first class citizen of your application.

View File

@ -32,11 +32,11 @@ to `Spectre.Console.CLi`.
+ using Spectre.Console.Cli;
```
# Breaking Changes
## Breaking Changes
In the process of moving `Spectre.Cli`, there have been some minor breaking changes.
## Spectre.Cli.Exceptions namespace moved
### Spectre.Cli.Exceptions namespace moved
All exceptions have been moved from the `Spectre.Cli.Exceptions` namespace to
the `Spectre.Console.Cli` namespace.

View File

@ -19,7 +19,7 @@ public sealed class MyCommandSettings : CommandSettings
This setting file tells `Spectre.Console.Cli` that our command has two parameters. One is marked as a `CommandArgument`, the other is a `CommandOption`.
# `CommandArgument`.
## CommandArgument
Arguments have a position and a name. The name is not only used for generating help, but it's formatting is used to determine whether or not the argument is optional. The name must either be surrounded by square brackets (e.g. `[name]`) or angle brackets (e.g. `<name>`). Angle brackets denote required whereas square brackets denote optional. If neither are specified an exception will be thrown.
@ -35,7 +35,7 @@ public string FirstName { get; set; }
public string LastName { get; set; }
```
# `CommandOption`.
## CommandOption
`CommandOption` is used when you have options that are passed in command line switches. The attribute has one parameter - a pipe delimited string with the list of argument names. The following rules apply:
@ -43,7 +43,7 @@ public string LastName { get; set; }
* Options with a single character must be preceded by a single dash (e.g. `-c`).
* Multi-character options must be preceded by two dashes (e.g. `--count`).
## Flags.
### Flags
There is a special mode for `CommandOptions` on boolean types. Typically all `CommandOptions` require a value to be included after the switch. For these only the switch needs to be specified to mark the value as true. This example would allow the user to run either `app.exe --debug`, or `app.exe --debug true`.
@ -52,11 +52,11 @@ There is a special mode for `CommandOptions` on boolean types. Typically all `Co
public bool Debug { get; set; }
```
# Description.
## Description
When rendering help the [`System.ComponentModel.Description`](https://docs.microsoft.com/en-us/dotnet/api/system.componentmodel.descriptionattribute?view=net-5.0) attribute is supported for specifying the text displayed to the user for both `CommandOption` and `CommandArgument`.
# DefaultValue.
## DefaultValue
The [`System.ComponentModel.DefaultValue`](https://docs.microsoft.com/en-us/dotnet/api/system.componentmodel.defaultvalueattribute?view=net-5.0) attribute supported to specify a default value for a command. For example, in the hello example displaying hello for a default count of zero wouldn't make sense. We can change this to a single hello:
@ -66,11 +66,11 @@ The [`System.ComponentModel.DefaultValue`](https://docs.microsoft.com/en-us/dotn
public int Count { get; set; }
```
# TypeConverter.
## TypeConverter
`System.ComponentModel.TypeConverter` is supported for more complex arguments, such as mapping log levels to an enum via a [`TypeConverter`](https://docs.microsoft.com/en-us/dotnet/api/system.componentmodel.typeconverter?view=net-5.0).
# Arrays.
## Arrays
`CommandArgument` can be defined as arrays and any additional parameters will be included in the value. For example
@ -81,7 +81,7 @@ public string[] Name { get; set; }
Would allow the user to run `app.exe Dwayne Elizondo "Mountain Dew" Herbert Camacho`. The settings passed to the command would have a 5 element array consisting of Dwayne, Elizondo, Mountain Dew, Herbert and Camacho.
# Constructors.
## Constructors
`Spectre.Console.Cli` supports constructor initialization and init only initialization. For constructor initialization, the parameter name of the constructor must match the name of the property name of the settings class. Order does not matter.
@ -110,7 +110,7 @@ public class Settings
}
```
# Validation.
## Validation
Simple type validation is performed automatically, but for scenarios where more complex validation is required, overriding the `Validate` method is supported. This method must return either `ValidationResult.Error` or `ValidationResult.Success`.
@ -128,4 +128,4 @@ public class Settings
: ValidationResult.Success();
}
}
```
```