public void Apply(IList <string> args, ICommand command, CommandDescriptor commandDescriptor) { for (int i = 0; i < args.Count; i++) { if (ApplyArgument(args[i], command, commandDescriptor)) { // Remove the argument because we have processed it args.RemoveAt(i); i--; } } }
public CommandDescriptor BuildDescriptor(Type commandType) { // Validate the type before we begin processing it ValidateType(commandType); // Build a descriptor CommandDescriptor descriptor = new CommandDescriptor(); CollectDetails(commandType, descriptor); CollectArguments(commandType, descriptor); CollectSubCommands(commandType, descriptor); // Validate command descriptor after it is built ValidateDescriptor(descriptor); return(descriptor); }
private static void CollectArguments(Type commandType, CommandDescriptor descriptor) { // Build up a list of arguments that will later be used for parsing PropertyInfo[] properties = commandType.GetProperties(BindingFlags.Public | BindingFlags.Instance); foreach (PropertyInfo propertyInfo in properties) { if (propertyInfo.IsDefined(typeof(ArgumentAttribute), true)) { ArgumentAttribute attribute = (ArgumentAttribute)Attribute.GetCustomAttribute( propertyInfo, typeof(ArgumentAttribute), true); ArgumentDescriptor argumentDescriptor = new ArgumentDescriptor(); argumentDescriptor.ArgumentType = propertyInfo.PropertyType; argumentDescriptor.PropertyInfo = propertyInfo; argumentDescriptor.Position = attribute.Position; // Add the specified short name if (!string.IsNullOrEmpty(attribute.ShortName)) { argumentDescriptor.ShortNames.Add(attribute.ShortName); } // Add the specified long name if (!string.IsNullOrEmpty(attribute.LongName)) { argumentDescriptor.LongNames.Add(attribute.LongName); } // If this isn't a positional argument, and a short or long name has not been set in the attribute, // then we'll automatically create a long name using the property name if (attribute.Position == -1 && string.IsNullOrEmpty(attribute.ShortName) && string.IsNullOrEmpty(attribute.LongName)) { argumentDescriptor.LongNames.Add(propertyInfo.Name.ToLower()); } descriptor.Arguments.Add(argumentDescriptor); } } }
public CommandDescriptor GetDescriptor(string commandName, CommandDescriptor parentCommand) { // Get the list of descriptors to look through IList <CommandDescriptor> descriptors = this.descriptors; if (parentCommand != null) { descriptors = parentCommand.SubCommands; } // Try to find a matching descriptor foreach (CommandDescriptor descriptor in descriptors) { if (descriptor.Name == commandName || descriptor.Aliases.Contains(commandName)) { return(descriptor); } } return(null); }
public void Register(Type commandType) { CommandDescriptor descriptor = descriptorBuilder.BuildDescriptor(commandType); descriptors.Add(descriptor); }
private bool ApplyArgument(string arg, ICommand command, CommandDescriptor commandDescriptor) { // Determine the name of the argument Prefix prefix; int endIndex; string argName; if (arg.StartsWith("--")) { prefix = Prefix.DoubleDash; endIndex = arg.IndexOfAny(KeyValueSeparators, 2); argName = arg.Substring(2, endIndex == -1 ? arg.Length - 2 : endIndex - 2); } else if (arg.StartsWith("-")) { prefix = Prefix.Dash; endIndex = arg.IndexOfAny(KeyValueSeparators, 1); argName = arg.Substring(1, endIndex == -1 ? arg.Length - 1 : endIndex - 1); } else if (arg.StartsWith("/")) { prefix = Prefix.ForwardSlash; endIndex = arg.IndexOfAny(KeyValueSeparators, 1); argName = arg.Substring(1, endIndex == -1 ? arg.Length - 1 : endIndex - 1); } else { // If the argument does not start a with the start of a named argument, we don't have any changes to make return(false); } // Remove the value suffixes from the argument name (these cannot be separators because args can have a dash in their name) argName = argName.TrimEnd(ValueSuffixes); // Attempt to find a descriptor for this argument List <ArgumentDescriptor> descriptors = new List <ArgumentDescriptor>(); if (prefix == Prefix.DoubleDash || prefix == Prefix.ForwardSlash) { descriptors.AddRange(commandDescriptor.Arguments.Where(a => a.LongNames.Contains(argName))); } if (prefix == Prefix.Dash || prefix == Prefix.ForwardSlash) { descriptors.AddRange(commandDescriptor.Arguments.Where(a => a.ShortNames.Contains(argName))); } if (descriptors.Count == 0) { throw new Exception(string.Format("Unknown argument '{0}'.", arg)); } if (descriptors.Count > 1) { throw new Exception(string.Format("Ambiguous argument '{0}', found {1} descriptors.", arg, descriptors.Count)); } var descriptor = descriptors[0]; // Get current value of this argument object currentValue = descriptor.PropertyInfo.GetValue(command, null); // Determine the value of the argument object argValue; if (ValueSuffixes.Contains(arg[arg.Length - 1])) { // Parse value with the '+' or '-' argValue = ValueConverter.ParseValue(descriptor.ArgumentType, arg[arg.Length - 1].ToString(), currentValue); } else if (endIndex == -1) { // No value was specified, so it is most likely a flag argValue = ValueConverter.ParseValue(descriptor.ArgumentType, null, currentValue); } else { // Parse value without the ':' argValue = ValueConverter.ParseValue(descriptor.ArgumentType, arg.Substring(endIndex + 1), currentValue); } // Set the value of the argument descriptor.PropertyInfo.SetValue(command, argValue, null); // We have processed this argument, so indicate this return(true); }