// 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()); }
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); }
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); } } }
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(); }
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))}"); } }
// 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"); } }
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"); } }
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); }
// 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); }
// 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(); }