Cli Class

Provides methods for parsing command line input and running an indicated command.

Definition

Namespace: DotMake.CommandLine
Assembly: DotMake.CommandLine (in DotMake.CommandLine.dll) Version: 1.8.7
C#
public static class Cli
Inheritance
Object    Cli

Example

C#
//Delegate-based model
//In Program.cs, add this simple code:
Cli.Run(([CliArgument] string argument1, bool option1) =>
{
    Console.WriteLine($@"Value for {nameof(argument1)} parameter is '{argument1}'");
    Console.WriteLine($@"Value for {nameof(option1)} parameter is '{option1}'");
});

//Or:
Cli.Run(Method);

void Method([CliArgument] string argument2, bool option2)
{
    Console.WriteLine($@"Value for {nameof(argument2)} parameter is '{argument2}'");
    Console.WriteLine($@"Value for {nameof(option2)} parameter is '{option2}'");
}
C#
// Class-based model
// Create a simple class like this:

[CliCommand(Description = "A root cli command")]
public class RootCliCommand
{
    [CliOption(Description = "Description for Option1")]
    public string Option1 { get; set; } = "DefaultForOption1";

    [CliArgument(Description = "Description for Argument1")]
    public string Argument1 { get; set; }

    public void Run()
    {
        Console.WriteLine($@"Handler for '{GetType().FullName}' is run:");
        Console.WriteLine($@"Value for {nameof(Option1)} property is '{Option1}'");
        Console.WriteLine($@"Value for {nameof(Argument1)} property is '{Argument1}'");
        Console.WriteLine();
    }
}

        //In Program.cs, add this single line:
        Cli.Run<RootCliCommand>(args);

        //If you need to simply parse the command-line arguments without invocation, use this:
        var parseResult = Cli.Parse<RootCliCommand>(args);
        var rootCliCommand = parseResult.Bind<RootCliCommand>();
C#
//In Program.cs, add this single line for returning exit code:
return Cli.Run<RootCliCommand>(args);

//In Program.cs, to go async, add this single line:
await Cli.RunAsync<RootCliCommand>(args);

//In Program.cs, to go async, add this single line for returning exit code:
return await Cli.RunAsync<RootCliCommand>(args);

//If you need to examine the parse result, such as errors:
var parseResult = Cli.Parse<RootCliCommand>(args);
if (parseResult.Errors.Count > 0)
{

}
C#
//To handle exceptions, you just use a try-catch block:
try
{
    Cli.Run<RootCliCommand>(args);
}
catch (Exception e)
{
    Console.WriteLine(@"Exception in main: {0}", e.Message);
}

//System.CommandLine, by default overtakes your exceptions that are thrown in command handlers
//(even if you don't set an exception handler explicitly) but DotMake.CommandLine, by default allows
//the exceptions to pass through. However if you wish, you can easily use the default exception handler
//by passing a `CliSettings` instance like below. Default exception handler prints the exception in red color to console:
Cli.Run<RootCliCommand>(args, new CliSettings { EnableDefaultExceptionHandler = true });
C#
using DotMake.CommandLine;
using Microsoft.Extensions.DependencyInjection;


// When the source generator detects that your project has reference to `Microsoft.Extensions.DependencyInjection`,
// it will generate extension methods for supporting dependency injection.
// For example, you can now add your services with the extension method `Cli.Ext.ConfigureServices`:

Cli.Ext.ConfigureServices(services =>
{
    services.AddTransient<TransientClass>();
    services.AddScoped<ScopedClass>();
    services.AddSingleton<SingletonClass>();
});

Cli.Run<RootCliCommand>();



    //Then let them be injected to your command class automatically by providing a constructor with the required services:

    [CliCommand(Description = "A root cli command with dependency injection")]
    public class RootCliCommand
    {
        private readonly TransientClass transientDisposable;
        private readonly ScopedClass scopedDisposable;
        private readonly SingletonClass singletonDisposable;

        public RootCliCommand(
            TransientClass transientDisposable,
            ScopedClass scopedDisposable,
            SingletonClass singletonDisposable
        )
        {
            this.transientDisposable = transientDisposable;
            this.scopedDisposable = scopedDisposable;
            this.singletonDisposable = singletonDisposable;
        }

        [CliOption(Description = "Description for Option1")]
        public string Option1 { get; set; } = "DefaultForOption1";

        [CliArgument(Description = "Description for Argument1")]
        public string Argument1 { get; set; }

        public void Run()
        {
            Console.WriteLine($@"Handler for '{GetType().FullName}' is run:");
            Console.WriteLine($@"Value for {nameof(Option1)} property is '{Option1}'");
            Console.WriteLine($@"Value for {nameof(Argument1)} property is '{Argument1}'");
            Console.WriteLine();

            Console.WriteLine($"Instance for {transientDisposable.Name} is available");
            Console.WriteLine($"Instance for {scopedDisposable.Name} is available");
            Console.WriteLine($"Instance for {singletonDisposable.Name} is available");
            Console.WriteLine();
        }
    }

    public sealed class TransientClass : IDisposable
    {
        public string Name => nameof(TransientClass);

        public void Dispose() => Console.WriteLine($"{nameof(TransientClass)}.Dispose()");
    }

    public sealed class ScopedClass : IDisposable
    {
        public string Name => nameof(ScopedClass);

        public void Dispose() => Console.WriteLine($"{nameof(ScopedClass)}.Dispose()");
    }

    public sealed class SingletonClass : IDisposable
    {
        public string Name => nameof(SingletonClass);

        public void Dispose() => Console.WriteLine($"{nameof(SingletonClass)}.Dispose()");
    }

Properties

Ext Provides extension methods for Cli. These are usually automatically generated by the source generator when current project supports a specific feature through a dependency, e.g. when you add package Microsoft.Extensions.DependencyInjection, dependency injection related extension methods will be available here.

Methods

GetArgs Returns a string array containing the command-line arguments for the current process.

Uses GetCommandLineArgs but skips the first element which is the executable file name, so the following zero or more elements that contain the remaining command-line arguments are returned, i.e. returns the same as the special variable args available in Program.cs (new style with top-level statements) or as the string array passed to the program's Main method (old style).

Also on Windows platform, backslash + double quote (\") at the end of an argument, is usually a path separator and not an escape for double quote, so it will be trimmed to prevent unnecessary path errors.

GetConfiguration(Type, CliSettings) Gets a CLI configuration for the indicated command.
GetConfigurationTDefinition(CliSettings) Gets a CLI configuration for the indicated command.
ParseTDefinition(String, CliSettings) Parses a command line string and returns the parse result.
ParseTDefinition(String, CliSettings) Parses a command line string array and returns the parse result.
Run(Delegate, CliSettings) Parses the command line arguments and runs the indicated command as delegate.
RunTDefinition(String, CliSettings) Parses a command line string value and runs the handler for the indicated command.
RunTDefinition(String, CliSettings) Parses a command line string array and runs the handler for the indicated command.
RunAsync(Delegate, CliSettings, CancellationToken) Parses the command line arguments and runs the indicated command as delegate.
RunAsyncTDefinition(String, CliSettings, CancellationToken) Parses a command line string value and runs the handler asynchronously for the indicated command.
RunAsyncTDefinition(String, CliSettings, CancellationToken) Parses a command line string array and runs the handler asynchronously for the indicated command.

See Also