-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
diff with what was officially approved in dotnet/runtime#68578 (comment): - CliSymbol, CliArgument, CliOption and CliCommand moved to new System.CommandLine.Parsing library - abstract types moved from System.CommandLine to System.CommandLine.Symbols namespace as they should be rarely used - HelpOption and VersionOption moved to System.CommandLine.Help library - CliRootCommand moved to main System.CommandLine package - CliSymbol.Description made virtual, to allow for customization like loading lazily from resources - CliSymbol extended with Terminating property that let's the parser know that given symbol terminates parsing (example: help) - CliSymbol.HelpName removed, as symbols are now unaware of help - CliCOmmand.Add and CliCommand.Children made virtual to allow for CliRootCommand extend with Directives
- Loading branch information
1 parent
0e9086d
commit fe9e38a
Showing
17 changed files
with
415 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
namespace System.CommandLine.Help; | ||
|
||
public sealed class HelpOption : CliOption<bool> | ||
{ | ||
/// <summary> | ||
/// When added to a <see cref="CliCommand"/>, it configures the application to show help when one of the following options are specified on the command line: | ||
/// <code> | ||
/// -h | ||
/// /h | ||
/// --help | ||
/// -? | ||
/// /? | ||
/// </code> | ||
/// </summary> | ||
public HelpOption() : base("--help", new[] { "-h", "/h", "-?", "/?" }) | ||
{ | ||
Recursive = true; | ||
Terminating = true; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>netstandard2.0</TargetFramework> | ||
<LangVersion>10.0</LangVersion> | ||
<Nullable>enable</Nullable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\System.CommandLine.Parsing\System.CommandLine.Parsing.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
namespace System.CommandLine.Help; | ||
|
||
public sealed class VersionOption : CliOption<bool> | ||
{ | ||
/// <summary> | ||
/// When added to a <see cref="CliCommand"/>, it enables the use of a <c>--version</c> option, which when specified in command line input will short circuit normal command handling and instead write out version information before exiting. | ||
/// </summary> | ||
public VersionOption() : base("--version", Array.Empty<string>()) | ||
{ | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
// DESIGN: not included in System.CommandLine namespace since most of the users won't ever need to use CliArgument type | ||
namespace System.CommandLine.Symbols; | ||
|
||
/// <summary> | ||
/// A symbol defining a value that can be passed on the command line to a <see cref="CliCommand">command</see> or <see cref="CliOption">option</see>. | ||
/// </summary> | ||
public abstract class CliArgument : CliSymbol | ||
{ | ||
private protected CliArgument(string name) : base(name) { } | ||
|
||
// DESIGN: HelpName is not included, as Help was moved out of main package | ||
|
||
/// <summary> | ||
/// Gets or sets the <see cref="Type" /> that the argument token(s) will be converted to. | ||
/// </summary> | ||
public abstract Type ValueType { get; } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
using System.CommandLine.Symbols; | ||
|
||
// DESIGN: this type will be frequently used and that it's why in the main namespace | ||
namespace System.CommandLine; | ||
|
||
public class CliArgument<T> : CliArgument | ||
{ | ||
/// <summary> | ||
/// Initializes a new instance of the Argument class. | ||
/// </summary> | ||
/// <param name="name">The name of the argument. It's not used for parsing, only when displaying Help or creating parse errors.</param>> | ||
public CliArgument(string name) : base(name) { } | ||
|
||
/// <inheritdoc /> | ||
public override Type ValueType => typeof(T); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
using System.Collections; | ||
using System.Collections.Generic; | ||
using System.CommandLine.Symbols; | ||
using System.ComponentModel; | ||
|
||
// DESIGN: this type will be frequently used and that it's why in the main namespace | ||
namespace System.CommandLine; | ||
|
||
/// <summary> | ||
/// Represents a specific action that the application performs. | ||
/// </summary> | ||
/// <remarks> | ||
/// Use the Command object for actions that correspond to a specific string (the command name). See | ||
/// <see cref="RootCommand"/> for simple applications that only have one action. For example, <c>dotnet run</c> | ||
/// uses <c>run</c> as the command. | ||
/// </remarks> | ||
public class CliCommand : CliSymbol, IEnumerable<CliSymbol> | ||
{ | ||
/// <summary> | ||
/// Initializes a new instance of the Command class. | ||
/// </summary> | ||
/// <param name="name">The name of the command.</param> | ||
/// <param name="description">The description of the command, shown in help.</param> | ||
public CliCommand(string name, string? description = null) : base(name) => Description = description; | ||
|
||
/// <summary> | ||
/// Gets the child symbols. | ||
/// </summary> | ||
// DESIGN: it's virtual so CliRootCommand can add Directives | ||
public virtual IEnumerable<CliSymbol> Children | ||
{ | ||
get | ||
{ | ||
foreach (var command in Subcommands) | ||
yield return command; | ||
|
||
foreach (var option in Options) | ||
yield return option; | ||
|
||
foreach (var argument in Arguments) | ||
yield return argument; | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Represents all of the arguments for the command. | ||
/// </summary> | ||
public IList<CliArgument> Arguments { get; } = new List<CliArgument>(); | ||
|
||
/// <summary> | ||
/// Represents all of the options for the command, including global options that have been applied to any of the command's ancestors. | ||
/// </summary> | ||
public IList<CliOption> Options { get; } = new List<CliOption>(); | ||
|
||
/// <summary> | ||
/// Represents all of the subcommands for the command. | ||
/// </summary> | ||
public IList<CliCommand> Subcommands { get; } = new List<CliCommand>(); | ||
|
||
/// <summary> | ||
/// Gets the unique set of strings that can be used on the command line to specify the command. | ||
/// </summary> | ||
/// <remarks>The collection does not contain the <see cref="CliSymbol.Name"/> of the Command.</remarks> | ||
public ICollection<string> Aliases { get; } = new HashSet<string>(); | ||
|
||
/// <summary> | ||
/// Adds a <see cref="CliSymbol"/> to the command. | ||
/// </summary> | ||
/// <param name="symbol">The symbol to add to the command.</param> | ||
[EditorBrowsable(EditorBrowsableState.Never)] // hide from intellisense, it's public for C# duck typing | ||
// DESIGN: it's virtual so CliRootCommand can add Directives | ||
public virtual void Add(CliSymbol symbol) | ||
{ | ||
switch (symbol) | ||
{ | ||
case CliOption option: Options.Add(option); break; | ||
case CliArgument argument: Arguments.Add(argument); break; | ||
case CliCommand command: Subcommands.Add(command); break; | ||
default: throw new NotSupportedException(); | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Represents all of the symbols for the command. | ||
/// </summary> | ||
public IEnumerator<CliSymbol> GetEnumerator() => Children.GetEnumerator(); | ||
|
||
/// <inheritdoc /> | ||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
namespace System.CommandLine.Symbols; | ||
|
||
/// <summary> | ||
/// The purpose of directives is to provide cross-cutting functionality that can apply across command-line apps. | ||
/// Because directives are syntactically distinct from the app's own syntax, they can provide functionality that applies across apps. | ||
/// | ||
/// A directive must conform to the following syntax rules: | ||
/// * It's a token on the command line that comes after the app's name but before any subcommands or options. | ||
/// * It's enclosed in square brackets. | ||
/// * It doesn't contain spaces. | ||
/// </summary> | ||
public class CliDirective : CliSymbol | ||
{ | ||
/// <summary> | ||
/// Initializes a new instance of the Directive class. | ||
/// </summary> | ||
/// <param name="name">The name of the directive. It can't contain whitespaces.</param> | ||
public CliDirective(string name) : base(name) { } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
using System.Collections.Generic; | ||
|
||
// DESIGN: not included in System.CommandLine namespace since most of the users won't ever need to use CliOption type | ||
namespace System.CommandLine.Symbols; | ||
|
||
/// <summary> | ||
/// A symbol defining a named parameter and a value for that parameter. | ||
/// </summary> | ||
public abstract class CliOption : CliSymbol | ||
{ | ||
private protected CliOption(string name) : base(name) { } | ||
|
||
// DESIGN: HelpName is not included, as Help was moved out of main package | ||
|
||
/// <summary> | ||
/// When set to true, this option will be applied to the command and recursively to subcommands. | ||
/// It will not apply to parent commands. | ||
/// </summary> | ||
public bool Recursive { get; set; } | ||
|
||
/// <summary> | ||
/// Indicates whether the option is required when its parent command is invoked. | ||
/// </summary> | ||
/// <remarks>When an option is required and its parent command is invoked without it, an error results.</remarks> | ||
public bool Required { get; set; } | ||
|
||
/// <summary> | ||
/// Gets the unique set of strings that can be used on the command line to specify the Option. | ||
/// </summary> | ||
/// <remarks>The collection does not contain the <see cref="CliSymbol.Name"/> of the Option.</remarks> | ||
public ICollection<string> Aliases { get; } = new HashSet<string>(); | ||
|
||
/// <summary> | ||
/// Gets or sets the <see cref="Type" /> that the argument token(s) will be converted to. | ||
/// </summary> | ||
public abstract Type ValueType { get; } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
using System.CommandLine.Symbols; | ||
|
||
// DESIGN: this type will be frequently used and that it's why in the main namespace | ||
namespace System.CommandLine; | ||
|
||
public class CliOption<T> : CliOption | ||
{ | ||
/// <summary> | ||
/// Initializes a new instance of the Option class. | ||
/// </summary> | ||
/// <param name="name">The name of the option. It's used for parsing, displaying Help and creating parse errors.</param>> | ||
/// <param name="aliases">Optional aliases. Used for parsing, suggestions and displayed in Help.</param> | ||
public CliOption(string name, params string[] aliases) : base(name) | ||
{ | ||
foreach (string alias in aliases) Aliases.Add(alias); | ||
} | ||
|
||
/// <inheritdoc /> | ||
public override Type ValueType => typeof(T); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
using System.Collections.Generic; | ||
|
||
// DESIGN: not included in System.CommandLine namespace since most of the users won't ever need to use CliSymbol type | ||
namespace System.CommandLine.Symbols; | ||
|
||
public abstract class CliSymbol | ||
{ | ||
// DESIGN: we don't allow for custom symbols by design. The users can derive only from CliCommand, CliArgument<T>, CliOption<T> and Directive. | ||
private protected CliSymbol(string name) => Name = name; | ||
|
||
// DESIGN: it's virtual so the users can customize the behavior. Example: lazily load the description from resources | ||
/// <summary> | ||
/// Gets or sets the description of the symbol. | ||
/// </summary> | ||
public virtual string? Description { get; set; } | ||
|
||
/// <summary> | ||
/// Indicates that the symbol terminates a command line parsing. | ||
/// Example: help. | ||
/// </summary> | ||
// DESIGN: simple things should be simple, advanced possible. Setting it to true requires creating a custom derived type. | ||
public bool Terminating { get; protected set; } = false; | ||
|
||
/// <summary> | ||
/// Gets the name of the symbol. | ||
/// </summary> | ||
public string Name { get; } | ||
|
||
/// <summary> | ||
/// Gets or sets a value indicating whether the symbol is hidden. | ||
/// </summary> | ||
public bool Hidden { get; set; } | ||
|
||
/// <summary> | ||
/// Gets the parent symbols. | ||
/// </summary> | ||
public IEnumerable<CliSymbol> Parents => throw new NotImplementedException(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFrameworks>netstandard2.0;net8.0</TargetFrameworks> | ||
<LangVersion>10.0</LangVersion> | ||
<Nullable>enable</Nullable> | ||
</PropertyGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
|
||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
# Visual Studio Version 17 | ||
VisualStudioVersion = 17.8.34110.38 | ||
MinimumVisualStudioVersion = 10.0.40219.1 | ||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.CommandLine.Parsing", "System.CommandLine.Parsing\System.CommandLine.Parsing.csproj", "{BEDEF4C5-9913-4FFA-94B1-1C7D1CE84AFD}" | ||
EndProject | ||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.CommandLine", "System.CommandLine\System.CommandLine.csproj", "{1D8CAF32-F227-44CE-AFF1-E6E745EFCA8C}" | ||
EndProject | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.CommandLine.Help", "System.CommandLine.Help\System.CommandLine.Help.csproj", "{277CF12C-6E74-45CF-86E2-F19A39E4A6B9}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|Any CPU = Debug|Any CPU | ||
Release|Any CPU = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{BEDEF4C5-9913-4FFA-94B1-1C7D1CE84AFD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{BEDEF4C5-9913-4FFA-94B1-1C7D1CE84AFD}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{BEDEF4C5-9913-4FFA-94B1-1C7D1CE84AFD}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{BEDEF4C5-9913-4FFA-94B1-1C7D1CE84AFD}.Release|Any CPU.Build.0 = Release|Any CPU | ||
{1D8CAF32-F227-44CE-AFF1-E6E745EFCA8C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{1D8CAF32-F227-44CE-AFF1-E6E745EFCA8C}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{1D8CAF32-F227-44CE-AFF1-E6E745EFCA8C}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{1D8CAF32-F227-44CE-AFF1-E6E745EFCA8C}.Release|Any CPU.Build.0 = Release|Any CPU | ||
{277CF12C-6E74-45CF-86E2-F19A39E4A6B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{277CF12C-6E74-45CF-86E2-F19A39E4A6B9}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{277CF12C-6E74-45CF-86E2-F19A39E4A6B9}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{277CF12C-6E74-45CF-86E2-F19A39E4A6B9}.Release|Any CPU.Build.0 = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(SolutionProperties) = preSolution | ||
HideSolutionNode = FALSE | ||
EndGlobalSection | ||
GlobalSection(ExtensibilityGlobals) = postSolution | ||
SolutionGuid = {1F4FC9E8-F6C7-4BA3-B947-720A288E9242} | ||
EndGlobalSection | ||
EndGlobal |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
using System.Collections.Generic; | ||
using System.CommandLine.Help; | ||
using System.CommandLine.Symbols; | ||
|
||
// DESIGN: this type will be frequently used, that it's why in the main namespace | ||
namespace System.CommandLine; | ||
|
||
public class CliRootCommand : CliCommand | ||
{ | ||
public CliRootCommand(string name, string? description = null) : base(name, description) | ||
{ | ||
Options.Add(new HelpOption()); | ||
Options.Add(new VersionOption()); | ||
} | ||
|
||
/// <summary> | ||
/// Represents all of the directives for the command. | ||
/// </summary> | ||
public IList<CliDirective> Directives { get; } = new List<CliDirective>(); | ||
|
||
public override void Add(CliSymbol symbol) | ||
{ | ||
if (symbol is CliDirective directive) Directives.Add(directive); | ||
else base.Add(symbol); | ||
} | ||
|
||
public override IEnumerable<CliSymbol> Children | ||
{ | ||
get | ||
{ | ||
foreach (CliSymbol child in base.Children) yield return child; | ||
foreach (CliDirective directive in Directives) yield return directive; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// DESIGN: this type will be referenced by CliRootCommand and enabled by default, that is why it's not in the main namespace | ||
namespace System.CommandLine.Symbols; | ||
|
||
/// <summary> | ||
/// Enables the use of the <c>[diagram]</c> directive, which when specified on the command line will short | ||
/// circuit normal command handling and display a diagram explaining the parse result for the command line input. | ||
/// </summary> | ||
/// Example: dotnet [diagram] build -c Release -f net7.0 | ||
/// Output: [ dotnet [ build [ -c <Release> ] [ -f <net7.0> ] ] ] | ||
public sealed class DiagramDirective : CliDirective | ||
{ | ||
/// <param name="errorExitCode">If the parse result contains errors, this exit code will be used when the process exits.</param> | ||
public DiagramDirective() : base("diagram") { } | ||
|
||
public int ParseErrorReturnValue { get; set; } = 1; | ||
} |
Oops, something went wrong.