/// <summary> /// Check command line semantics. /// </summary> public static void Check(CmdLineNode commandLine, CmdLineRules rules) { // Check rules consistency var cmds = new HashSet <string>(); foreach (var command in rules.Commands) { if (!cmds.Add(command.Name)) { throw new CommandLineCheckException($"Duplicate commands '{command.Name}'"); } } var cmdOpts = new Dictionary <string, HashSet <string> >(); foreach (var cmdOpt in rules .Options .SelectMany( opt => !opt.DependOnCommands.Any() ? new[] { new { Cmd = "", Opt = opt.Name } } : opt.DependOnCommands.Select(cn => new { Cmd = cn, Opt = opt.Name }))) { HashSet <string> opts; if (!cmdOpts.TryGetValue(cmdOpt.Cmd, out opts)) { opts = new HashSet <string>(); cmdOpts.Add(cmdOpt.Cmd, opts); } if (!opts.Add(cmdOpt.Opt)) { throw new CommandLineCheckException( $"Duplicate option {cmdOpt.Opt}{(cmdOpt.Cmd == "" ? "" : $" in command {cmdOpt.Cmd}")}"); } }
public void OneCommand() { var rules = new CmdLineRules( CommandQuantifier.One, new[] { new CommandRule("cmd1"), new CommandRule("cmd2") }, new[] { new OptionRule("opt1") }); var settings = GetSettings(); settings.OptionPrefix = OptionPrefix.Slash; var res = rules.PrintUsage(settings); Assert.AreEqual(@"Test program. Copyright (C) 2010 by CodeJam Team. All rights reserved. Usage: program.exe <cmd1|cmd2> [/opt1...] - COMMANDS - cmd1 - cmd2 - - OPTIONS - /opt1 - ", res); }
private static string GetCommandDescription(CommandRule cmd, CmdLineRules rules, string optPrefix) { var sb = new StringBuilder(cmd.Description); var cmdOpts = rules .Options .Where(opt => opt.DependOnCommands.Contains(cmd.Name)) .ToArray(); var reqOpts = cmdOpts .Where(opt => opt.Required) .Select(opt => GetOptionString(opt, false, optPrefix)) .Join(", "); if (reqOpts.Length > 0) { sb.Append($" Required: {reqOpts}."); } var optOpts = cmdOpts .Where(opt => !opt.Required) .Select(opt => GetOptionString(opt, false, optPrefix)) .Join(", "); if (optOpts.Length > 0) { sb.Append($" Optional: {optOpts}."); } return(sb.ToString()); }
/// <summary> /// Print usage. /// </summary> public static string PrintUsage( [NotNull] this CmdLineRules rules, [NotNull] PrintUsageSettings settings) { var sw = new StringWriter(); PrintUsage(rules, sw, settings); return(sw.ToString()); }
/// <summary> /// Print usage. /// </summary> public static void PrintUsage( [NotNull] this CmdLineRules rules, [NotNull] TextWriter writer, [NotNull] PrintUsageSettings settings) { Code.NotNull(rules, nameof(rules)); Code.NotNull(writer, nameof(writer)); Code.NotNull(settings, nameof(settings)); UsagePrinter.PrintUsage(rules, writer, settings); }
/// <summary> /// Print usage. /// </summary> public static void PrintUsage( [NotNull] this CmdLineRules rules, [NotNull] TextWriter writer, [NotNull] PrintUsageSettings settings) { if (rules == null) { throw new ArgumentNullException(nameof(rules)); } if (writer == null) { throw new ArgumentNullException(nameof(writer)); } if (settings == null) { throw new ArgumentNullException(nameof(settings)); } UsagePrinter.PrintUsage(rules, writer, settings); }
public void ZeroOrOneCommand() { var rules = new CmdLineRules( CommandQuantifier.ZeroOrOne, new [] { new CommandRule("cmd1", "Command 1."), new CommandRule("cmd2", "Command 2."), new CommandRule("command3", "Command #3.") }, new[] { new OptionRule("opt1", "Option 1."), new OptionRule("opt2", "Option #2.", OptionType.Value, true, "cmd2"), new OptionRule("opt3", "Option Three.", OptionType.Bool, false, "cmd2") }); var res = rules.PrintUsage(GetSettings()); Assert.AreEqual( @"Test program. Copyright (C) 2010 by CodeJam Team. All rights reserved. Usage: program.exe [cmd1|cmd2|command3] [-opt1|-opt2=|-opt3+...] - COMMANDS - cmd1 - Command 1. cmd2 - Command 2. Required: -opt2=. Optional: -opt3+. command3 - Command #3. - OPTIONS - -opt1 - Option 1. -opt2=<value> - Option #2. Required. Valid with commands: cmd2. -opt3[+|-] - Option Three. Valid with commands: cmd2. ", res); }
public static void PrintUsage(CmdLineRules rules, TextWriter writer, PrintUsageSettings settings) { var titleExists = false; if (!settings.ProductNameString.IsNullOrEmpty()) { writer.WriteLine(settings.ProductNameString); titleExists = true; } if (!settings.CopyrightString.IsNullOrEmpty()) { writer.WriteLine(settings.CopyrightString); titleExists = true; } if (titleExists) { writer.WriteLine(); } writer.Write("Usage: "); if (!settings.ProgramFileName.IsNullOrEmpty()) { writer.Write(settings.ProgramFileName); } else { var entry = Assembly.GetEntryAssembly(); if (entry == null) { throw new ApplicationException("Could not retrieve program file name. Try to specify it in settings."); } writer.Write(entry.GetName(false).Name); } var hasCmds = rules.Commands.Length > 0; if (hasCmds) { writer.Write(" "); string prefix, suffix; switch (rules.CommandQuantifier) { case CommandQuantifier.ZeroOrOne: prefix = "["; suffix = "]"; break; case CommandQuantifier.ZeroOrMultiple: prefix = "["; suffix = "...]"; break; case CommandQuantifier.One: prefix = "<"; suffix = ">"; break; case CommandQuantifier.OneOrMultiple: prefix = "<"; suffix = "...>"; break; default: throw new ArgumentOutOfRangeException(); } writer.Write( prefix + (settings.RealCommandsInHeadLine ? rules.Commands.Select(cmd => cmd.Name).Join("|") : "command") + suffix); } var hasOpts = rules.Options.Length > 0; string optPrefix; switch (settings.OptionPrefix) { case OptionPrefix.Dash: optPrefix = "-"; break; case OptionPrefix.Slash: optPrefix = "/"; break; default: throw new ArgumentOutOfRangeException(); } if (hasOpts) { writer.Write( // ReSharper disable once PassStringInterpolation " [{0}...]", settings.RealOptionsInHeadLine ? rules.Options.Select(opt => GetOptionString(opt, false, optPrefix)).Join("|") : "options"); } writer.WriteLine(); writer.WriteLine(); if (hasCmds) { writer.WriteLine(" - COMMANDS -"); var cmdDescs = rules .Commands .Select(cmd => new ItemDescriptor(cmd.Name, GetCommandDescription(cmd, rules, optPrefix))) .ToList(); var maxLen = cmdDescs.Max(desc => desc.Name.Length); foreach (var desc in cmdDescs) { var descWithSpace = desc.Description.IsNullOrEmpty() ? "" : " " + desc.Description; writer.WriteLine($" {desc.Name.PadRight(maxLen)} -{descWithSpace}"); } } if (hasOpts) { writer.WriteLine(" - OPTIONS -"); var optDescs = rules .Options .Select(opt => new ItemDescriptor(GetOptionString(opt, true, optPrefix), GetOptionDescription(opt))) .ToList(); var maxLen = optDescs.Max(desc => desc.Name.Length); foreach (var desc in optDescs) { var descWithSpace = desc.Description.IsNullOrEmpty() ? "" : " " + desc.Description; writer.WriteLine($" {desc.Name.PadRight(maxLen)} -{descWithSpace}"); } } }
/// <summary> /// Print usage with default settings. /// </summary> public static void PrintUsage( [NotNull] this CmdLineRules rules, [NotNull] TextWriter writer) => PrintUsage(rules, writer, new PrintUsageSettings());
/// <summary> /// Check command line semantics. /// </summary> public static void Check(CmdLineNode commandLine, CmdLineRules rules) => CommandLineChecker.Check(commandLine, rules);
/// <summary> /// Check command line semantics. /// </summary> public static void Check(string commandLine, CmdLineRules rules) => Check(CommandLineParser.ParseCommandLine(commandLine), rules);