private SubCommandAttribute GetSubCommandAttribute(out TCommandExecutor commandExecutor, out IEnumerator <string> argumentEnumerator) { TCommandExecutor executor = new TCommandExecutor(); IEnumerable <string> args = Environment.GetCommandLineArgs().Skip(1); IEnumerator <string> enumerator = args.GetEnumerator(); while (enumerator.MoveNext()) { string arg = enumerator.Current; SubCommandAttribute attr = _commands.FirstOrDefault(c => c.Command == enumerator.Current); if (attr != null) { commandExecutor = executor; argumentEnumerator = enumerator; return(attr); } if (!_attrs.Any(kvp => kvp.Value.TryConsumeArgs(executor, kvp.Key, enumerator)) && arg != "-h" && arg != "--help") { throw new ArgumentException($"Invalid argument '{enumerator.Current}'"); } } commandExecutor = null; argumentEnumerator = null; return(null); }
public async Task Invoke() { SubCommandAttribute cmdAttr = this.GetSubCommandAttribute(out TCommandExecutor commandExecutor, out IEnumerator <string> argumentEnumerator); if (cmdAttr == null && this.IsHelp()) { this.ShowHelp(); return; } //if (cmdAttr == null) { // IEnumerable<string> args = Environment.GetCommandLineArgs().Skip(1); // string strCmd = args.FirstOrDefault(); // throw new CommandLineException($"Invalid command: {strCmd}"); //} if (this.IsHelp(cmdAttr)) { this.ShowHelp(cmdAttr); return; } if (cmdAttr != null) { SubCommand cmd = this.GetSubCommand(commandExecutor, cmdAttr.Type, argumentEnumerator); await cmd.Run(); } }
public void ShowHelp(SubCommandAttribute cmdAttr) { string fileName = Path.GetFileNameWithoutExtension(System.Reflection.Assembly.GetEntryAssembly().Location); string description = this.Type.GetCustomAttribute <DescriptionAttribute>()?.Description ?? string.Empty; Console.WriteLine(fileName); Console.WriteLine(description); Console.WriteLine(); Console.WriteLine("Command:"); Console.WriteLine($" {cmdAttr.Command}:"); Console.WriteLine($" {cmdAttr.Description}"); Console.WriteLine(); Console.WriteLine("Usage:"); string argumentLine = string.Join( " ", cmdAttr.Type.GetProperties() .OrderBy(p => p.GetCustomAttribute <RequiredAttribute>() == null) .Select(p => { bool isReq = p.GetCustomAttribute <RequiredAttribute>() != null; bool isMulti = p.PropertyType.GetInterfaces().Contains(typeof(System.Collections.IEnumerable)) && p.PropertyType != typeof(string); CommandAbstractAttribute optAttr = p.GetCustomAttribute <CommandAbstractAttribute>(); if (optAttr == null) { return(null); } bool isOpt = optAttr is CommandOptionAttribute; return((isReq ? "" : "[") + "--" + optAttr.LongName + "|" + "-" + optAttr.ShortName + (isOpt ? " " + optAttr.LongName : "") + (isReq ? "" : "]") + (isMulti ? "+" : "")); }).Where(p => p != null) ); Console.WriteLine($"{fileName} {cmdAttr.Command} {argumentLine}"); Console.WriteLine(); var attrs = cmdAttr.Type.GetProperties().Where(p => p.GetCustomAttribute <CommandAbstractAttribute>(true) != null) .ToDictionary(p => p, p => p.GetCustomAttribute <CommandAbstractAttribute>(true)); Console.WriteLine("Options:"); foreach (var kvp in attrs) { var attr = kvp.Value; var p = kvp.Key; bool isOpt = attr is CommandOptionAttribute; Console.WriteLine($" --{attr.LongName} | -{attr.ShortName}" + (isOpt ? " " + attr.LongName : "") + ":"); Console.WriteLine($" {attr.Description}"); if (p.PropertyType.IsEnum) { string options = string.Join(", ", Enum.GetValues(p.PropertyType).OfType <object>()); Console.WriteLine($" Available options: {options}"); } Console.WriteLine(); } Console.WriteLine($" --help | -h"); Console.WriteLine($" Print this help message and exit."); Console.WriteLine(); }
public bool IsHelp(SubCommandAttribute cmd) { IEnumerable <string> args = Environment.GetCommandLineArgs().Skip(2); return(!args.Any() || args.Any(a => a == "-h" || a == "--help")); }