Esempio n. 1
0
        public Option <(ParameterMapping, CommandLineArgumentList remainingArguments)> Map(
            ParameterModel parameterModel,
            CommandLineArgumentList args)
        {
            var maybeMappingByName = NamedPass(parameterModel, args);

            if (maybeMappingByName.HasValue)
            {
                return(maybeMappingByName);
            }

            var maybeMappingByPosition = PositionalPass(parameterModel, args);

            if (maybeMappingByPosition.HasValue)
            {
                return(maybeMappingByPosition);
            }

            if (parameterModel.AllowNoValues)
            {
                return(new ParameterMapping.NoValue(parameterModel), args);
            }

            return(None);
        }
Esempio n. 2
0
        public CommandLineArgumentList ExpandShortForms(CommandLineArgumentList arguments)
        {
            foreach (var argument in arguments.OfType <CommandLineArgument.BareNameOrFlag>())
            {
                if (MatchesAllShortForms(argument))
                {
                    return(arguments.ExpandShortFormArgument(argument));
                }
            }

            return(arguments);
        }
Esempio n. 3
0
        private static IReadOnlyCollection <CommandLineAction> ResolveActions(
            Func <Type, object> objectFactory,
            TypeConverterCollection typeConverters,
            CommandLineArgumentList commandLineArgs,
            AssemblyModel model)
        {
            var methodMapper = new MethodMapper(new ParameterMapper());

            return
                (new CommandLineActionFactory(
                     model, objectFactory, typeConverters, methodMapper)
                 .Resolve(commandLineArgs));
        }
Esempio n. 4
0
        private IReadOnlyCollection <MethodMapping> GetBestMatches(CommandLineArgumentList commandLineArgs)
        {
            var matchGroups =
                GetMethodMappings(commandLineArgs)
                .ToLookup(mapping => mapping.MatchPriority)
                .OrderByDescending(group => group.Key);

            return
                (matchGroups
                 .FirstOrDefault(group => group.Any())
                 ?.ToList()
                 ?? new List <MethodMapping>());
        }
Esempio n. 5
0
        public (bool isMatch, CommandLineArgumentList remainingArguments) MatchesVerbSequence(
            CommandLineArgumentList commandLineArguments)
        {
            var argsMatched = new List <CommandLineArgument>();

            using (var verbEnumerator = GetEnumerator())
                using (var inputArgumentEnumerator = commandLineArguments.GetEnumerator())
                {
                    while (verbEnumerator.MoveNext())
                    {
                        if (inputArgumentEnumerator.MoveNext() &&
                            inputArgumentEnumerator.Current is CommandLineArgument.Free free &&
                            verbEnumerator.Current.Matches(free.Value))
                        {
                            argsMatched.Add(free);
                        }
Esempio n. 6
0
        public static object Execute(CommandLineConfiguration config, params string[] args)
        {
            // Defensively copy the configuration into local variables
            var helpOutput = config.HelpOutput;

            _traceOutput = config.TraceOutput;
            var assembliesToScan = config.AssembliesToScan.ToList();
            var typeConverters   = new TypeConverterCollection(config.TypeConverters);
            var objectFactory    = config.ObjectFactory;

            var commandLineArgs = CommandLineArgumentList.Parse(args);

            if (commandLineArgs.TraceToStandardOutput)
            {
                _traceOutput = helpOutput;
            }

            var model = AssemblyModel.Scan(assembliesToScan);
            var resolvedCommandLineActions = ResolveActions(
                objectFactory, typeConverters, commandLineArgs, model);

            if (IsReadyForExecution(commandLineArgs, resolvedCommandLineActions))
            {
                var commandLineAction = resolvedCommandLineActions.Single();

                try
                {
                    return(commandLineAction.Invoke());
                }
                catch (TypeConversionException e)
                {
                    helpOutput(e.Message);
                    _traceOutput(e.ToString());

                    return(null);
                }
            }
            else
            {
                var helpBuilder = new HelpBuilder(XmlCommentsRepository.LoadFor(assembliesToScan));

                helpOutput(
                    helpBuilder.GenerateHelp(commandLineArgs, model, resolvedCommandLineActions));

                return(null);
            }
        }
Esempio n. 7
0
        public int GetPartialMatchAccuracy(CommandLineArgumentList commandLineArgs)
        {
            var bestAccuracy = 0;

            foreach (var route in _routes)
            {
                using (var verbEnumerator = route.GetEnumerator())
                    using (var inputArgumentEnumerator = commandLineArgs.GetEnumerator())
                    {
                        var currentAccuracy = 0;

                        while (verbEnumerator.MoveNext())
                        {
                            if (inputArgumentEnumerator.MoveNext() &&
                                inputArgumentEnumerator.Current is CommandLineArgument.Free free &&
                                verbEnumerator.Current.Matches(free.Value))
                            {
                                currentAccuracy++;
                            }
Esempio n. 8
0
        public string GenerateHelp(
            CommandLineArgumentList commandLineArgs,
            IEnumerable <MethodModel> models,
            IReadOnlyCollection <CommandLineAction> resolvedCommandLineActions)
        {
            var(maxAccuracy, modelsForHelp) = models.AllByMax(m => m.GetPartialMatchAccuracy(commandLineArgs));

            var sb = new StringBuilder();

            if (!commandLineArgs.IsCallForHelp)
            {
                if (resolvedCommandLineActions.Count == 0)
                {
                    sb.AppendLine("Could not match the given arguments to a command");
                    sb.AppendLine("");
                }
                else if (resolvedCommandLineActions.Count > 1)
                {
                    sb.AppendLine("The given arguments are ambiguous between the following:");

                    modelsForHelp = resolvedCommandLineActions.Select(a => a.Model).ToList();
                }
            }

            if (commandLineArgs.Count == 0)
            {
                sb.AppendLine("Usage:");
            }
            else
            {
                sb.AppendLine($"Help for {String.Join(" ", commandLineArgs.Take(maxAccuracy))}:");
            }

            sb.AppendLine("");

            foreach (var model in modelsForHelp)
            {
                sb.AppendLine(BuildForMethod(model).ToString());
            }

            return(sb.ToString());
        }
Esempio n. 9
0
        public Option <(ParameterMapping, CommandLineArgumentList remainingArguments)> NamedPass(
            ParameterModel parameterModel,
            CommandLineArgumentList args)
        {
            var argumentsMatched = new List <CommandLineArgument>();
            var suppliedValues   = new List <string>();

            using (var enumerator = args.GetEnumerator())
            {
                while (enumerator.MoveNext())
                {
                    switch (enumerator.Current)
                    {
                    case CommandLineArgument.NameValuePair nvPair
                        when parameterModel.MatchesName(nvPair.Name):

                        argumentsMatched.Add(nvPair);

                        if (parameterModel.AllowMultipleValues)
                        {
                            suppliedValues.Add(nvPair.Value);
                            continue;
                        }

                        return(
                            new ParameterMapping.NamedValue(parameterModel, ListOf(nvPair.Value)),
                            args.Without(argumentsMatched));

                    case CommandLineArgument.BareNameOrFlag nameOrFlag
                        when parameterModel.MatchesName(nameOrFlag.Name) && parameterModel.IsFlag:
                        argumentsMatched.Add(nameOrFlag);

                        return(
                            new ParameterMapping.Flag(parameterModel),
                            args.Without(argumentsMatched));

                    case CommandLineArgument.BareNameOrFlag bnf
                        when parameterModel.MatchesName(bnf.Name):
                        if (enumerator.MoveNext())
                        {
                            if (enumerator.Current is CommandLineArgument.Free free)
                            {
                                argumentsMatched.Add(bnf);
                                argumentsMatched.Add(free);

                                if (parameterModel.AllowMultipleValues)
                                {
                                    suppliedValues.Add(free.Value);
                                    continue;
                                }

                                return(
                                    new ParameterMapping.NamedValue(
                                        parameterModel,
                                        ListOf(free.Value)),
                                    args.Without(argumentsMatched));
                            }
                        }

                        break;

                    default:
                        break;
                    }
                }
            }

            if (parameterModel.AllowMultipleValues && suppliedValues.Any())
            {
                return(
                    new ParameterMapping.NamedValue(parameterModel, suppliedValues),
                    args.Without(argumentsMatched));
            }

            return(default);
Esempio n. 10
0
 public int GetPartialMatchAccuracy(CommandLineArgumentList commandLineArgs) =>
 Routes.GetPartialMatchAccuracy(commandLineArgs);
Esempio n. 11
0
 private static bool IsReadyForExecution(
     CommandLineArgumentList commandLineArgs,
     IReadOnlyCollection <CommandLineAction> resolvedCommandLineActions)
 {
     return(!(commandLineArgs.IsCallForHelp || resolvedCommandLineActions.Count != 1));
 }
Esempio n. 12
0
 private IReadOnlyCollection <MethodMapping> GetMethodMappings(CommandLineArgumentList args) =>
 _assemblyModel
 .Select(model => _methodMapper.GetMethodMapping(model, args))
 .Choose()
 .ToList();
Esempio n. 13
0
 public IReadOnlyCollection <CommandLineAction> Resolve(CommandLineArgumentList commandLineArgs) =>
 GetBestMatches(commandLineArgs)
 .Select(mapping => CreateAction(mapping, _objectFactory))
 .ToList();