Table of Contents

Cli Class

Definition

Namespace
DotMake.CommandLine
Assembly
DotMake.CommandLine.dll

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

public static class Cli
Inheritance
Cli

Examples

//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}'");
}
// 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 result = Cli.Parse<RootCliCommand>(args);
var rootCliCommand = result.Bind<RootCliCommand>();
// A root cli command which shows help if command is empty, i.e. no arguments or options are passed.
// Arguments and options should be optional, if they are required (no default values),
// then handler will not run and missing error message will be shown.

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

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

    public void Run(CliContext context)
    {
        if (context.IsEmptyCommand())
            context.ShowHelp();
        else
            context.ShowValues();
    }
}
//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 result = Cli.Parse<RootCliCommand>(args);
if (result.ParseResult.Errors.Count > 0)
{

}
//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 });
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; } = "DefaultForArgument1";

    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 argsavailable in Program.cs(new style with top-level statements) or as the string array passed to the program's Mainmethod (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.

GetParser(Type, CliSettings)

Gets a CLI parser configured for the indicated command.

GetParser<TDefinition>(CliSettings)

Gets a CLI parser configured for the indicated command.

Parse<TDefinition>(string, CliSettings)

Parses a command line string and returns the parse result for the indicated command.

Parse<TDefinition>(string[], CliSettings)

Parses a command line string array and returns the parse result for the indicated command.

Run(Delegate, CliSettings)

Parses the command line arguments and runs the indicated command as delegate.

Run<TDefinition>(string, CliSettings)

Parses a command line string value and runs the handler for the indicated command.

Run<TDefinition>(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.

RunAsync<TDefinition>(string, CliSettings, CancellationToken)

Parses a command line string value and runs the handler asynchronously for the indicated command.

RunAsync<TDefinition>(string[], CliSettings, CancellationToken)

Parses a command line string array and runs the handler asynchronously for the indicated command.