// Given a Model, generates a string which can be printed to the CLI
        // based on information provided by the ApplicationModel
        public static string Generate(ArgumentModel model)
        {
            StringBuilder builder  = new StringBuilder();
            var           options  = model.Options.OrderBy(mo => mo.Definition.ShortName).ToList();
            var           operands = model.Operands.OrderBy(mo => mo.Definition.Position).ToList();
            var           envVars  = model.EnvironmentVariables.OrderBy(ev => ev.Definition.VariableName).ToList();

            // Header section
            if (model.CliArguments.UtilityName.Length > 0)
            {
                string utilityName = model.CliArguments.UtilityName;
                string version     = MainAssembly(model.CliArguments).GetName().Version.ToString().TrimEnd('.', '0');
                builder.AppendLine($"{utilityName} v{version} Documentation");
                builder.AppendLine();
            }
            if (model.Help.Detail.Length > 0)
            {
                builder.AppendLine(model.Help.Detail);
                builder.AppendLine();
            }

            builder.AppendLine(GenerateUsageSummary(MainAssembly(model.CliArguments).GetName().Name));
            builder.AppendLine();
            builder.AppendLine(GenerateBreakdown(options, operands, envVars));

            return(builder.ToString());
        }
예제 #2
0
 public static A Parse <A>(A arguments, string[] args) where A : BaseCliArguments
 {
     try {
         ArgumentModel model = ParseArguments(arguments, args);
         return((A)model.CliArguments);
     } catch (UserFacingException e) {
         arguments.UserFacingExceptionThrown = true;
         arguments.OnUserFacingException(e, e.Message);
     }
     return(arguments);
 }
예제 #3
0
 static void StoreEnvironmentVariables(ArgumentModel model)
 {
     foreach (var envVar in model.EnvironmentVariables)
     {
         object value = envVar.Strategy.GetValue(envVar);
         if (value != null)
         {
             envVar.Property.SetValue(model.CliArguments, value);
         }
     }
 }
예제 #4
0
        static void StoreOptions(ArgumentModel model, ParseResult parseResult)
        {
            foreach (var tokenGroup in parseResult.TokenGroups)
            {
                var modelOption = model.FindOptionByToken(tokenGroup.Option);

                object value = modelOption.Definition.Strategy.GetValue(modelOption, tokenGroup);
                modelOption.Property.SetValue(model.CliArguments, value);
            }
            model.CliArguments.Operands = parseResult.Operands.Select(t => t.Value).ToArray();
        }
예제 #5
0
        static void ValidateTokensForDuplicateOptions(ArgumentModel model, List <TokenGroup> tokenGroups)
        {
            var duplicates = tokenGroups
                             .Select(a => model.FindOptionByToken(a.Option).Definition)
                             .Duplicates(new BaseOptionAttributeEqualityComparer());

            if (duplicates.Any())
            {
                throw new DuplicateOptionException(
                          $"Duplicate options were provided for "
                          + $"{string.Join("/", duplicates.Select(o => o.LongName))}");
            }
        }
예제 #6
0
        // if an option was not provided, Validate whether it's marked as required
        static void ValidateRequiredOptions(ArgumentModel model, List <TokenGroup> usedOptions)
        {
            var requiredOption = model
                                 .WhereOptionsNotIn(usedOptions)
                                 .FirstOrDefault(mo => mo.Property.HasRequiredAttribute());

            if (requiredOption != null)
            {
                throw new RequiredException(
                          $"The option {Cli.DASH_SINGLE}{requiredOption.Definition.ShortName}/"
                          + $"{Cli.DASH_DOUBLE}{requiredOption.Definition.LongName} "
                          + "was not included, but is a required option");
            }
        }
예제 #7
0
        static void HandleUnusedOperands(ArgumentModel model, ParseResult parseResult)
        {
            int providedOperandsCount = parseResult.Operands.Count;

            var requiredOperand = model.Operands
                                  .Where(mo => mo.Definition.Position > providedOperandsCount)
                                  .FirstOrDefault(mo => mo.Required);

            if (requiredOperand != null)
            {
                throw new RequiredException(
                          $"The operand in position {requiredOperand.Definition.Position} "
                          + "was not provided, but is required");
            }
        }
예제 #8
0
        private static ArgumentModel ParseArguments <A>(A arguments, string[] args) where A : BaseCliArguments
        {
            // Process inputs
            ArgumentModel model       = new ArgumentModel(arguments);
            var           tokens      = Tokeniser.MakeTokens(args);
            ParseResult   parseResult = Parser.MakeParseResult(tokens, model);

            // Map results
            model = ArgumentMapper.MapOptions(model, parseResult);

            if (model.CliArguments.HelpInvoked)
            {
                model.HelpFacade.Execute();
            }

            return(model);
        }
예제 #9
0
        // Takes the input from the API and orchestrates the process of model population
        public static ArgumentModel MapOptions(ArgumentModel model, ParseResult parseResult)
        {
            // Validate Model and Arguments
            model.Validate();
            ValidateTokensForDuplicateOptions(model, parseResult.TokenGroups);

            // Populate ArgumentsModel
            StoreOptions(model, parseResult);
            if (model.CliArguments.HelpInvoked)
            {
                return(model);
            }
            ValidateRequiredOptions(model, parseResult.TokenGroups);

            StoreOperands(model, parseResult);
            HandleUnusedOperands(model, parseResult);

            StoreEnvironmentVariables(model);

            return(model);
        }
예제 #10
0
        // Map and then Remove operands which have been mapped on the Model
        static void StoreOperands(ArgumentModel model, ParseResult parseResult)
        {
            var operands = parseResult.Operands;

            foreach (var operand in model.Operands)
            {
                if (parseResult.OperandProvided(operand))
                {
                    object value = operand.Strategy.GetValue(operand, parseResult);
                    operand.Property.SetValue(model.CliArguments, value);
                }
            }

            var maxPosition = model
                              .Operands
                              .Max(mo => mo.Definition.Position as int?) ?? 0;

            model.CliArguments.Operands = model
                                          .CliArguments
                                          .Operands
                                          .Skip(maxPosition)
                                          .ToArray();
        }