예제 #1
0
        internal static RootCommand CreateCommandLineOptions()
        {
            var rootCommand = new RootCommand
            {
                new Argument <string?>("workspace")
                {
                    Arity       = ArgumentArity.ZeroOrOne,
                    Description = Resources.A_path_to_a_solution_file_a_project_file_or_a_folder_containing_a_solution_or_project_file_If_a_path_is_not_specified_then_the_current_directory_is_used
                }.LegalFilePathsOnly(),
                new Option(new[] { "--folder", "-f" }, Resources.Whether_to_treat_the_workspace_argument_as_a_simple_folder_of_files),
                new Option(new[] { "--fix-whitespace", "-w" }, Resources.Run_whitespace_formatting_Run_by_default_when_not_applying_fixes),
                new Option(new[] { "--fix-style", "-s" }, Resources.Run_code_style_analyzers_and_apply_fixes)
                {
                    Argument = new Argument <string?>("severity")
                    {
                        Arity = ArgumentArity.ZeroOrOne
                    }.FromAmong(SeverityLevels)
                },
                new Option(new[] { "--fix-analyzers", "-a" }, Resources.Run_3rd_party_analyzers_and_apply_fixes)
                {
                    Argument = new Argument <string?>("severity")
                    {
                        Arity = ArgumentArity.ZeroOrOne
                    }.FromAmong(SeverityLevels)
                },
                new Option(new[] { "--include" }, Resources.A_list_of_relative_file_or_folder_paths_to_include_in_formatting_All_files_are_formatted_if_empty)
                {
                    Argument = new Argument <string[]>(() => Array.Empty <string>())
                },
                new Option(new[] { "--exclude" }, Resources.A_list_of_relative_file_or_folder_paths_to_exclude_from_formatting)
                {
                    Argument = new Argument <string[]>(() => Array.Empty <string>())
                },
                new Option(new[] { "--check" }, Resources.Formats_files_without_saving_changes_to_disk_Terminates_with_a_non_zero_exit_code_if_any_files_were_formatted),
                new Option(new[] { "--report" }, Resources.Accepts_a_file_path_which_if_provided_will_produce_a_format_report_json_file_in_the_given_directory)
                {
                    Argument = new Argument <string?>(() => null)
                    {
                        Name = "report-path"
                    }.LegalFilePathsOnly()
                },
                new Option(new[] { "--verbosity", "-v" }, Resources.Set_the_verbosity_level_Allowed_values_are_quiet_minimal_normal_detailed_and_diagnostic)
                {
                    Argument = new Argument <string?>()
                    {
                        Arity = ArgumentArity.ExactlyOne
                    }.FromAmong(VerbosityLevels)
                },
                new Option(new[] { "--include-generated" }, Resources.Include_generated_code_files_in_formatting_operations)
                {
                    IsHidden = true
                },
            };

            rootCommand.Description = "dotnet-format";
            rootCommand.AddValidator(EnsureFolderNotSpecifiedWhenFixingStyle);
            rootCommand.AddValidator(EnsureFolderNotSpecifiedWhenFixingAnalyzers);

            return(rootCommand);
        }
예제 #2
0
        /// <summary>
        /// Build the RootCommand for parsing
        /// </summary>
        /// <returns>RootCommand</returns>
        public static RootCommand BuildRootCommand()
        {
            RootCommand root = new RootCommand
            {
                Name        = "WebValidate",
                Description = "Validate API responses",
                TreatUnmatchedTokensAsErrors = true
            };

            root.AddOption(new Option <string>(new string[] { "-s", "--server" }, ParseString, true, "Server to test"));
            root.AddOption(new Option <List <string> >(new string[] { "-f", "--files" }, ParseStringList, true, "List of files to test"));
            root.AddOption(new Option <int>(new string[] { "-l", "--sleep" }, ParseInt, true, "Sleep (ms) between each request"));
            root.AddOption(new Option <string>(new string[] { "-u", "--base-url" }, ParseString, true, "Base url for files"));
            root.AddOption(new Option <bool>(new string[] { "-v", "--verbose" }, ParseBool, true, "Display verbose results"));
            root.AddOption(new Option <bool>(new string[] { "-r", "--run-loop" }, ParseBool, true, "Run test in an infinite loop"));
            root.AddOption(new Option <bool>(new string[] { "--random" }, ParseBool, true, "Run requests randomly (requires --run-loop)"));
            root.AddOption(new Option <int>(new string[] { "--duration" }, ParseInt, true, "Test duration (seconds)  (requires --run-loop)"));
            root.AddOption(new Option <int>(new string[] { "-t", "--timeout" }, ParseInt, true, "Request timeout (seconds)"));
            root.AddOption(new Option <int>(new string[] { "--max-concurrent" }, ParseInt, true, "Max concurrent requests"));
            root.AddOption(new Option <int>(new string[] { "--max-errors" }, ParseInt, true, "Max validation errors"));
            root.AddOption(new Option <string>(new string[] { "--telemetry-name" }, ParseString, true, "App Insights application name"));
            root.AddOption(new Option <string>(new string[] { "--telemetry-key" }, ParseString, true, "App Insights key"));
            root.AddOption(new Option <bool>(new string[] { "-d", "--dry-run" }, "Validates configuration"));

            // these require access to --run-loop so are added at the root level
            root.AddValidator(ValidateRunLoopDependencies);
            root.AddValidator(ValidateTelemetry);

            return(root);
        }
예제 #3
0
        internal static RootCommand CreateCommandLineOptions()
        {
            var rootCommand = new RootCommand
            {
                new Argument<string>("project")
                {
                    Arity = ArgumentArity.ZeroOrOne,
                    Description = Resources.The_solution_or_project_file_to_operate_on_If_a_file_is_not_specified_the_command_will_search_the_current_directory_for_one
                },
                new Option(new[] { "--folder", "-f" }, Resources.Whether_to_treat_the_project_path_as_a_folder_of_files)
                {
                    Argument = new Argument<string?>(() => null) { Arity = ArgumentArity.ZeroOrOne },
                },
                new Option(new[] { "--workspace", "-w" }, Resources.The_solution_or_project_file_to_operate_on_If_a_file_is_not_specified_the_command_will_search_the_current_directory_for_one)
                {
                    Argument = new Argument<string?>(() => null),
                    IsHidden = true
                },
                new Option(new[] { "--include", "--files" }, Resources.A_list_of_relative_file_or_folder_paths_to_include_in_formatting_All_files_are_formatted_if_empty)
                {
                    Argument = new Argument<string[]>(() => Array.Empty<string>())
                },
                new Option(new[] { "--exclude" }, Resources.A_list_of_relative_file_or_folder_paths_to_exclude_from_formatting)
                {
                    Argument = new Argument<string[]>(() => Array.Empty<string>())
                },
                new Option(new[] { "--check", "--dry-run" }, Resources.Formats_files_without_saving_changes_to_disk_Terminates_with_a_non_zero_exit_code_if_any_files_were_formatted)
                {
                    Argument = new Argument<bool>()
                },
                new Option(new[] { "--report" }, Resources.Accepts_a_file_path_which_if_provided_will_produce_a_format_report_json_file_in_the_given_directory)
                {
                    Argument = new Argument<string?>(() => null)
                },
                new Option(new[] { "--verbosity", "-v" }, Resources.Set_the_verbosity_level_Allowed_values_are_quiet_minimal_normal_detailed_and_diagnostic)
                {
                    Argument = new Argument<string?>() { Arity = ArgumentArity.ExactlyOne }
                },
                new Option(new[] { "--include-generated" }, Resources.Include_generated_code_files_in_formatting_operations)
                {
                    Argument = new Argument<bool>(),
                    IsHidden = true
                },
            };

            rootCommand.Description = "dotnet-format";
            rootCommand.AddValidator(ValidateProjectArgumentAndWorkspace);
            rootCommand.AddValidator(ValidateProjectArgumentAndFolder);
            rootCommand.AddValidator(ValidateWorkspaceAndFolder);

            return rootCommand;
        }
예제 #4
0
        /// <summary>
        /// Build the RootCommand for parsing
        /// </summary>
        /// <returns>RootCommand</returns>
        public static RootCommand BuildRootCommand()
        {
            RootCommand root = new RootCommand
            {
                Name        = "loderunner",
                Description = "Validate API responses",
                TreatUnmatchedTokensAsErrors = true,
            };

            root.AddOption(new Option <List <string> >(new string[] { "-s", "--server" }, Parsers.ParseStringList, true, "Server(s) to test"));
            root.AddOption(new Option <List <string> >(new string[] { "-f", "--files" }, Parsers.ParseStringList, true, "List of files to test"));
            root.AddOption(new Option <string>(new string[] { "--zone" }, Parsers.ParseString, true, "Zone for logging"));
            root.AddOption(new Option <string>(new string[] { "--region" }, Parsers.ParseString, true, "Region for logging"));
            root.AddOption(new Option <bool>(new string[] { "-p", "--prometheus" }, Parsers.ParseBool, true, "Send metrics to Prometheus"));
            root.AddOption(new Option <string>(new string[] { "--tag" }, Parsers.ParseString, true, "Tag for logging"));
            root.AddOption(new Option <int>(new string[] { "-l", "--sleep" }, Parsers.ParseIntGTZero, true, "Sleep (ms) between each request"));
            root.AddOption(new Option <bool>(new string[] { "-j", "--strict-json" }, Parsers.ParseBool, true, "Use strict json when parsing"));
            root.AddOption(new Option <string>(new string[] { "-u", "--base-url" }, Parsers.ParseString, true, "Base url for files"));
            root.AddOption(new Option <bool>(new string[] { "-v", "--verbose" }, Parsers.ParseBool, true, "Display verbose results"));
            root.AddOption(new Option <bool>(new string[] { "-r", "--run-loop" }, Parsers.ParseBool, true, "Run test in an infinite loop"));
            root.AddOption(new Option <bool>(new string[] { "--verbose-errors" }, Parsers.ParseBool, true, "Log verbose error messages"));
            root.AddOption(new Option <bool>(new string[] { "--random" }, Parsers.ParseBool, true, "Run requests randomly (requires --run-loop)"));
            root.AddOption(new Option <int>(new string[] { "--duration" }, Parsers.ParseIntGTZero, true, "Test duration (seconds)  (requires --run-loop)"));
            root.AddOption(new Option <int>(new string[] { "--summary-minutes" }, Parsers.ParseIntGTZero, true, "Display summary results (minutes)  (requires --run-loop)"));
            root.AddOption(new Option <int>(new string[] { "-t", "--timeout" }, Parsers.ParseIntGTZero, true, "Request timeout (seconds)"));
            root.AddOption(new Option <int>(new string[] { "--max-concurrent" }, Parsers.ParseIntGTZero, true, "Max concurrent requests"));
            root.AddOption(new Option <int>(new string[] { "--max-errors" }, Parsers.ParseIntGTZero, true, "Max validation errors"));
            root.AddOption(new Option <int>(new string[] { "--delay-start" }, Parsers.ParseIntGTZero, true, "Delay test start (seconds)"));
            root.AddOption(new Option <bool>(new string[] { "-d", "--dry-run" }, "Validates configuration"));

            // these require access to --run-loop so are added at the root level
            root.AddValidator(ValidateRunLoopDependencies);

            return(root);
        }
예제 #5
0
        public static RootCommand GetRootCommand()
        {
            var rootCommand = new RootCommand();

            rootCommand.Name        = "nrustlightning-cli";
            rootCommand.Description = "CLI interface for requesting to NRustLightning server";
            foreach (var op in GetOptions())
            {
                rootCommand.Add(op);
            }
            foreach (var sub in GetSubCommands())
            {
                rootCommand.AddCommand(sub);
            }
            rootCommand.AddValidator(result =>
            {
                var hasNetwork = result.Children.Contains("network");
                if (result.Children.Contains("mainnet") && hasNetwork)
                {
                    return("You cannot specify both '--network' and '--mainnet'");
                }
                if (result.Children.Contains("testnet") && hasNetwork)
                {
                    return("You cannot specify both '--network' and '--testnet'");
                }
                if (result.Children.Contains("regtest") && hasNetwork)
                {
                    return("You cannot specify both '--network' and '--regtest'");
                }

                return(null);
            });
            return(rootCommand);
        }
        [Fact] // https://github.com/dotnet/command-line-api/issues/1573
        public void Multiple_validators_on_the_same_command_do_not_report_duplicate_errors()
        {
            var command = new RootCommand();

            command.AddValidator(result => result.ErrorMessage = "Wrong");
            command.AddValidator(_ => { });

            var parseResult = command.Parse("");

            parseResult.Errors
            .Should()
            .ContainSingle()
            .Which
            .Message
            .Should()
            .Be("Wrong");
        }
예제 #7
0
        internal static RootCommand CreateCommandLineOptions()
        {
            // Sync changes to option and argument names with the FormatCommant.Handler above.
            var rootCommand = new RootCommand
            {
                new Argument <string?>("workspace", () => null, Resources.A_path_to_a_solution_file_a_project_file_or_a_folder_containing_a_solution_or_project_file_If_a_path_is_not_specified_then_the_current_directory_is_used).LegalFilePathsOnly(),
                new Option <bool>(new[] { "--no-restore" }, Resources.Doesnt_execute_an_implicit_restore_before_formatting),
                new Option <bool>(new[] { "--folder", "-f" }, Resources.Whether_to_treat_the_workspace_argument_as_a_simple_folder_of_files),
                new Option <bool>(new[] { "--fix-whitespace", "-w" }, Resources.Run_whitespace_formatting_Run_by_default_when_not_applying_fixes),
                new Option(new[] { "--fix-style", "-s" }, Resources.Run_code_style_analyzers_and_apply_fixes, argumentType: typeof(string), arity: ArgumentArity.ZeroOrOne)
                {
                    ArgumentHelpName = "severity"
                }.FromAmong(SeverityLevels),
                new Option(new[] { "--fix-analyzers", "-a" }, Resources.Run_3rd_party_analyzers_and_apply_fixes, argumentType: typeof(string), arity: ArgumentArity.ZeroOrOne)
                {
                    ArgumentHelpName = "severity"
                }.FromAmong(SeverityLevels),
                new Option <string[]>(new[] { "--diagnostics" }, () => Array.Empty <string>(), Resources.A_space_separated_list_of_diagnostic_ids_to_use_as_a_filter_when_fixing_code_style_or_3rd_party_issues),
                new Option <string[]>(new[] { "--include" }, () => Array.Empty <string>(), Resources.A_list_of_relative_file_or_folder_paths_to_include_in_formatting_All_files_are_formatted_if_empty),
                new Option <string[]>(new[] { "--exclude" }, () => Array.Empty <string>(), Resources.A_list_of_relative_file_or_folder_paths_to_exclude_from_formatting),
                new Option <bool>(new[] { "--check" }, Resources.Formats_files_without_saving_changes_to_disk_Terminates_with_a_non_zero_exit_code_if_any_files_were_formatted),
                new Option(new[] { "--report" }, Resources.Accepts_a_file_path_which_if_provided_will_produce_a_format_report_json_file_in_the_given_directory, argumentType: typeof(string), arity: ArgumentArity.ZeroOrOne)
                {
                    ArgumentHelpName = "report-path"
                }.LegalFilePathsOnly(),
                new Option <string>(new[] { "--verbosity", "-v" }, Resources.Set_the_verbosity_level_Allowed_values_are_quiet_minimal_normal_detailed_and_diagnostic).FromAmong(VerbosityLevels),
                new Option <bool>(new[] { "--include-generated" }, Resources.Include_generated_code_files_in_formatting_operations)
                {
                    IsHidden = true
                },
                new Option(new[] { "--binarylog" }, Resources.Log_all_project_or_solution_load_information_to_a_binary_log_file, argumentType: typeof(string), arity: ArgumentArity.ZeroOrOne)
                {
                    ArgumentHelpName = "binary-log-path"
                }.LegalFilePathsOnly(),
            };

            rootCommand.Description = "dotnet-format";
            rootCommand.AddValidator(EnsureFolderNotSpecifiedWhenFixingStyle);
            rootCommand.AddValidator(EnsureFolderNotSpecifiedWhenFixingAnalyzers);
            rootCommand.AddValidator(EnsureFolderNotSpecifiedWithNoRestore);
            rootCommand.AddValidator(EnsureFolderNotSpecifiedWhenLoggingBinlog);

            return(rootCommand);
        }
예제 #8
0
        public static RootCommand InitializeCommands(IServiceScope scope)
        {
            var argAccountname = new Argument("accountname")
            {
                Arity       = ArgumentArity.ExactlyOne,
                Description = "Accountname. Must be a text."
            };

            var argUsername = new Argument("username")
            {
                Arity       = ArgumentArity.ExactlyOne,
                Description = "Username. Must be a text."
            };

            var argPassword = new Argument("password")
            {
                Arity       = ArgumentArity.ExactlyOne,
                Description = "User password. Must meet minimum security requirements."
            };

            CommandWithExamples createAccount = new CommandWithExamples(
                "-createaccount",
                "Creates a new account in database with provided accountname, username and password.",
                new[]
                { "%1 -createaccount Some!Demo_Accountname Some!Username Some!Password" }
                )
            {
                argAccountname, argUsername, argPassword
            };

            var account = scope.ServiceProvider.GetService <IAccountRepository>();

            createAccount.Handler = CommandHandler.Create(
                (string accountname, string username, string password) => InitializeCreateAccount(account, accountname, username, password));

            var optionStartup = new Option("-startup", "Start a SPV Channel rest server");

            RootCommand root = new RootCommand("Start a SPV Channel rest server when invoked without parameters. Manage users when invoked with additional parameters.")
            {
                createAccount,
                optionStartup
            };

            root.AddValidator(symbol =>
            {
                if (symbol.Children.Count == 0)
                {
                    return("Starting application without parameters is not allowed.");
                }
                return(String.Empty);
            });

            root.Handler = CommandHandler.Create <string>((startup) => { });

            return(root);
        }
예제 #9
0
        public static int Main(string[] args)
        {
            var rootCommand = new RootCommand("A tool for obfuscating file names.");

            rootCommand.AddValidator(x => "Select a command to continue. Run --help for more information.");

            var obfuscationCommand = CreateObfuscationCommand();

            rootCommand.AddCommand(obfuscationCommand);

            var deobfuscate = CreateDeobfuscationCommand();

            rootCommand.AddCommand(deobfuscate);

            return(rootCommand.Invoke(args));
        }
        public void All_custom_validators_are_called(string commandLine)
        {
            var commandValidatorWasCalled  = false;
            var optionValidatorWasCalled   = false;
            var argumentValidatorWasCalled = false;

            var option = new Option <string>("-o");

            option.AddValidator(_ =>
            {
                optionValidatorWasCalled = true;
                return(null);
            });

            var argument = new Argument <string>("the-arg");

            argument.AddValidator(_ =>
            {
                argumentValidatorWasCalled = true;
                return(null);
            });

            var rootCommand = new RootCommand
            {
                option,
                argument
            };

            rootCommand.AddValidator(_ =>
            {
                commandValidatorWasCalled = true;
                return(null);
            });

            rootCommand.Invoke(commandLine);

            commandValidatorWasCalled.Should().BeTrue();
            optionValidatorWasCalled.Should().BeTrue();
            argumentValidatorWasCalled.Should().BeTrue();
        }
예제 #11
0
파일: Program.cs 프로젝트: Axemasta/boots
        static async Task Main(string [] args)
        {
            if (args.Length == 1 && IsUrl(args[0]))
            {
                await Run(args [0]);

                return;
            }

            const string options     = "Options include: Xamarin.Android, Xamarin.iOS, Xamarin.Mac, and Mono.";
            var          rootCommand = new RootCommand
            {
                new Option(
                    "--url",
                    "A URL to a pkg or vsix file to install")
                {
                    Argument = new Argument <string>()
                },
                new Option(
                    "--stable",
                    $"Install the latest *stable* version of a product from VS manifests. {options}")
                {
                    Argument = new Argument <string>()
                },
                new Option(
                    "--preview",
                    $"Install the latest *preview* version of a product from VS manifests. {options}")
                {
                    Argument = new Argument <string>()
                },
            };

            rootCommand.Name = "boots";
            rootCommand.AddValidator(Validator);
            rootCommand.Description = $"boots {Version} File issues at: https://github.com/jonathanpeppers/boots/issues";
            rootCommand.Handler     = CommandHandler.Create <string, string, string> (Run);
            await rootCommand.InvokeAsync(args);
        }
예제 #12
0
        /// <summary>
        /// Build the RootCommand for parsing
        /// </summary>
        /// <returns>RootCommand</returns>
        public static RootCommand BuildRootCommand()
        {
            RootCommand root = new RootCommand
            {
                Name        = "DataService",
                Description = "NGSA Data Service",
                TreatUnmatchedTokensAsErrors = true,
            };

            // add the options
            root.AddOption(new Option <int>(new string[] { "--cache-duration" }, () => 300, "Cache for duration (seconds)"));
            root.AddOption(new Option <bool>(new string[] { "--in-memory" }, "Use in-memory database"));
            root.AddOption(new Option <bool>(new string[] { "--no-cache" }, "Don't cache results"));
            root.AddOption(new Option <int>(new string[] { "--perf-cache" }, "Cache only when load exceeds value"));
            root.AddOption(new Option <string>(new string[] { "--secrets-volume" }, () => "secrets", "Secrets Volume Path"));
            root.AddOption(new Option <LogLevel>(new string[] { "-l", "--log-level" }, () => LogLevel.Warning, "Log Level"));
            root.AddOption(new Option <bool>(new string[] { "-d", "--dry-run" }, "Validates configuration"));

            // validate dependencies
            root.AddValidator(ValidateDependencies);

            return(root);
        }
예제 #13
0
        public static RootCommand GetRootCommand()
        {
            var rootCommand = new RootCommand();

            rootCommand.Name        = "nrustlightning-cli";
            rootCommand.Description = "CLI interface for requesting to NRustLightning server";
            foreach (var op in GetOptions())
            {
                rootCommand.Add(op);
            }
            foreach (var sub in GetSubCommands())
            {
                rootCommand.AddCommand(sub);
            }
            rootCommand.AddValidator(result =>
            {
                var hasNetwork = result.Children.Contains("network");
                var hasMainnet = result.Children.Contains("mainnet");
                var hasTestNet = result.Children.Contains("testnet");
                var hasRegtest = result.Children.Contains("regtest");
                int count      = 0;
                foreach (var flag in new bool[] { hasNetwork, hasMainnet, hasTestNet, hasRegtest })
                {
                    if (flag)
                    {
                        count++;
                    }
                }

                if (count > 1)
                {
                    return("You cannot specify more than one network.");
                }
                return(null);
            });
            return(rootCommand);
        }
예제 #14
0
        /// <summary>
        /// Entry point for `perlang`, with the possibility to override the console streams (stdin, stdout, stderr).
        /// </summary>
        /// <param name="args">The command line arguments.</param>
        /// <param name="console">A custom `IConsole` implementation to use. May be null, in which case the standard
        /// streams of the calling process will be used.</param>
        /// <returns>Zero if the program executed successfully; non-zero otherwise.</returns>
        public static int MainWithCustomConsole(string[] args, IConsole console)
        {
            var versionOption         = new Option(new[] { "--version", "-v" }, "Show version information");
            var detailedVersionOption = new Option("-V", "Show detailed version information");
            var evalOption            = new Option <string>("-e", "Executes a single-line script")
            {
                AllowMultipleArgumentsPerToken = false, ArgumentHelpName = "script"
            };
            var printOption = new Option <string>("-p", "Parse a single-line script and output a human-readable version of the AST")
            {
                ArgumentHelpName = "script"
            };
            var noWarnAsErrorOption = new Option <string>("-Wno-error", "Treats specified warning as a warning instead of an error.")
            {
                ArgumentHelpName = "error"
            };

            var disabledWarningsAsErrorsList = new List <WarningType>();

            noWarnAsErrorOption.AddValidator(result =>
            {
                string warningName = result.GetValueOrDefault <string>();

                if (!WarningType.KnownWarning(warningName))
                {
                    return($"Unknown warning: {warningName}");
                }

                disabledWarningsAsErrorsList.Add(WarningType.Get(warningName));

                return(null);
            });

            // Note: options must be present in this list to be valid for the RootCommand.
            var options = new[]
            {
                versionOption,
                detailedVersionOption,
                evalOption,
                printOption,
                noWarnAsErrorOption
            };

            var scriptNameArgument = new Argument <string>
            {
                Name  = "script-name",
                Arity = ArgumentArity.ZeroOrOne,
            };

            scriptNameArgument.AddValidator(result =>
            {
                var tokens = result.Parent !.Tokens;

                if (tokens.Any(t => t.Type == System.CommandLine.Parsing.TokenType.Option && t.Value == evalOption.Name))
                {
                    return("<script-name> positional argument cannot be used together with the -e option");
                }

                return(null);
            });

            var rootCommand = new RootCommand
            {
                Description = "The Perlang Interpreter",

                Handler = CommandHandler.Create((ParseResult parseResult, IConsole console) =>
                {
                    if (parseResult.HasOption(versionOption))
                    {
                        console.Out.WriteLine(CommonConstants.InformationalVersion);
                        return(Task.FromResult(0));
                    }

                    if (parseResult.HasOption(detailedVersionOption))
                    {
                        console.Out.WriteLine($"Perlang {CommonConstants.InformationalVersion} (built from git commit {CommonConstants.GitCommit}) on .NET {Environment.Version}");
                        console.Out.WriteLine();
                        console.Out.WriteLine($"  Number of detected (v)CPUs: {Environment.ProcessorCount}");
                        console.Out.WriteLine($"  Running in 64-bit mode: {Environment.Is64BitProcess}");
                        console.Out.WriteLine($"  Operating system info: {Environment.OSVersion.VersionString}");
                        console.Out.WriteLine();

                        return(Task.FromResult(0));
                    }

                    if (parseResult.HasOption(evalOption))
                    {
                        // TODO: Workaround until we have a command-line-api package with https://github.com/dotnet/command-line-api/pull/1271 included.
                        OptionResult optionResult = parseResult.FindResultFor(evalOption);

                        string source = optionResult.Children
                                        .Where(c => c.Symbol.Name == evalOption.ArgumentHelpName)
                                        .Cast <ArgumentResult>()
                                        .First()
                                        .GetValueOrDefault <string>();

                        var program = new Program(
                            replMode: true,
                            standardOutputHandler: console.Out.WriteLine,
                            disabledWarningsAsErrors: disabledWarningsAsErrorsList
                            );

                        int result = program.Run(source, program.CompilerWarning);

                        return(Task.FromResult(result));
                    }
                    else if (parseResult.HasOption(printOption))
                    {
                        // TODO: Workaround until we have a command-line-api package with https://github.com/dotnet/command-line-api/pull/1271 included.
                        OptionResult optionResult = parseResult.FindResultFor(printOption);

                        string source = optionResult.Children
                                        .Where(c => c.Symbol.Name == evalOption.ArgumentHelpName)
                                        .Cast <ArgumentResult>()
                                        .First()
                                        .GetValueOrDefault <string>();

                        new Program(
                            replMode: true,
                            standardOutputHandler: console.Out.WriteLine,
                            disabledWarningsAsErrors: disabledWarningsAsErrorsList
                            ).ParseAndPrint(source);

                        return(Task.FromResult(0));
                    }
                    else if (parseResult.Tokens.Count == 0)
                    {
                        new Program(
                            replMode: true,
                            standardOutputHandler: console.Out.WriteLine,
                            disabledWarningsAsErrors: disabledWarningsAsErrorsList
                            ).RunPrompt();

                        return(Task.FromResult(0));
                    }
                    else
                    {
                        string scriptName = parseResult.ValueForArgument(scriptNameArgument);
                        int result;

                        if (parseResult.Tokens.Count == 1)
                        {
                            var program = new Program(
                                replMode: false,
                                standardOutputHandler: console.Out.WriteLine,
                                disabledWarningsAsErrors: disabledWarningsAsErrorsList
                                );

                            result = program.RunFile(scriptName);
                        }
                        else
                        {
                            // The first token available in RootCommandResult.Tokens at this point is the script name.
                            // All remaining arguments are passed to the program, which can use methods on the ARGV
                            // object to retrieve them.
                            var remainingArguments = parseResult.RootCommandResult.Tokens.Skip(1)
                                                     .Take(parseResult.Tokens.Count - 1)
                                                     .Select(r => r.Value);

                            var program = new Program(
                                replMode: false,
                                arguments: remainingArguments,
                                standardOutputHandler: console.Out.WriteLine,
                                disabledWarningsAsErrors: disabledWarningsAsErrorsList
                                );

                            result = program.RunFile(scriptName);
                        }

                        return(Task.FromResult(result));
                    }
                })
            };

            rootCommand.AddArgument(scriptNameArgument);

            rootCommand.AddValidator(result =>
            {
                if (result.HasOption(evalOption) && result.HasOption(printOption))
                {
                    return("Error: the -e and -p options are mutually exclusive");
                }

                if (result.HasOption(evalOption) && result.HasArgument(scriptNameArgument))
                {
                    return("Error: the -e option cannot be combined with the <script-name> argument");
                }

                return(null);
            });

            var scriptArguments = new Argument <string>
            {
                Name  = "args",
                Arity = ArgumentArity.ZeroOrMore
            };

            rootCommand.AddArgument(scriptArguments);

            foreach (Option option in options)
            {
                rootCommand.AddOption(option);
            }

            return(new CommandLineBuilder(rootCommand)
                   .UseDefaults()
                   .Build()
                   .Invoke(args, console));
        }
예제 #15
0
        /// <summary>
        /// Build the RootCommand for parsing
        /// </summary>
        /// <returns>RootCommand</returns>
        public static RootCommand BuildRootCommand()
        {
            RootCommand root = new RootCommand
            {
                Name        = "complex-app",
                Description = "Validate API responses",
                TreatUnmatchedTokensAsErrors = true
            };

            // create options with validators
            Option serverOption = new Option(new string[] { "-s", "--server" }, "Server to test")
            {
                Argument = new Argument <string>(), Required = true
            };

            serverOption.AddValidator(v =>
            {
                const string errorMessage = "--server must be 3 - 20 characters [a-z][0-9]";

                if (v.Tokens == null ||
                    v.Tokens.Count != 1 ||
                    v.Tokens[0].Value == null ||
                    v.Tokens[0].Value.Length < 3 ||
                    v.Tokens[0].Value.Length > 20)
                {
                    return(errorMessage);
                }

                return(string.Empty);
            });

            Option filesOption = new Option(new string[] { "-f", "--files" }, "List of files to test")
            {
                Argument = new Argument <List <string> >(() => new List <string> {
                    "baseline.json"
                })
            };

            filesOption.AddValidator(v =>
            {
                string ret = string.Empty;

                if (v.Tokens.Count != 0)
                {
                    foreach (Token t in v.Tokens)
                    {
                        if (!CheckFileExists(t.Value))
                        {
                            if (string.IsNullOrEmpty(ret))
                            {
                                ret = "File not found: " + t.Value;
                            }
                            else
                            {
                                ret  = ret.Replace("File ", "Files ", StringComparison.Ordinal);
                                ret += ", " + t.Value;
                            }
                        }
                    }
                }

                return(ret);
            });

            Option timeoutOption = new Option(new string[] { "-t", "--timeout" }, "Request timeout (seconds)")
            {
                Argument = new Argument <int>(() => 30)
            };

            timeoutOption.AddValidator(ValidateIntGTEZero);

            Option sleepOption = new Option(new string[] { "-l", "--sleep" }, "Sleep (ms) between each request")
            {
                Argument = new Argument <int>()
            };

            sleepOption.AddValidator(ValidateIntGTEZero);

            Option durationOption = new Option(new string[] { "--duration" }, "Test duration (seconds)  (requires --run-loop)")
            {
                Argument = new Argument <int>(() => 0)
            };

            durationOption.AddValidator(ValidateIntGTEZero);

            Option maxConcurrentOption = new Option(new string[] { "--max-concurrent" }, "Max concurrent requests")
            {
                Argument = new Argument <int>(() => 100)
            };

            maxConcurrentOption.AddValidator(ValidateIntGTEZero);

            Option maxErrorsOption = new Option(new string[] { "--max-errors" }, "Max validation errors")
            {
                Argument = new Argument <int>(() => 10)
            };

            maxErrorsOption.AddValidator(ValidateIntGTEZero);

            Option telemetryOption = new Option(new string[] { "--telemetry" }, "App Insights name and key")
            {
                Argument = new Argument <List <string> >()
            };

            telemetryOption.AddValidator(v =>
            {
                if (v.Tokens.Count != 2)
                {
                    return("--telemetry requires appName and appKey parameters");
                }

                return(string.Empty);
            });

            root.AddOption(serverOption);
            root.AddOption(filesOption);
            root.AddOption(sleepOption);
            root.AddOption(new Option(new string[] { "-v", "--verbose" }, "Display verbose results")
            {
                Argument = new Argument <bool>()
            });
            root.AddOption(new Option(new string[] { "-r", "--run-loop" }, "Run test in an infinite loop")
            {
                Argument = new Argument <bool>(() => false)
            });
            root.AddOption(new Option(new string[] { "--random" }, "Run requests randomly (requires --run-loop)")
            {
                Argument = new Argument <bool>(() => false)
            });
            root.AddOption(durationOption);
            root.AddOption(timeoutOption);
            root.AddOption(maxConcurrentOption);
            root.AddOption(maxErrorsOption);
            root.AddOption(telemetryOption);
            root.AddOption(new Option(new string[] { "-d", "--dry-run" }, "Validates configuration")
            {
                Argument = new Argument <bool>()
            });

            // these require access to --run-loop so are added at the root level
            root.AddValidator(ValidateDuration);
            root.AddValidator(ValidateRandom);

            return(root);
        }