예제 #1
0
        async public Task ExecuteAsync <TRoot, TGlobalOptions>(TRoot rootCommand, TGlobalOptions globalOptions)
        {
            var verbAtt = new VerbAttribute
            {
                IsRoot   = true,
                Instance = rootCommand
            };

            var globalOptionsWrapper = _impl.GetGlobalOptions(globalOptions);

            _attributeDecorator.Decorate(verbAtt, typeof(TGlobalOptions));

            var commandParts = _parser.Parse().GetEnumerator();

            try
            {
                await _impl.ExecuteInternalAsync(verbAtt, commandParts, globalOptionsWrapper);
            }
            catch (BadCommandException bce)
            {
                Console.WriteLine(bce.BadCommand);

                if (bce.Command != null)
                {
                    _commandHelper.WriteCommandHelp(bce.Command, _options, globalOptionsWrapper);
                }
                else
                {
                    _commandHelper.WriteVerbHelp(bce.Verb, _options, globalOptionsWrapper);
                }
            }
        }
예제 #2
0
 void IAttributeDecorator.Decorate(VerbAttribute parentVerbAtt, Type globalOptionsType)
 {
     foreach (var member in _typeHelper.GetPropertiesAndMethods(parentVerbAtt.Instance))
     {
         if (member is PropertyInfo property && _typeHelper.TryGetVerbAttribute(property, out var childVerbAtt))
         {
             childVerbAtt.Property   = property;
             childVerbAtt.ParentVerb = parentVerbAtt;
             childVerbAtt.Instance   = property.GetValue(parentVerbAtt.Instance);
             _attributeDecorator.Decorate(childVerbAtt, globalOptionsType);
             parentVerbAtt.Verbs[childVerbAtt.GetName()] = childVerbAtt;
         }
예제 #3
0
        void ICommandHelper.GetVerbHelp(VerbAttribute verb, string prefix, SortedDictionary <string, string> help)
        {
            foreach (var innerVerb in verb.Verbs.Values)
            {
                _commandHelper.GetVerbHelp(innerVerb, $"{prefix} {innerVerb.GetName()}", help);
            }

            foreach (var command in verb.Commands)
            {
                help.Add($"{prefix} {command.Key}", command.Value.HelpText);
            }
        }
예제 #4
0
        void ICommandHelper.WriteVerbHelp(VerbAttribute verb, ICommandExecutorOptions options, GlobalOptionsWrapper globalOptions)
        {
            var sortedDictionary = new SortedDictionary <string, string>();

            _commandHelper.GetVerbHelp(verb, "", sortedDictionary);

            if (verb.IsRoot)
            {
                WriteUsage(globalOptions, globalOptions.GlobalOptions != null, "COMMAND");

                WriteGlobalOptions(globalOptions);
            }

            Console.WriteLine();

            var commandGroups = verb.Commands.Select(x => x.Value).Distinct().Select(x => new
            {
                x.Category,
                Name = x.GetName(),
                x.HelpText
            }).Concat(verb.Verbs.Select(x => x.Value).Distinct().Select(x => new
            {
                x.Category,
                Name = x.GetName(),
                x.HelpText
            })).OrderBy(x => x.Name).GroupBy(x => x.Category);

            foreach (var commandGroup in commandGroups)
            {
                Console.WriteLine((commandGroup.Key ?? "Commands") + ":");

                foreach (var command in commandGroup)
                {
                    Console.CursorLeft = 2;
                    Console.Write(command.Name);

                    foreach (var line in GetLines(command.HelpText, 55))
                    {
                        Console.CursorLeft = 14;
                        Console.Write(line);
                    }

                    Console.WriteLine();
                }

                Console.WriteLine();
            }

            Console.WriteLine($"For help with command syntax, type `COMMAND --{options.HelpLongForm}` or `COMMAND -{options.HelpShortForm}`");
        }
예제 #5
0
        bool ICommandHelper.TryShowHelpOrVersion(CommandPart commandPart, VerbAttribute verb, string key, ICommandExecutorOptions options, GlobalOptionsWrapper globalOptions)
        {
            if ((commandPart.IsShortForm && key[0] == options.VersionShortForm) || (!commandPart.IsShortForm && key.Equals(options.VersionLongForm, StringComparison.OrdinalIgnoreCase)))
            {
                _commandHelper.WriteVersion(options);
                return(true);
            }

            if ((commandPart.IsShortForm && key[0] == options.HelpShortForm) || (!commandPart.IsShortForm && key.Equals(options.HelpLongForm, StringComparison.OrdinalIgnoreCase)))
            {
                _commandHelper.WriteVerbHelp(verb, options, globalOptions);
                return(true);
            }

            return(false);
        }
예제 #6
0
        async Task ICommandExecutorImpl.ExecuteInternalAsync(VerbAttribute verb, IEnumerator <CommandPart> commandParts, GlobalOptionsWrapper globalOptions)
        {
            if (!commandParts.MoveNext())
            {
                throw new BadCommandException(verb, "Malformed command");
            }

            if (commandParts.Current.IsArgument)
            {
                var key = _parser.GetString(commandParts.Current.Key);

                if (_impl.TrySetGlobalOption(key, commandParts.Current, globalOptions))
                {
                    await _impl.ExecuteInternalAsync(verb, commandParts, globalOptions);

                    return;
                }

                if (_commandHelper.TryShowHelpOrVersion(commandParts.Current, verb, key, _options, globalOptions))
                {
                    return;
                }

                throw new BadCommandException(verb, "Unexpected option");
            }

            var name = _parser.GetString(commandParts.Current.Key);

            if (verb.Verbs.TryGetValue(name, out var nextVerb))
            {
                await _impl.ExecuteInternalAsync(nextVerb, commandParts, globalOptions);

                return;
            }

            if (verb.Commands.TryGetValue(name, out var nextCommand))
            {
                await _impl.ExecuteCommandAsync(nextCommand, commandParts, globalOptions);

                return;
            }

            throw new BadCommandException(verb, name);
        }
예제 #7
0
 public bool TryGetVerbAttribute(PropertyInfo propertyInfo, out VerbAttribute verbAttribute)
 {
     verbAttribute = propertyInfo.GetCustomAttribute <VerbAttribute>();
     return(verbAttribute != null);
 }
예제 #8
0
 public BadCommandException(VerbAttribute verb, string badVerb)
     : base($"Unknown verb {badVerb}")
 {
     Verb       = verb;
     BadCommand = badVerb;
 }