Skip to content

Releases: dotmake-build/command-line

DotMake.CommandLine v2.8.2

12 Oct 13:25

Choose a tag to compare

  • Fixed: All types in generated code will now be prefixed with global namespace global:: to prevent
    CS0234 errors (namespace and type conflict compile errors) which can happen when user names a namespace part and a class same.
    Example code to replicate the problem (now fixed), note the .TestApp, .System, .DotMake
    as the final part of the namespace which triggered the problem:

    using DotMake.CommandLine;
    
    //Generated code should not fail to compile even if user uses some crazy namespaces
    
    namespace TestApp.Commands.TestApp
    {
        [CliCommand]
        public class TestAppCliCommand
        {
            [CliArgument(Arity = CliArgumentArity.ZeroOrMore)]
            public string Arg { get; set; }
        }
    }
    
    namespace TestApp.Commands.System
    {
        [CliCommand]
        public class SystemCliCommand
        {
    
        }
    }
    
    namespace TestApp.Commands.DotMake
    {
        [CliCommand]
        public class DotMakeCliCommand
        {
    
        }
    }
  • Improved: Documentation for CliContext.IsEmptyCommand() and CliContext.IsEmpty() to emphasize the difference.

DotMake.CommandLine v2.8.1

27 Sep 08:12

Choose a tag to compare

  • Fixed: Help was no longer printed for subcommands with a required argument with v2.8.0.
    This happened due to the update to 2.0.0-rc.1.25451.107 of System.CommandLine.
    There is a new property ClearsParseErrors in SynchronousCommandLineAction
    which from now on, should be overridden to return true for our custom actions like CustomHelpAction and VersionOptionAction.
    Normally our CliHelpBuilder checks for ParseResult.Errors.Count > 0 to avoid printing help when there is a parsing error.
    So as ClearsParseErrors was not set to true, CliHelpBuilder was not printing help as it thought there was a parse error
    i.e. Required argument missing for command, even though -? or -h was passed.

DotMake.CommandLine v2.8.0

12 Sep 19:22

Choose a tag to compare

  • Improved: Updated to version 2.0.0-rc.1.25451.107 of System.CommandLine.
  • Added: MaxWidthproperty to CustomHelpAction
    and ensure correct maxWidth parameter in CliHelpBuilder constructor if not specified.

DotMake.CommandLine v2.7.1

02 Sep 19:56

Choose a tag to compare

  • Fixed: Foreground color is always white on macOS regardless of theme settings.

DotMake.CommandLine v2.7.0

16 Aug 14:42

Choose a tag to compare

  • Updated to version 2.0.0-beta7.25380.108 of System.CommandLine.

DotMake.CommandLine v2.6.8

11 Aug 09:33

Choose a tag to compare

  • Added: Command and RootCommand properties to CliParser class:

    var parser = Cli.GetParser<RootCliCommand>();
    
    //Access the command that is used to parse the command line input.
    var command = parser.Command;
    
    //Access the root of the command that is used to parse the command line input.
    //If parser.Command is already a root command, this will be same instance.
    //If it's a sub-command, it will be the root of that sub-command.
    var rootCommand = parser.RootCommand;
  • Fixed: SourceGenerator sometimes triggers a concurrency exception. Use ConcurrentDictionary for GenerationCounts.

  • Fixed: Do not add auto name or alias for root commands as it can unnecessarily conflict with children.

DotMake.CommandLine v2.6.7

25 Jul 20:11

Choose a tag to compare

  • Fixed: Naming related settings were not being inherited correctly after level-2 sub-commands or above.

  • Fixed: NullReferenceException when invoking help output for a sub-command that had completions.

DotMake.CommandLine v2.6.6

21 Jul 02:23

Choose a tag to compare

  • Updated to version 2.0.0-beta6.25358.103 of System.CommandLine.
    Also use exact version match with [] for PackageReference as future beta versions can break API.

  • Added: Order property to [CliCommand], [CliDirective], [CliOption] and [CliArgument] attributes.
    The order is used when printing the symbols in help and for arguments additionally effects the parsing order.
    When not set (or is 0 - the default value), the symbol order is determined based on source code ordering.

    [CliCommand(Description = "A root cli command with custom order")]
    public class OrderedCliCommand
    {
        [CliOption(Description = "Description for Option1", Order = 2)]
        public string Option1 { get; set; } = "DefaultForOption1";
    
        [CliOption(Description = "Description for Option2", Order = 1)]
        public string Option2 { get; set; } = "DefaultForOption2";
    
        [CliArgument(Description = "Description for Argument1", Order = 2)]
        public string Argument1 { get; set; } = "DefaultForArgument1";
    
        [CliArgument(Description = "Description for Argument2", Order = 1)]
        public string Argument2 { get; set; } = "DefaultForArgument2";
    
        [CliCommand(Description = "Description for sub-command1", Order = 2)]
        public class Sub1CliCommand
        {
    
        }
    
        [CliCommand(Description = "Description for sub-command2", Order = 1)]
        public class Sub2CliCommand
        {
    
        }
    }
  • Improved: Nested classes with container class not having [CliCommand] attribute, can now be used.

  • Fixed: If there is no HelpName for option and if option is not a flag, show the <argument> next to it, for example:

    Options:
      --settingsfile <settingsfile>  Path to settings file [required]

DotMake.CommandLine v2.6.4

19 Jul 00:59

Choose a tag to compare

  • Improved: Even more robust command binding. Added Create, BindCalled, BindAll, IsCalled, Contains methods to CliResult.
    These methods are also available in CliContext.Result which can be accessed in Run command handler.

    var result = Cli.Parse<RootCliCommand>(args);
    
    //Bind now returns null if the command line input does not contain
    //the indicated definition class (as self or as a parent)
    var subCommand = result.Bind<SubCliCommand>();
    //unless you set new returnEmpty parameter to true
    var subCommand2 = result.Bind<SubCliCommand>(true);
    
    //You can get an object for called command
    //without specifying the definition class
    var command = result.BindCalled();
    if (command is SubCliCommand subCommand3)
    {
    
    }
    //Or get an array of objects for all contained commands
    //(self and parents) without specifying the definition class
    var commands = result.BindAll();
    if (commands[0] is SubCliCommand subCommand4)
    {
    
    }
    
    //You can check if the command line input is
    //for the indicated definition class
    if (result.IsCalled<SubCliCommand>())
    {
    
    }
    //You can check if the command line input contains
    //the indicated definition class (as self or as a parent)
    if (result.Contains<SubCliCommand>())
    {
    
    }
    
    //You can create a new instance of the command definition class
    //but without any binding. This is useful for example when you need to
    //instantiate a definition class when using dependency injection.
    var subCommand5 = result.Create<SubCliCommand>();
  • Improved: Command accessor properties can now be safely used for child commands and not only parent commands.
    Circular dependency errors will be prevented, for example when parent and child has command accessors that point to each other.

    [CliCommand(Description = "A root cli command")]
    public class RootCliCommand
    {
        //This will be non-null only when the called command was this sub-command
        //For example you can check sub-command accessors for null to determine
        //which one was called
        public SubCliCommand SubCliCommandAccessor { get; set; }
    
        [CliCommand(Description = "A sub-command")]
        public class SubCliCommand
        {
            //This will be always non-null because if sub-command was called,
            //it's parent-command should also have been called
            public RootCliCommand RootCliCommandAccessor { get; set; }
        }
    }

DotMake.CommandLine v2.6.2

17 Jul 04:25

Choose a tag to compare

  • Changed: Renamed Cli.GetConfiguration() to Cli.GetParser() and changed return type from CommandLineConfiguration
    to new class CliParser.
    This method returns a CLI parser configured for the indicated command and you can call Parse or Run methods on it.
    So you can reuse the same CliParser for parsing and running.

    var parser = Cli.GetParser<RootCliCommand>();
    
    var result = parser.Parse(args);
    
    parser.Run(args);

    Changed return type of Cli.Parse methods from ParseResult to new class CliResult which
    describes the results of parsing a command line input based on a specific parser configuration
    and provides methods for binding the result to definition classes.

    var result = Cli.Parse<RootCliCommand>(args);
    
    var rootCliCommand = result.Bind<RootCliCommand>();
    
    if (result.ParseResult.Errors.Count > 0)
    {
    }
  • Improved: More robust command binding. Introduced CliBindingContext for internally encapsulating binders per command build and configuration.
    For example, in previous versions, the below code worked incorrectly, i.e. second call to Cli.Parse with same definition type,
    overwrote the binder so the later Bind call did not work correctly.

    var result = Cli.Parse<RootCliCommand>(args);
    var result2 = Cli.Parse<RootCliCommand>(args);
    
    var rootCommand = result.Bind<RootCliCommand>();