public async Task Trims_environment_variable_value() { bool asserted = false; string variable = test_variable; const string value = "This is a test"; var rootCommand = new RootCommand(); rootCommand.SetHandler(() => { asserted = true; Environment.GetEnvironmentVariable(variable).Should().Be(value); }); var parser = new CommandLineBuilder(rootCommand) .UseEnvironmentVariableDirective() .Build(); await parser.InvokeAsync(new[] { $"[env:{variable}= {value} ]" }); asserted.Should().BeTrue(); }
static int Main(string[] args) { var existingOnlyOption = new Option <FileInfo>("--out-file") { Description = "Location to write the generated interface file", IsRequired = true }.ExistingOnly(); var command = new RootCommand { existingOnlyOption }; command.SetHandler(async(FileInfo f) => { var generated = InterfaceGenerator.Generate(); await File.WriteAllTextAsync(f.FullName, generated); }, existingOnlyOption); return(command.Invoke(args)); }
public void If_parameter_order_does_not_match_symbol_order_then_an_error_results() { var boolOption = new Option <bool>("-o"); var stringArg = new Argument <string>("value"); var command = new RootCommand { boolOption, stringArg }; var wasCalled = false; command.SetHandler((bool boolValue, string stringValue) => wasCalled = true, stringArg, boolOption); var exitCode = command.Invoke("-o hi"); wasCalled.Should().BeFalse(); exitCode.Should().Be(1); }
private static int Main(string[] args) { Option <bool> boolOption = new Option <bool>(new[] { "--bool", "-b" }, "Bool option"); Option <string> stringOption = new Option <string>(new[] { "--string", "-s" }, "String option"); RootCommand command = new RootCommand { boolOption, stringOption }; command.SetHandler(Run); return(new CommandLineBuilder(command).Build().Invoke(args)); void Run(InvocationContext context) { context.Console.WriteLine($"Bool option: {context.ParseResult.GetValueForOption(boolOption)}"); context.Console.WriteLine($"String option: {context.ParseResult.GetValueForOption(stringOption)}"); } }
public async Task Custom_argument_parser_is_only_called_once() { var callCount = 0; var handlerWasCalled = false; var option = new Option <int>("--value", result => { callCount++; return(int.Parse(result.Tokens.Single().Value)); }); var command = new RootCommand(); command.SetHandler((int value) => handlerWasCalled = true, option); command.AddOption(option); await command.InvokeAsync("--value 42"); callCount.Should().Be(1); handlerWasCalled.Should().BeTrue(); }
public static async Task Ignores_environment_directive_with_whitespace_variable_name() { bool asserted = false; string value = $"This is a test, random: {randomizer.Next()}"; var rootCommand = new RootCommand(); rootCommand.SetHandler(() => { asserted = true; var env = Environment.GetEnvironmentVariables(); env.Values.Cast <string>().Should().NotContain(value); }); var parser = new CommandLineBuilder(rootCommand) .UseEnvironmentVariableDirective() .Build(); await parser.InvokeAsync(new[] { $"[env: ={value}]" }); asserted.Should().BeTrue(); }
static async Task Original(string[] args) { // <original> var fileOption = new Option <FileInfo>( "--file", description: "The file to print out.", getDefaultValue: () => new FileInfo("scl.runtimeconfig.json")); var lightModeOption = new Option <bool> ( "--light-mode", description: "Determines whether the background color will be black or white"); var foregroundColorOption = new Option <ConsoleColor>( "--color", description: "Specifies the foreground color of console output", getDefaultValue: () => ConsoleColor.White); var rootCommand = new RootCommand("Read a file") { fileOption, lightModeOption, foregroundColorOption }; rootCommand.SetHandler( (FileInfo file, bool lightMode, ConsoleColor color) => { Console.BackgroundColor = lightMode ? ConsoleColor.White: ConsoleColor.Black; Console.ForegroundColor = color; Console.WriteLine($"--file = {file?.FullName}"); Console.WriteLine($"File contents:\n{file?.OpenText().ReadToEnd()}"); }, fileOption, lightModeOption, foregroundColorOption); await rootCommand.InvokeAsync(args); // </original> Console.WriteLine("Default help"); await rootCommand.InvokeAsync("-h"); }
/// <summary> /// Main entry for the program. /// https://dotnetdevaddict.co.za/2020/09/25/getting-started-with-system-commandline/ Tutorial for System.CommandLine /// https://github.com/dotnet/command-line-api System.CommandLine Git repository and its document. /// </summary> /// <param name="args">Command line arguments.</param> static int Main(string[] args) { var rootCommand = new RootCommand("The PHP switcher command line that will work on these tasks for you."); var phpversion = new Argument <string>( name: "phpversion", description: "The PHP version to switch to." ); rootCommand.AddArgument(phpversion); var configjson = new Option <FileInfo>( name: "--config-json", description: "The path to phpswitch.json configuration file." ); rootCommand.AddOption(configjson); var verbose = new Option <bool>( name: "--verbose", description: "Show verbose output" ); verbose.AddAlias("-v"); rootCommand.Add(verbose); rootCommand.Description = "The PHP switcher command line that will work on these tasks for you." + "\n" + " Switch PHP version for CLI.\n" + " Rewrite Apache configuration to use selected PHP version. (Optional)\n" + " Start and stop web server service(s). (Optional)\n" + " Copy files depend on PHP version in JSON config file. (Optional)"; rootCommand.SetHandler((phpversion, configJson, verbose) => { var app = new App(); app.Run(phpversion, configJson, verbose); }, phpversion, configjson, verbose); // Parse the incoming args and invoke the handler return(rootCommand.InvokeAsync(args).Result); }
public async Task RootCommand_InvokeAsync_returns_1_when_handler_throws() { var wasCalled = false; var rootCommand = new RootCommand(); rootCommand.SetHandler(() => { wasCalled = true; throw new Exception("oops!"); // Help the compiler pick a CommandHandler.Create overload. #pragma warning disable CS0162 // Unreachable code detected return(Task.FromResult(0)); #pragma warning restore CS0162 }); var resultCode = await rootCommand.InvokeAsync(""); wasCalled.Should().BeTrue(); resultCode.Should().Be(1); }
// <mainandhandler> static async Task <int> Main(string[] args) { int returnCode = 0; var urlOption = new Option <string>("--url", "A URL."); var rootCommand = new RootCommand("Handle termination example"); rootCommand.Add(urlOption); rootCommand.SetHandler(async( string urlOptionValue, CancellationToken token) => { returnCode = await DoRootCommand(urlOptionValue, token); }, urlOption); await rootCommand.InvokeAsync(args); return(returnCode); }
// <contextexitcode> static async Task <int> Main(string[] args) { var delayOption = new Option <int>("--delay"); var messageOption = new Option <string>("--message"); var rootCommand = new RootCommand("Model binding example"); rootCommand.Add(delayOption); rootCommand.Add(messageOption); rootCommand.SetHandler(async (int delayOptionValue, string messageOptionValue, InvocationContext ctx) => { Console.WriteLine($"--delay = {delayOptionValue}"); await Task.Delay(delayOptionValue); Console.WriteLine($"--message = {messageOptionValue}"); ctx.ExitCode = 100; }, delayOption, messageOption); return(await rootCommand.InvokeAsync(args)); }
public static int Main(string[] args) { var file = new Option <FileInfo>("--file", "the file to decrypt") { IsRequired = true }; var dir = new Option <DirectoryInfo>("--destDir", "the destination directory") { IsRequired = true }; var rootCommand = new RootCommand { file, dir }; rootCommand.Description = "Decrypt a file into a directory."; rootCommand.SetHandler((FileInfo file, DirectoryInfo dir) => Main2(file, dir), file, dir); return(rootCommand.InvokeAsync(args).Result); }
static async Task <int> Main(string[] args) { // <option> var fileOption = new Option <FileInfo?>( name: "--file", description: "The file to read and display on the console."); var rootCommand = new RootCommand("Sample app for System.CommandLine"); rootCommand.AddOption(fileOption); // </option> // <sethandler> rootCommand.SetHandler( (FileInfo file) => { ReadFile(file); }, fileOption); // </sethandler> return(await rootCommand.InvokeAsync(args)); }
static async Task Main(string[] args) { var delayOption = new Option <int>("--delay"); var messageOption = new Option <string>("--message"); var rootCommand = new RootCommand("Middleware example"); rootCommand.Add(delayOption); rootCommand.Add(messageOption); rootCommand.SetHandler((int delayOptionValue, string messageOptionValue) => { DoRootCommand(delayOptionValue, messageOptionValue); }, delayOption, messageOption); // <middleware> var commandLineBuilder = new CommandLineBuilder(rootCommand); commandLineBuilder.AddMiddleware(async(context, next) => { if (context.ParseResult.Directives.Contains("just-say-hi")) { context.Console.WriteLine("Hi!"); } else { await next(context); } }); commandLineBuilder.UseDefaults(); var parser = commandLineBuilder.Build(); await parser.InvokeAsync("[just-say-hi] --delay 42 --message \"Hello world!\""); // </middleware> }
public static int Main(string[] args) { var dir = new Option <DirectoryInfo>("--dir", "the directory to weakly encrypt") { IsRequired = true }; var file = new Option <FileInfo>("--file", "the file to hold the directory's contents") { IsRequired = true }; var rootCommand = new RootCommand { dir, file }; rootCommand.Description = "Weakly encrypt a directory's contents and store in a file."; rootCommand.SetHandler((DirectoryInfo dir, FileInfo file) => Main2(dir, file), dir, file); return(rootCommand.InvokeAsync(args).Result); }
private static Task <int> Main(string[] args) { var onlineConfigDirOption = new Option <string>("--online-config-dir", "Directory of generated online config.") { IsRequired = true, }; var outputDirOption = new Option <string>("--output-dir", "Output directory.") { IsRequired = true, }; var rootCommand = new RootCommand("A rescue tool CLI for restoring ss-uri-gen config from generated online config directory.") { onlineConfigDirOption, outputDirOption, }; var cancellationTokenBinder = new CancellationTokenBinder(); rootCommand.SetHandler(HandleRootCommand, onlineConfigDirOption, outputDirOption, cancellationTokenBinder); Console.OutputEncoding = Encoding.UTF8; return(rootCommand.InvokeAsync(args)); }
static async Task RequiredOption(string[] args) { // <requiredoption> var endpointOption = new Option <Uri>("--endpoint") { IsRequired = true }; var command = new RootCommand(); command.Add(endpointOption); command.SetHandler( (Uri? uri) => { Console.WriteLine(uri?.GetType()); Console.WriteLine(uri?.ToString()); }, endpointOption); await command.InvokeAsync(args); // </requiredoption> Console.WriteLine("Provide required option"); await command.InvokeAsync("--endpoint https://contoso.com"); }
private static Task Main(string[] args) { var botTokenOption = new Option <string?>("--bot-token", "Telegram bot token."); var enableCommandsModuleOption = new Option <bool?>("--enable-commands-mod", "Whether to enable the commands module."); var enableStatsModuleOption = new Option <bool?>("--enable-stats-mod", "Whether to enable the stats module."); var enablePersonalCommandsOption = new Option <bool?>("--enable-personal-commands", "Whether to enable personal commands."); var enableCommonCommandsOption = new Option <bool?>("--enable-common-commands", "Whether to enable common commands."); var enableDiceCommandsOption = new Option <bool?>("--enable-dice-commands", "Whether to enable dice commands."); var enableConsentNotNeededCommandsOption = new Option <bool?>("--enable-consent-not-needed-commands", "Whether to enable consent not needed commands."); var enableNonVeganCommandsOption = new Option <bool?>("--enable-non-vegan-commands", "Whether to enable non-vegan commands."); var enableLawEnforcementCommandsOption = new Option <bool?>("--enable-law-enforcement-commands", "Whether to enable law enforcement commands."); var enablePublicServicesCommandsOption = new Option <bool?>("--enable-public-services-commands", "Whether to enable public services commands."); var enableChineseCommandsOption = new Option <bool?>("--enable-chinese-commands", "Whether to enable Chinese commands."); var enableChineseTasksCommandsOption = new Option <bool?>("--enable-chinese-tasks-commands", "Whether to enable Chinese tasks commands."); var enableSystemdCommandsOption = new Option <bool?>("--enable-systemd-commands", "Whether to enable systemd commands."); var enableGrassStatsOption = new Option <bool?>("--enable-grass-stats", "Whether to enable grass stats."); var enableCommandStatsOption = new Option <bool?>("--enable-command-stats", "Whether to enable command stats."); var enableMessageCounterOption = new Option <bool?>("--enable-message-counter", "Whether to enable message counter."); var configGetCommand = new Command("get", "Print config."); var configSetCommand = new Command("set", "Change config.") { botTokenOption, enableCommandsModuleOption, enableStatsModuleOption, enablePersonalCommandsOption, enableCommonCommandsOption, enableDiceCommandsOption, enableConsentNotNeededCommandsOption, enableNonVeganCommandsOption, enableLawEnforcementCommandsOption, enablePublicServicesCommandsOption, enableChineseCommandsOption, enableChineseTasksCommandsOption, enableSystemdCommandsOption, enableGrassStatsOption, enableCommandStatsOption, enableMessageCounterOption, }; var configSetBinder = new ConfigSetBinder( botTokenOption, enableCommandsModuleOption, enableStatsModuleOption, enablePersonalCommandsOption, enableCommonCommandsOption, enableDiceCommandsOption, enableConsentNotNeededCommandsOption, enableNonVeganCommandsOption, enableLawEnforcementCommandsOption, enablePublicServicesCommandsOption, enableChineseCommandsOption, enableChineseTasksCommandsOption, enableSystemdCommandsOption, enableGrassStatsOption, enableCommandStatsOption, enableMessageCounterOption); configGetCommand.SetHandler <CancellationToken>(ConfigCommand.Get); configSetCommand.SetHandler <ConfigChangeSet, CancellationToken>(ConfigCommand.Set, configSetBinder); var configCommand = new Command("config", "Print or change config.") { configGetCommand, configSetCommand, }; var rootCommand = new RootCommand("A stupid and annoying chatbot for your group chats.") { configCommand, }; rootCommand.AddOption(botTokenOption); rootCommand.SetHandler <string?, CancellationToken>(BotRunner.RunBot, botTokenOption); Console.OutputEncoding = Encoding.UTF8; return(rootCommand.InvokeAsync(args)); }
static async Task DescriptionSection(string[] args) { var fileOption = new Option <FileInfo>( "--file", description: "The file to print out.", getDefaultValue: () => new FileInfo("scl.runtimeconfig.json")); var lightModeOption = new Option <bool>( "--light-mode", description: "Determines whether the background color will be black or white", getDefaultValue: () => true); var foregroundColorOption = new Option <ConsoleColor>( "--color", description: "Specifies the foreground color of console output", getDefaultValue: () => ConsoleColor.White); var rootCommand = new RootCommand("Read a file") { fileOption, lightModeOption, foregroundColorOption }; rootCommand.SetHandler( (FileInfo file, bool lightMode, ConsoleColor color) => { Console.BackgroundColor = lightMode ? ConsoleColor.Black : ConsoleColor.White; Console.ForegroundColor = color; Console.WriteLine($"--file = {file?.FullName}"); Console.WriteLine($"File contents:\n{file?.OpenText().ReadToEnd()}"); }, fileOption, lightModeOption, foregroundColorOption); // <description> fileOption.ArgumentHelpName = "<FILEPATH>"; var parser = new CommandLineBuilder(rootCommand) .UseDefaults() .UseHelp(ctx => { ctx.HelpBuilder.CustomizeSymbol(foregroundColorOption, firstColumnText: "--color <Black, White, Red, or Yellow>", secondColumnText: "Specifies the foreground color. " + "Choose a color that provides enough contrast " + "with the background color. " + "For example, a yellow foreground can't be read " + "against a light mode background."); ctx.HelpBuilder.CustomizeLayout( _ => HelpBuilder.Default .GetLayout() .Skip(1) // Skip the default command description section. .Prepend( _ => Spectre.Console.AnsiConsole.Write( new FigletText(rootCommand.Description !)) )); }) .Build(); await parser.InvokeAsync(args); // </description> Console.WriteLine("Description section customized"); await parser.InvokeAsync("-h"); }
static int Main(string[] args) { var assemblyFilenameOption = new Option <FileInfo>( new[] { "--assembly", "-a" }, description: "The assembly to decompile into XML."); var verboseOption = new Option <bool>( new[] { "--verbose", "-v" }, description: "Provide output as code is running."); var outputOption = new Option <DirectoryInfo>( new[] { "--output", "-o" }, description: "The root directory where the XML files will be written. The directory must exist."); var rootCommand = new RootCommand { assemblyFilenameOption, verboseOption, outputOption, }; rootCommand.Description = "Command to extract C# code into XML suitable for reasoning."; rootCommand.SetHandler((FileInfo assemblyFile, bool verbose, DirectoryInfo outputDirectory) => { if (assemblyFile == null) { Console.Error.WriteLine("No assembly provided to extract"); return; } if (outputDirectory == null) { Console.Error.WriteLine("No target directory provided"); return; } // Set up the preferences for the decompilation of the IL into source. var settings = new DecompilerSettings() { AlwaysUseBraces = true, ShowXmlDocumentation = true }; settings.CSharpFormattingOptions.IndentationString = " "; var decompiler = new CSharpDecompiler(assemblyFile.FullName, settings); // Traverse all the types in the assembly foreach (var typeDefinition in decompiler.TypeSystem.MainModule.TopLevelTypeDefinitions) { if (typeDefinition.Name.StartsWith("<")) { continue; } if (verbose) { Console.WriteLine($"Extracting {typeDefinition.FullName}."); } var syntaxTree = decompiler.DecompileType(typeDefinition.FullTypeName); // This is needed to get the locations correctly set in the AST. StringWriter w = new StringWriter(); var q = new TextWriterTokenWriter(w); q.IndentationString = " "; TokenWriter tokenWriter = q; tokenWriter = TokenWriter.WrapInWriterThatSetsLocationsInAST(tokenWriter); syntaxTree.AcceptVisitor(new CSharpOutputVisitor(tokenWriter, settings.CSharpFormattingOptions)); var source = w.ToString(); var generator = new XmlGeneratorVisitor(assemblyFile.FullName, source); syntaxTree.AcceptVisitor(generator); File.WriteAllText(Path.Combine(outputDirectory.FullName, typeDefinition.FullTypeName.Name) + ".xml", generator.Document.ToString()); } }, assemblyFilenameOption, verboseOption, outputOption); return(rootCommand.Invoke(args)); }
static async Task <int> Main(string[] args) { // var workerFileName = $"HstWbInstaller.Imager.GuiApp.exe"; // var currentProcessId = Process.GetCurrentProcess().Id; // var processes = Process.GetProcesses(); // // foreach (var process in processes) // { // try // { // if (process.Id == currentProcessId || // process.ProcessName.IndexOf("HstWbInstaller.Imager.GuiApp", StringComparison.OrdinalIgnoreCase) < 0 || // process.MainModule == null || // process.MainModule.FileName == null || // process.MainModule.FileName.IndexOf(workerFileName, StringComparison.OrdinalIgnoreCase) < 0) // { // continue; // } // } // catch (Exception) // { // continue; // } // // var kill = process.MainModule.FileName; // //process.Kill(); // } //var process = ElevateHelper.StartElevatedProcess("HstWB Installer", "cmd.exe"); // await process.WaitForExitAsync(); //var process = ElevateHelper.StartElevatedProcess("HstWB Installer", "cmd.exe"); // await process.WaitForExitAsync(); // //await "/usr/bin/osascript".RunProcessAsync("-e 'do shell script \"/bin/bash\" with prompt \"{prompt}\" with administrator privileges'"); //return 0; var mbrTest = new MbrTest(); mbrTest.Create(); mbrTest.Read(); var listOption = new Option <bool>( new[] { "--list", "-l" }, "List physical drives."); var infoOption = new Option <string>( new[] { "--info", "-i" }, "Display information about physical drive or image file.") { Arity = ArgumentArity.ExactlyOne }; var readOption = new Option <string[]>( new[] { "--read", "-r" }, "Read physical drive to image file.") { AllowMultipleArgumentsPerToken = true, Arity = new ArgumentArity(2, 2) }; var writeOption = new Option <string[]>( new[] { "--write", "-w" }, "Write image file to physical drive.") { AllowMultipleArgumentsPerToken = true, Arity = new ArgumentArity(2, 2) }; var convertOption = new Option <string[]>( new[] { "--convert", "-c" }, "Convert image file.") { AllowMultipleArgumentsPerToken = true, Arity = new ArgumentArity(2, 2) }; var verifyOption = new Option <string[]>( new[] { "--verify", "-v" }, "Verify image file.") { AllowMultipleArgumentsPerToken = true, Arity = new ArgumentArity(2, 2) }; var blankOption = new Option <string>( new[] { "--blank", "-b" }, "Create blank image file.") { Arity = ArgumentArity.ExactlyOne }; var optimizeOption = new Option <string>( new[] { "--optimize", "-o" }, "Optimize image file.") { Arity = ArgumentArity.ExactlyOne }; var sizeOption = new Option <long>( new[] { "--size", "-s" }, "Size of source image file or physical drive."); var fakeOption = new Option <bool>( new[] { "--fake", "-f" }, "Fake source paths (debug only).") { IsHidden = true }; var rootCommand = new RootCommand { listOption, infoOption, readOption, writeOption, convertOption, verifyOption, blankOption, optimizeOption, sizeOption, fakeOption }; rootCommand.Description = "HstWB Installer Imager to read and write image file to and from physical drive."; rootCommand.SetHandler( async(bool list, string info, string[] read, string[] write, string[] convert, string[] verify, string blank, string optimize, long size, bool fake) => { var arguments = new Arguments(); if (list) { arguments = new Arguments { Command = Arguments.CommandEnum.List }; } else if (!string.IsNullOrWhiteSpace(info)) { arguments = new Arguments { Command = Arguments.CommandEnum.Info, SourcePath = info }; } else if (read.Any()) { arguments = new Arguments { Command = Arguments.CommandEnum.Read, SourcePath = read[0], DestinationPath = read[1] }; } else if (write.Any()) { arguments = new Arguments { Command = Arguments.CommandEnum.Write, SourcePath = write[0], DestinationPath = write[1] }; } else if (convert.Any()) { arguments = new Arguments { Command = Arguments.CommandEnum.Convert, SourcePath = convert[0], DestinationPath = convert[1] }; } else if (verify.Any()) { arguments = new Arguments { Command = Arguments.CommandEnum.Verify, SourcePath = verify[0], DestinationPath = verify[1] }; } else if (!string.IsNullOrWhiteSpace(blank)) { arguments = new Arguments { Command = Arguments.CommandEnum.Blank, SourcePath = blank }; } else if (!string.IsNullOrWhiteSpace(optimize)) { arguments = new Arguments { Command = Arguments.CommandEnum.Optimize, SourcePath = optimize }; } if (size != 0) { arguments.Size = size; } arguments.Fake = fake; await Run(arguments); }, listOption, infoOption, readOption, writeOption, convertOption, verifyOption, blankOption, optimizeOption, sizeOption, fakeOption); return(await rootCommand.InvokeAsync(args)); }