CommandLine.NetCore
1.0.10
See the version list below for details.
dotnet add package CommandLine.NetCore --version 1.0.10
NuGet\Install-Package CommandLine.NetCore -Version 1.0.10
<PackageReference Include="CommandLine.NetCore" Version="1.0.10" />
paket add CommandLine.NetCore --version 1.0.10
#r "nuget: CommandLine.NetCore, 1.0.10"
// Install CommandLine.NetCore as a Cake Addin #addin nuget:?package=CommandLine.NetCore&version=1.0.10 // Install CommandLine.NetCore as a Cake Tool #tool nuget:?package=CommandLine.NetCore&version=1.0.10
CommandLine.NetCore
CommandLine.NetCore library provides support to handle command line arguments (parse, validate, command pattern) for .Net Core console applications with ANSI VT support (cursor,colors,screen size) for multi-plateform (windows, linux, osx, arm) console applications using C# and .NET Core 6
This project is licensed under the terms of the MIT license: LICENSE.md
Index
Features
The library provides functionalities needed to build console applications running in a terminal (WSL/WSL2, cmd.exe, ConEmu, bash, ...) with text interface. That includes:
parsing command line arguments
command pattern helps implementing commands binded to methods from command line in a simple and regular way
multi-language commands help configuration files
automatic help command
can compile a .exe for a a single command command, showing only the help for a specific command, or for several commands, showing a help for all commands as a shell would do
compatible with AnsiVtConsole.NetCore :
a text printer engine that supports print directives (markup) allowing to manage console functionalities from text itself, as html would do but with a simplest syntax (that can be configured). That makes possible colored outputs, cursor control, text scrolling and also dynamic C# execution (scripting), based on System.Console and ANSI VT100 / VT52 (VT100 type Fp or 3Fp, Fs, CSI, SGR)
A Ansi Parser that can identify/remove escape sequences in a text
The console output can be controlled by:
- tokens in a string (print directives)
- as string shortcuts (dynamic ansi vt strings)
- throught API methods
Howto
1. Running the command line
download the nuget from command line or add it from Visual Studio
dotnet add package CommandLine.NetCore
Notice
When installing the package, the following files are copied into your project:
- Config/appSettings.core.json
the file Config/appSettings.core.json is mandatory since it contains the CommandLine.NetCore parser root configuration
link to the library in your console application main class (example: Program.cs):
using CommandLine.NetCore.Services.CmdLine;
from your main method of your app or using top level statements, transfer control to the library CommandLine.NetCore :
Program.cs
namespace MyConsoleApp;
/// <summary>
/// command line input
/// <para>commandName ( option (optionValue)* | parameter )* globalOption*</para>
/// </summary>
/// <param name="args">arguments</param>
/// <returns>status code</returns>
public static int Main(string[] args)
=> new CommandLineInterfaceBuilder()
.Build(args)
.Run();
or using a top level statement:
new CommandLineInterfaceBuilder()
.Build(args)
.Run();
That leads to the loading of any command line components like global arguments, commands and help settings from both the library core and your own console app and parsing of the declared syntaxes and eventualy execution of the method corresponding to the matching syntax.
2. Testing the integrated help command:
Any console application built with the library ComandLine.NetCore implements by
default a command named help
that dump any available help about commands that are
implemented in the software that uses the library and in the library itself.
As an example, you can build the example application console, provided in the project CommandLine.NetCore.Example
,
Just execute in your favorite shell this command (available in the folder bin/Release/net6.0
):
./CommandLine.NetCore.Example.exe help
To get the help for a particular command, the syntax is help {commandName}
. In this example you
get help about the command help:
./CommandLine.NetCore.Example.exe help help
3. Configuring the library and a console application built with it
The library settings provides the description of the application and of the commands, and also the translation of texts. You should override these settings according to your needs.
Every settings are pushed throught IHostBuilder.ConfigureAppConfiguration
.
Settings are looked up by this way, in the specified order:
provided by the library CommandLine.NetCore:
appSettings.core.json
: this file contains the settings needed by the core functionalities of the library: decription of the library, texts and description of the integrated command, in the default language (en-us)appSettings.core.{culture}.json
: same as above, any of these files provides translations for the culture specified by the tag{culture}
according to available cultures specified inMicrosoft.
. The settings file that matches the current platform culture is loaded if it exists.
provided by your application;
appSettings.json
: dscription of the commands provided by your application, the texts, and any settings in the default language (en-us)appSettings.{culture}.json
: same as above for the translations of the culture specified by the tag{culture}
The settings must conform with the following conventions:
Informations about application
"App": {
"Title": "CommandLine.NetCore",
"ReleaseDate": "10/12/2022"
}
Texts
"Texts": {
"{TextId}": "Text"
}
Description of the commands
"Commands": {
"{CommandName}": {
"Description": "short description of the command",
"Syntax": {
"{Syntax 1}" : "Description of the functionality provided by the syntax 1",
...
"{Syntax n}" : "Description of the functionality provided by the syntax n",
},
"Options": {
"{Option 1}" : "Description of the command option 1",
...
"{Option n}" : "Description of the command option n",
}
}
}
example of the command help
:
"Commands": {
"help": {
"Description": "output a of list commands and global arguments or output help about a command",
"Syntax": {
"": "list all commands",
"commandName": "help about the command with name commandName"
},
"Options": {
"-v": "enable verbose: add details to normal output",
"--info" : "output additional informations about the command line context"
}
}
},
These settings are describing the following syntaxes for the command help
:
; help for a command
help {commandName} [-v] [--info]
; global help (all commands)
help [-v] [--info]
Command options are optionals and are available for any syntax of the command (here -v and --info). They can appears from the position they are declared in the command syntax
Description of the global arguments
"GlobalOptions": {
"{ArgumentName}": {
"{Syntax}" : "Description of the functionality provided by the argument syntax"
}
}
Global arguments are optional and availables for any command. They must appear from the end of the command arguments
example of the global argument s
:
"GlobalOptions": {
"s": {
"-s" : "turn off any output (silent mode)"
}
}
by convention (POSIX), single letter arguments are prefixed by -
, whereas arguments with
several letters are prefixed by --
4. Implementing a command
A command specification and implementation is defined in a class that inherits from CommandLine.NetCore.Services.CmdLine.Commands.Command
.
- the name of the command is
kebab case
from the name of the class (in this case GetInfo declares the get-info command) - the command class msut have a constructor with parameter
Dependencies
. These classes are instantiated by the dependency injector, thus any registered dependency can be added as a constructor parameter - the command class must implements the method:
CommandResult Execute(ArgSet args)
- the method
Execute
declares the syntaxes of the command and the related implementations - the method
For
declares a command syntax:For(params Arg[] syntax)
- the list of arguments are specifing the command syntax
- an
Arg
is either anoption
or aparameter
. Their grammar is defined as this:Option ::= [-|--]{optionName}[value0..valuen]
- options can be expected or optionnal
- options can have from 0 to n values
- can have from 0 to n values of a type
T
, where T can be any scalar type, a collection of scalar types (with,
as separator) or an Enum - an option can be defined with values, values are always expected
Opt("x")
builds the optionx
with no expected value:-x
- by convention (posix), if the length of the name of the option is greater than 1, the prefix becomes:
--
. For instance,Opt("xy")
defines the syntax:--xy
Opt("x",true)
builds the optionx
wich is optional in the syntaxOpt<T>("value")
builds the optionvalue
having one expected value that must be convertible to typeT
. For instance,Opt<int>("value")
defines an option that expect an int, like in syntax:--value 123
- Flag is a construct of an Opt without value
Parameter ::= parameterValue?
- parameters have exactly one value
- parameters are always expected
- have a value of a type
T
, where T can be any scalar type, a collection of scalar types (with,
as separator) or an Enum - if a parameter if defined with a value, it is an expected word in the syntax
- if a parameter is defined without a value, a value is expected in the syntax
Param()
builds a parameter that expect a value of typestring
like in syntax:iamastring
Param<T>()
builds a parameter that expect a value that must be convertible to typeT
. For instance,Param<int>()
builds a parameter that expect a value of typeint
, like in syntax:123
Param("color")
builds a parameter that is expected and being the syntax:color
- an
the method
Do
chained to a For indicates the method that must be executed if the syntax match the command line args:- the most common way to define the operation method si the lambda expression, since it allows to use a standard method with concrete typed parameters (not Opt,Param,.. but the values types inside it) :
// takes a method in a lambda unary call expression: () => methodName, takes a called method with no parameter, takes a called method with a default command result (code ok, result null). // Allows to map command arguments to method parameters and operation context Do(LambdaExpression expression)
- others operation methods prototypes that are accepted:
// with no parameter and void result delegate Do(Action @delegate) // with no parameter and void result delegate Do(Func<OperationResult> @delegate) // with parameter operation context and void delegate Do(Action<OperationContext> @delegate) // with parameter operation context and OperationResult result delegate Do(Func<OperationContext, OperationResult> @delegate)
the lambda expression in the method style
Do(LambdaExpression expression)
can have one of these profiles:- the most practical is the use of concrete values types (not Opt,Param,.. but the values types inside it):
// arguments mapping to concrete types // also accepts an OperationContext parameter placed anywhere // also accepts explicit mapping of arguments, with positional references in syntax, and no result // avoid repeating the command arguments declarations (Param, Opt) void MyOperation( string arg0, bool arg1 , ..)
- others lambda expressions prototypes that are accepted:
// no parameter and no result void MyOperation() // explicit mapping of arguments, with positional references in syntax, and no result void MyOperation([MapArg(1) Param<string> arg0,[MapArg(5)] Opt<bool> arg1) // implicit mapping of arguments and no result // expected arguments (arguments having expected valie(s)) are mapped according to their declaring order void MyOperation(Param<string> arg0,Opt<bool> arg1) // can also have an auto-mapped parameter to the operation context: // a parameter of type OperationContext can be placed anywhere in the parameters list void MyOperation(...,OperationContext context,..)
methods
For
can be chainedthe method
Options
can be chained to a For. This method allows to declare the command global options (avalaible for any syntax of the command) :Options(params IOpt[] options)
the method
With
launch the command executing process. First command line parsing, then syntax matching, then operation dispatch:With(ArgSet args)
Arguments to concrete types mapping of Do(LambdaExpression expression)
expression parameters:
Flags
argument constructor | possible corresponding type(s) |
---|---|
Flag("argName") |
bool |
Flag("argName",isOptional: true) |
bool |
Options
argument constructor | possible corresponding type(s) |
---|---|
Opt("argName") <br> Opt("argName",valueCount:0) |
as it is expected to exactly match the syntax argName (expected values count = 0), this arg must not be mapped |
Opt("argName",isOptional: true) <br> Opt("argName",isOptional: true,valueCount:0) |
bool (because expected values count = 0, acts as Flag in that case) |
Opt("argName",valueCount:1) |
string |
Opt("argName",isOptional: true,valueCount:1) |
string? or null |
Opt("argName",valueCount:2..n) |
List<string> |
Opt("argName",isOptional: true,valueCount:2..n) |
List<string>? or null |
Opt<T>("argName",valueCount:0) |
as it is expected to exactly match the syntax argName (expected values count = 0), this arg must not be mapped |
Opt<T>("argName",isOptional: true,valueCount:0) |
bool (because expected values count = 0, acts as Flag in that case) |
Opt<T>("argName") <br> Opt<T>("argName",valueCount:1) |
T |
Opt<T>("argName",isOptional: true) <br> Opt<T>("argName",isOptional: true,valueCount:1) |
T? or default |
Opt<T>("argName",valueCount:2..n) |
List<T> |
Opt<T>("argName",isOptional: true,valueCount:2..n) |
List<T>? or null |
Parameters
argument constructor | possible corresponding type(s) |
---|---|
Param() |
string |
Param_T() |
T |
Param("keyWord") |
as it is expected to exactly match the syntax keyWord, this arg must not be mapped |
Exemple of the command help
defined in CommandLine.NetCore.Commands.CmdLine
:
// command syntax: help [commandName] [-v] [--info]
internal sealed class Help : Command
{
protected override CommandResult Execute(ArgSet args) =>
// syntax: help
For()
.Do(() => DumpHelpForAllCommands)
// syntax: help {commandName}
.For(Param())
.Do(() => DumpCommandHelp)
// any syntax accepts -v and/or --info
.Options(Opt("v"), Opt("info"))
// parse and run
.With(args);
private void DumpCommandHelp(string commandName, bool verbose, bool info)
{
// ...
}
private void DumpHelpForAllCommands(bool verbose, bool info)
{
// ...
}
}
Exemple of the command get-info
defined in CommandLine.NetCore.Example.Commands.GetInfo
:
// syntax: get-info (env -l) | (env {varName}) | console | system | --all
internal sealed class GetInfo : Command
{
protected override CommandResult Execute(ArgSet args) =>
// syntax: get-info env -l
For(
Param("env"),
Opt("l")
)
.Do(DumpAllVars)
// syntax: get-info env {varName}
.For(
Param("env"),
Param())
.Do(() => DumpEnvVar)
// syntax: get-info console
.For(
Param("console"))
.Do(DumpConsole)
// syntax: get-info system
.For(
Param("system"))
.Do(DumpSystem)
// syntax: get-info --all
.For(
Opt("all"))
.Do(DumpAll)
// parse and run
.With(args);
private void DumpEnvVar(string envVarName)
{
// ...
}
}
5. Setup an unique command console app (without command argument)
You can prepare a console application that run immediately a specific command at launch and that doesn't requires a command name argument, by activating this option in the main of your app or using top level statements as shown below:
Program.cs
using CommandLine.NetCore.Services.CmdLine;
new CommandLineInterfaceBuilder()
// add this for single command mode (here: only get-info, no global help)
.ForCommand<GetInfo>()
// add this to avoid global help of the command line parser
.DisableGlobalHelp()
.Build(args)
.Run();
This example will produce an executable that do not accept a command name parameter
neither the help
global command.
If the program is compiled as MyConsoleApp.exe
the following command lines are accepted:
- get help about the get-info command:
MyConsoleApp.exe -h
┌──────────────────────────────────────────────────┐
│ CommandLine.NetCore.Example (1.0.9.0 05/08/2023) │
└──────────────────────────────────────────────────┘
sample command that output informations about system and console
-h : help about this command
--all : output all infos
console : dump infos about console
env -l : list of environment variables names and values
env varName : dump environment variable value with name varName
system : dump infos about system
- run the get-info command:
MyConsoleApp.exe system
system informations:
Operanting System = Microsoft Windows NT 10.0.22621.0
ProcArch = AMD64
Processor Model = Intel64 Family 6 Model 165 Stepping 2, GenuineIntel
Processor Level = 6
System Directory = C:\WINDOWS\system32
Processor Count = 12
User Domain Name = LAPTOP-R3538U70
User Name = franc
Version = 6.0.20
C:\ =
C:\ Volume Label = Windows
C:\ Drive Type = Fixed
C:\ Drive Format = NTFS
C:\ Total Size = 511280410624
C:\ Available FreeSpace = 98612314112
6. Debug and troobleshoot
Integrated options
Integrated command line parser options may help the command developer to fix issues:
parser traces
--parser-logging logLevel
enable display of parser syntaxes analysis detailed informations. Possibles values from Microsoft.Extensions.Logging.LogLevel.
If Trace
or Debug
the parser add detailed informations about the parsed syntaxes
CommandLine.NetCore.Example.exe help --parser-logging Debug
HelpAboutCommandSyntax: 0:Opt<String>-h 1:Opt?<String>-v 2:Opt?<String>--info 3:Opt?<String>-v 4:Opt?<String>--info : match=False
DumpHelpForAllCommands: 0:Opt?<String>-v 1:Opt?<String>--info 2:Opt?<String>-v 3:Opt?<String>--info : match=True
DumpCommandHelp: 0:Param<String>? 1:Opt?<String>-v 2:Opt?<String>--info 3:Opt?<String>-v 4:Opt?<String>--info : match=False
parser setup
--exclude-ambiguous-syntax
exclude any ambiguous syntax when parsing command line arguments. By default, the first matching syntax is selected in the command line arguments parser.
If this option is set syntaxes of a command can't be ambiguous
Versions history
1.0.10
- 08/06/2023
- add support of mapping to array parameters when possible (instead of List) in command lambda operations
- add global option --disable-global-help
- doc update
1.0.9
- 08/06/2023
- add support of mapping for parameters having arguments concrete values types in command lambda operation (not Opt,Param,.. but the values types inside it)
- fix bug GetValue when not setted option
- migrate help,test and get-info commands operations methods with concrete type mapping
- improve mapping errors feedback
- add SyntaxMatcherDispatcherException and subclasses
1.0.8
- 01/14/2023
- add single command mode allowing to build an executable for only one command and eventually without the global help
- change editor config and code cleanup
- packages update
1.0.7
- 01/13/2023
- add global option
--no-color
that turn off ansi/vt outputs - fix auto syntax -h was not passing global arguments
- new RunCommand in current host
- improve help output
- embed symbols and sources
1.0.6
- 01/11/2023
- fix MAJOR bug in command options parsing. Were not recongnized correctly
AppHostBuilder
moved to namespaceCommandLine.NetCore.Services.AppHost
- fix auto command -h (Command.RunCommand) didn't call back configure and build delegates
- fix support of -v and --info in -h auto syntax
- doc update
1.0.5
- 01/05/2023
- fix nupkg: adding the package to a project now deploy files Config/appSettings.core.json, LICENSE.md, README.md, assets/ascii-icon.png in your project. These files are configured as 'Content' and are deployed in the
bin
folder. You can remove any of these files EXCEPT Config/appSettings.core.json wich is mandatory since it contains the CommandLine.NetCore parser root configuration - fix doc
1.0.4
- 01/04/2023
- fix nupkg
1.0.3
- 01/04/2023
- fix nupkg
1.0.2
- 01/04/2023
- fix doc
1.0.1
- 01/04/2023
- add CommandContext to lambda operations method
- add support of abstract classes that inherits from command
- rename OperationContext by CommandContext
- fix bug command options were always set in delegate for -h
1.0.0
- 03/01/2023
- init
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
-
net6.0
- AnsiVtConsole.NetCore (>= 1.0.20)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
1.0.32 | 231 | 4/11/2024 |
1.0.31 | 107 | 4/11/2024 |
1.0.30 | 108 | 4/11/2024 |
1.0.29 | 122 | 4/11/2024 |
1.0.28 | 115 | 4/11/2024 |
1.0.27 | 121 | 2/16/2024 |
1.0.26 | 109 | 2/16/2024 |
1.0.25 | 115 | 2/15/2024 |
1.0.24 | 1,390 | 2/15/2024 |
1.0.23 | 128 | 2/14/2024 |
1.0.22 | 114 | 2/14/2024 |
1.0.21 | 119 | 2/12/2024 |
1.0.20 | 127 | 2/12/2024 |
1.0.18 | 128 | 2/1/2024 |
1.0.17 | 110 | 2/1/2024 |
1.0.16 | 111 | 2/1/2024 |
1.0.15 | 1,305 | 2/1/2024 |
1.0.14 | 107 | 2/1/2024 |
1.0.13 | 1,523 | 2/1/2024 |
1.0.12 | 107 | 2/1/2024 |
1.0.11 | 1,413 | 1/10/2024 |
1.0.10 | 2,331 | 8/10/2023 |
1.0.9 | 196 | 8/6/2023 |
1.0.8 | 349 | 1/23/2023 |
1.0.7 | 348 | 1/13/2023 |
1.0.6 | 321 | 1/12/2023 |
1.0.5 | 322 | 1/4/2023 |
1.0.4 | 330 | 1/4/2023 |
1.0.3 | 326 | 1/4/2023 |
1.0.2 | 310 | 1/4/2023 |
1.0.1 | 305 | 1/4/2023 |
1.0.0 | 299 | 1/3/2023 |
`1.0.10` - 08/11/2023
- add global option --disable-global-help + improve help output in single command mode
- add support of mapping to array parameters when possible (instead of List) in command lambda operations
`1.0.9` - 08/06/2023
- add support of mapping for parameters having arguments concrete values types in command lambda operation (not Opt,Param,.. but the values types inside it)
- fix bug GetValue when not setted option
- migrate help,test and get-info commands operations methods with concrete type mapping
- improve mapping errors feedback
- add SyntaxMatcherDispatcherException and subclasses
`1.0.8` - 01/14/2023
- add single command mode allowing to build an executable for only one command and eventually without the global help
- change editor config and code cleanup
- packages update
`1.0.7` - 01/13/2023
- add global option `--no-color` that turn off ansi/vt outputs
- fix auto syntax -h was not passing global arguments
- new RunCommand in current host
- improve help output
- embed symbols and sources
`1.0.6` - 01/11/2023
- fix MAJOR bug in command options parsing. Were not recongnized correctly
- `AppHostBuilder` moved to namespace `CommandLine.NetCore.Services.AppHost`
- fix auto command -h (Command.RunCommand) didn't call back configure and build delegates
- fix support of -v and --info in -h auto syntax
- doc update
`1.0.5` - 01/05/2023
- fix nupkg: adding the package to a project now deploy files Config/appSettings.core.json, LICENSE.md, README.md, assets/ascii-icon.png in your project. These files are configured as 'Content' and are deployed in the `bin` folder.
You can remove any of these files **EXCEPT Config/appSettings.core.json** wich is mandatory since it contains the CommandLine.NetCore parser root configuration
- fix doc
`1.0.4` - 01/04/2023
- fix nupkg
`1.0.3` - 01/04/2023
- fix nupkg
`1.0.2` - 01/04/2023
- fix doc
`1.0.1` - 01/04/2023
- add CommandContext to lambda operations method
- add support of abstract classes that inherits from command
- rename OperationContext by CommandContext
- fix bug command options were always set in delegate for -h
`1.0.0` - 03/01/2023
- init