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); }
public CommandLineArgumentList ExpandShortForms(CommandLineArgumentList arguments) { foreach (var argument in arguments.OfType <CommandLineArgument.BareNameOrFlag>()) { if (MatchesAllShortForms(argument)) { return(arguments.ExpandShortFormArgument(argument)); } } return(arguments); }
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)); }
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>()); }
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); }
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); } }
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++; }
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()); }
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);
public int GetPartialMatchAccuracy(CommandLineArgumentList commandLineArgs) => Routes.GetPartialMatchAccuracy(commandLineArgs);
private static bool IsReadyForExecution( CommandLineArgumentList commandLineArgs, IReadOnlyCollection <CommandLineAction> resolvedCommandLineActions) { return(!(commandLineArgs.IsCallForHelp || resolvedCommandLineActions.Count != 1)); }
private IReadOnlyCollection <MethodMapping> GetMethodMappings(CommandLineArgumentList args) => _assemblyModel .Select(model => _methodMapper.GetMethodMapping(model, args)) .Choose() .ToList();
public IReadOnlyCollection <CommandLineAction> Resolve(CommandLineArgumentList commandLineArgs) => GetBestMatches(commandLineArgs) .Select(mapping => CreateAction(mapping, _objectFactory)) .ToList();