是否有一个C#的命令行解析库,对git,svn等风格的“子命令”有很好的支持?例如,“git”命令有几个子命令:
git add git status git diff ...
必须在子命令名称之前的两个全局选项,以及必须遵循其名称的子命令的特定选项.例如,这些做了不同的事情:
git -p add git add -p
不同的子命令可能各自具有完全不同的选项和参数集.
我一直在使用NDesk.Options,但到目前为止我还不需要实现子命令.我认为它足够灵活,可以在上面构建子命令,但是如何以简洁优雅的方式做到这一点并不是完全明显的.是否可以在NDesk.Options中执行此操作,或者是否有更合适的C#命令行解析库?
解决方法
我偏爱
my own option parsing library,我是
blogging about currently.我的确计划涵盖子命令,但是在我达到它之前还需要一段时间(它将是最后的帖子之一).
Nito.KitchenSink.OptionParsing不直接支持子命令,但您可以使用该库仅解析部分命令行,并自行处理子命令. “全局”和“子命令特定”选项集添加了一个有趣的转折,但它可以这样做:
using System; using System.Linq; using Nito.KitchenSink.OptionParsing; class Program { private sealed class GlobalOptions : OptionArgumentsBase { // Use a better name than "POption". This is just an example. [Option('p',OptionArgument.None)] public bool POption { get; set; } // Override Validate to allow AdditionalArguments. public override void Validate() { } } private sealed class AddOptions : OptionArgumentsBase { [Option('p',OptionArgument.None)] public bool POption { get; set; } } static int Main() { try { // Parse the entire command line into a GlobalOptions object. var options = OptionParser.Parse<GlobalOptions>(); // The first entry in AdditionalArguments is our sub-command. if (options.AdditionalArguments.Count == 0) throw new OptionParsingException("No sub-command specified."); object subcommandOptions = null; string subcommand = options.AdditionalArguments[0]; switch (subcommand) { case "add": { // Parse the remaining arguments as command-specific options. subcommandOptions = OptionParser.Parse<AddOptions>(options.AdditionalArguments.Skip(1)); break; } case "status": // TODO: Parse command-specific options for this,too. break; case "diff": // TODO: Parse command-specific options for this,too. break; default: throw new OptionParsingException("Unknown sub-command: " + subcommand); } // At this point,we have our global options,subcommand,and subcommand options. Console.WriteLine("Global -p option: " + options.POption); Console.WriteLine("Subcommand: " + subcommand); var addOptions = subcommandOptions as AddOptions; if (addOptions != null) Console.WriteLine("Add-specific -p option: " + addOptions.POption); return 0; } catch (OptionParsingException ex) { Console.Error.WriteLine(ex.Message); // TODO: write out usage information. return 2; } catch (Exception ex) { Console.Error.WriteLine(ex); return 1; } } }
上面的示例程序产生以下输出:
>CommandLineParsingTest.exe No sub-command specified. >CommandLineParsingTest.exe -p No sub-command specified. >CommandLineParsingTest.exe test Unknown sub-command: test >CommandLineParsingTest.exe add Global -p option: False Subcommand: add Add-specific -p option: False >CommandLineParsingTest.exe -p add Global -p option: True Subcommand: add Add-specific -p option: False >CommandLineParsingTest.exe add -p Global -p option: False Subcommand: add Add-specific -p option: True >CommandLineParsingTest.exe -p add -p Global -p option: True Subcommand: add Add-specific -p option: True >CommandLineParsingTest.exe status Global -p option: False Subcommand: status >CommandLineParsingTest.exe -p status Global -p option: True Subcommand: status
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。