public void Should_Set_Descriptions_For_Branches()
        {
            // Given
            var configurator = new Configurator(null);

            configurator.AddBranch <AnimalSettings>("animal", animal =>
            {
                animal.SetDescription("An animal");
                animal.AddBranch <MammalSettings>("mammal", mammal =>
                {
                    mammal.SetDescription("A mammal");
                    mammal.AddCommand <DogCommand>("dog");
                    mammal.AddCommand <HorseCommand>("horse");
                });
            });

            // When
            var model = CommandModelBuilder.Build(configurator);

            // Then
            model.Commands[0].As(animal =>
            {
                animal.Description.ShouldBe("An animal");
                animal.Children[0].As(mammal => mammal.Description.ShouldBe("A mammal"));
            });
        }
        public void Should_Set_Parents_Correctly()
        {
            // Given
            var configurator = new Configurator(null);

            configurator.AddBranch <AnimalSettings>("animal", animal =>
            {
                animal.AddBranch <MammalSettings>("mammal", mammal =>
                {
                    mammal.AddCommand <DogCommand>("dog");
                    mammal.AddCommand <HorseCommand>("horse");
                });
            });

            // When
            var model = CommandModelBuilder.Build(configurator);

            // Then
            model.Commands.Count.ShouldBe(1);
            model.Commands[0].As(animal =>
            {
                animal.Parent.ShouldBeNull();
                animal.Children.Count.ShouldBe(1);
                animal.Children[0].As(mammal =>
                {
                    mammal.Parent.ShouldBe(animal);
                    mammal.Children.Count.ShouldBe(2);
                    mammal.Children[0].As(dog => dog.Parent.ShouldBe(mammal));
                    mammal.Children[1].As(horse => horse.Parent.ShouldBe(mammal));
                });
            });
        }
            public static string Write(Configurator configurator)
            {
                var model  = CommandModelBuilder.Build(configurator);
                var output = HelpWriter.Write(model);

                return(Render(output));
            }
        public void Should_Make_Shadowed_Options_Non_Required()
        {
            // Given
            var configurator = new Configurator(null);

            configurator.AddBranch <MammalSettings>("mammal", mammal =>
            {
                mammal.AddCommand <HorseCommand>("horse");
            });

            // When
            var model = CommandModelBuilder.Build(configurator);

            // Then
            model.Commands[0].As(mammal =>
            {
                mammal.Children[0].As(horse =>
                {
                    horse.GetOption(option => option.LongNames.Contains("name", StringComparer.Ordinal)).As(o2 =>
                    {
                        o2.ShouldNotBeNull();
                        o2.Required.ShouldBe(false);
                    });
                });
            });
        }
            public static string Write(Configurator configurator, Func <CommandModel, CommandInfo> command)
            {
                var model  = CommandModelBuilder.Build(configurator);
                var output = HelpWriter.WriteCommand(model, command(model));

                return(Render(output));
            }
        public void Should_Shadow_Options_Declared_In_Parent_Command_If_Settings_Are_Of_Same_Type()
        {
            // Given
            var configurator = new Configurator(null);

            configurator.AddBranch <MammalSettings>("mammal", mammal =>
            {
                mammal.AddCommand <HorseCommand>("horse");
            });

            // When
            var model = CommandModelBuilder.Build(configurator);

            // Then
            model.Commands[0].As(mammal =>
            {
                mammal.GetOption(option => option.LongNames.Contains("name", StringComparer.Ordinal)).As(o1 =>
                {
                    o1.ShouldNotBeNull();
                    o1.IsShadowed.ShouldBe(false);
                });

                mammal.Children[0].As(horse =>
                {
                    horse.GetOption(option => option.LongNames.Contains("name", StringComparer.Ordinal)).As(o2 =>
                    {
                        o2.ShouldNotBeNull();
                        o2.IsShadowed.ShouldBe(true);
                    });
                });
            });
        }
            public CommandTreeParserResult Parse(IEnumerable <string> args, Action <Configurator> func)
            {
                func(_configurator);

                var model = CommandModelBuilder.Build(_configurator);

                return(new CommandTreeParser(model).Parse(args));
            }
Beispiel #8
0
            public static (CommandTree tree, ILookup <string, string> remaining) Parse(IEnumerable <string> args, Action <Configurator> func)
            {
                var configurator = new Configurator(null);

                func(configurator);

                var model = CommandModelBuilder.Build(configurator);

                return(new CommandTreeParser(model).Parse(args));
            }
Beispiel #9
0
            public (CommandTree, IRemainingArguments remaining) Parse(IEnumerable <string> args, Action <Configurator> func)
            {
                var configurator = new Configurator(null, _defaultCommand);

                func(configurator);

                var model = CommandModelBuilder.Build(configurator);

                return(new CommandTreeParser(model).Parse(args));
            }
        public void Should_Not_Throw_If_No_Commands_Have_Been_Configured_But_A_Default_Command_Has()
        {
            // Given
            var configurator = new Configurator(null, typeof(DogCommand));

            // When
            var result = CommandModelBuilder.Build(configurator);

            // Then
            result.DefaultCommand.ShouldNotBeNull();
        }
        public void Should_Throw_If_No_Commands_Not_Default_Command_Have_Been_Configured()
        {
            // Given
            var configurator = new Configurator(null);

            // When
            var result = Record.Exception(() => CommandModelBuilder.Build(configurator));

            // Then
            result.ShouldBeOfType <ConfigurationException>().And(exception =>
                                                                 exception.Message.ShouldBe("No commands have been configured."));
        }
        public void Should_Set_Default_Value_For_Options()
        {
            // Given
            var configurator = new Configurator(null);

            configurator.AddCommand <CatCommand>("cat");

            // When
            var model = CommandModelBuilder.Build(configurator);

            // Then
            model.Commands[0]
            .GetOption(option => option.LongNames.Contains("agility", StringComparer.Ordinal))
            .DefaultValue.Value.ShouldBe(10);
        }
Beispiel #13
0
        public int Execute(IConfiguration configuration, IEnumerable <string> args)
        {
            if (configuration == null)
            {
                throw new ArgumentNullException(nameof(configuration));
            }
            if (configuration.Commands.Count == 0)
            {
                throw new CommandAppException("No commands have been configured.");
            }

            // Create the command model.
            var model = CommandModelBuilder.Build(configuration);

            // Parse and map the model against the arguments.
            var parser = new CommandTreeParser(model, new CommandOptionAttribute("-h|--help"));

            var(tree, remaining) = parser.Parse(args);

            // Currently the root?
            if (tree == null)
            {
                // Display help.
                HelpWriter.Write(model);
                return(0);
            }

            // Get the command to execute.
            var leaf = tree.GetLeafCommand();

            if (leaf.Command.IsProxy || leaf.ShowHelp)
            {
                // Proxy's can't be executed. Show help.
                HelpWriter.Write(model, leaf.Command);
                return(0);
            }

            // Register the arguments with the container.
            var arguments = new Arguments(remaining);

            _registrar?.RegisterInstance(typeof(IArguments), arguments);

            // Create the resolver.
            var resolver = new TypeResolverAdapter(_registrar?.Build());

            // Execute the command tree.
            return(Execute(leaf, tree, remaining, resolver));
        }
        public void Should_Set_TypeConverter_For_Options()
        {
            // Given
            var configurator = new Configurator(null);

            configurator.AddCommand <CatCommand>("cat");

            // When
            var model = CommandModelBuilder.Build(configurator);

            // Then
            model.Commands[0]
            .GetOption(option => option.LongNames.Contains("agility", StringComparer.Ordinal))
            .Converter.ConverterTypeName
            .ShouldStartWith("Spectre.Cli.Tests.Data.Converters.CatAgilityConverter");
        }
        public void Should_Throw_If_Branch_Has_No_Children()
        {
            // Given
            var configurator = new Configurator(null);

            configurator.AddBranch <AnimalSettings>("animal", _ =>
            {
            });

            // When
            var result = Record.Exception(() => CommandModelBuilder.Build(configurator));

            // Then
            result.ShouldBeOfType <ConfigurationException>().And(exception =>
                                                                 exception.Message.ShouldBe("The branch 'animal' does not define any commands."));
        }
Beispiel #16
0
            public static T Bind <T>(IEnumerable <string> args, Action <Configurator> action)
                where T : CommandSettings, new()
            {
                // Configure
                var configurator = new Configurator(null);

                action(configurator);

                // Parse command tree.
                var parser = new CommandTreeParser(CommandModelBuilder.Build(configurator));
                var result = parser.Parse(args);

                // Bind the settings to the tree.
                CommandSettings settings = new T();

                CommandBinder.Bind(result.Tree, ref settings, new TypeResolverAdapter(null));

                // Return the settings.
                return((T)settings);
            }
        public void Should_Generate_Correct_Model_For_Default_Command()
        {
            // Given
            var configurator = new Configurator(null, typeof(DogCommand));

            // When
            var model = CommandModelBuilder.Build(configurator);

            // Then
            model.DefaultCommand.ShouldNotBeNull();
            model.DefaultCommand.As(command =>
            {
                command.CommandType.ShouldBe <DogCommand>();
                command.SettingsType.ShouldBe <DogSettings>();
                command.Children.Count.ShouldBe(0);
                command.Description.ShouldBe("The dog command.");
                command.IsBranch.ShouldBeFalse();
                command.Name.ShouldBe("__default_command");
                command.Parent.ShouldBeNull();
            });
        }
Beispiel #18
0
        public static string Serialize(Action <Configurator> func)
        {
            var configurator = new Configurator(null);

            func(configurator);

            var model = CommandModelBuilder.Build(configurator);

            var settings = new XmlWriterSettings
            {
                Indent             = true,
                IndentChars        = "  ",
                NewLineChars       = "\n",
                OmitXmlDeclaration = false
            };

            using (var buffer = new StringWriter())
                using (var xmlWriter = XmlWriter.Create(buffer, settings))
                {
                    Serialize(model).WriteTo(xmlWriter);
                    xmlWriter.Flush();
                    return(buffer.GetStringBuilder().ToString().NormalizeLineEndings());
                }
        }
            public static string GetParseMessage(IEnumerable <string> args, Configurator configurator, bool shouldThrowOnSuccess = true)
            {
                try
                {
                    // Create the model from the configuration.
                    var model = CommandModelBuilder.Build(configurator);

                    // Parse the resulting tree from the model and the args.
                    var parser = new CommandTreeParser(model);
                    parser.Parse(args);

                    // If we get here, something is wrong.
                    if (shouldThrowOnSuccess)
                    {
                        throw new InvalidOperationException("Expected a parse exception.");
                    }

                    return(null);
                }
                catch (ParseException ex)
                {
                    return(Render(ex.Pretty));
                }
            }
    public async Task <int> Execute(IConfiguration configuration, IEnumerable <string> args)
    {
        if (configuration == null)
        {
            throw new ArgumentNullException(nameof(configuration));
        }

        _registrar.RegisterInstance(typeof(IConfiguration), configuration);
        _registrar.RegisterLazy(typeof(IAnsiConsole), () => configuration.Settings.Console.GetConsole());

        // Create the command model.
        var model = CommandModelBuilder.Build(configuration);

        _registrar.RegisterInstance(typeof(CommandModel), model);
        _registrar.RegisterDependencies(model);

        // No default command?
        if (model.DefaultCommand == null)
        {
            // Got at least one argument?
            var firstArgument = args.FirstOrDefault();
            if (firstArgument != null)
            {
                // Asking for version? Kind of a hack, but it's alright.
                // We should probably make this a bit better in the future.
                if (firstArgument.Equals("--version", StringComparison.OrdinalIgnoreCase) ||
                    firstArgument.Equals("-v", StringComparison.OrdinalIgnoreCase))
                {
                    var console = configuration.Settings.Console.GetConsole();
                    console.WriteLine(ResolveApplicationVersion(configuration));
                    return(0);
                }
            }
        }

        // Parse and map the model against the arguments.
        var parser       = new CommandTreeParser(model, configuration.Settings);
        var parsedResult = parser.Parse(args);

        _registrar.RegisterInstance(typeof(CommandTreeParserResult), parsedResult);

        // Currently the root?
        if (parsedResult.Tree == null)
        {
            // Display help.
            configuration.Settings.Console.SafeRender(HelpWriter.Write(model));
            return(0);
        }

        // Get the command to execute.
        var leaf = parsedResult.Tree.GetLeafCommand();

        if (leaf.Command.IsBranch || leaf.ShowHelp)
        {
            // Branches can't be executed. Show help.
            configuration.Settings.Console.SafeRender(HelpWriter.WriteCommand(model, leaf.Command));
            return(leaf.ShowHelp ? 0 : 1);
        }

        // Register the arguments with the container.
        _registrar.RegisterInstance(typeof(IRemainingArguments), parsedResult.Remaining);

        // Create the resolver and the context.
        using (var resolver = new TypeResolverAdapter(_registrar.Build()))
        {
            var context = new CommandContext(parsedResult.Remaining, leaf.Command.Name, leaf.Command.Data);

            // Execute the command tree.
            return(await Execute(leaf, parsedResult.Tree, context, resolver, configuration).ConfigureAwait(false));
        }
    }