public object[] BuildMethodParameters(CommandRule commandRule) { if (!commandRule.IsValid) { throw new CommandRuleNotValidatedExption("Unable to build parameter array before command rule has been validated."); } if (commandRule.Method == null) { throw new NullReferenceException("Method property has not been initialiazed."); } var parameterValues = new List <object>(); var methodParameters = commandRule.Method.GetParameters(); //var stringToObject = new StringToObject(new ArrayParser()); for (int i = 0; i < commandRule.Command.RequiredParameters.Count; i++) { parameterValues.Add(_stringToObject.ConvertValue(commandRule.Command.RequiredParameters[i].Value, methodParameters[i].ParameterType)); } for (int i = 0; i < commandRule.Command.OptionalParameters.Count; i++) { parameterValues.Add(_stringToObject.ConvertValue(commandRule.Command.OptionalParameters[i].Value, methodParameters[i + commandRule.Command.RequiredParameters.Count].ParameterType)); } return(parameterValues.ToArray()); }
private void GetCommandRulesFromMethods(IEnumerable <MethodInfo> methods, object targetObject, List <CommandRule> commandRules) { foreach (MethodInfo method in methods) { var customAttributes = method.GetCustomAttributes(false); foreach (object customAttribute in customAttributes) { if (customAttribute is CommandAttribute) { CommandRule newCommandRule = GetCommandRule(method, targetObject); CommandRule existingCommandRule = commandRules.Find(rule => rule.Command.Name == newCommandRule.Command.Name); if (existingCommandRule != null) { throw new DuplicateCommandException("A duplicate command has been defined: " + newCommandRule.Command.Name); } commandRules.Add(newCommandRule); } } } }
/// <summary> Shows the command rule help. </summary> /// /// <remarks> trond, 2013-05-01. </remarks> /// /// <param name="commandRule"> The command rule. </param> /// <param name="includeParameters"> true to include, false to exclude the parameters. </param> /// <param name="applicationInfo"> Information describing the application. </param> private void ShowCommandRuleHelp(CommandRule commandRule, bool includeParameters, IApplicationInfo applicationInfo) { IValueConverter valueConverter = new ValueConverter(); StringBuilder helpString = new StringBuilder(); StringBuilder exampleString = new StringBuilder(); StringBuilder alternativeExampleString = new StringBuilder(); helpString.Append(FormatCommand(commandRule.Command.Name)); if (!includeParameters) { helpString.Append(FormatCommandDescription(commandRule.Command.Summary, _commandColumnWidth, MaxWidth - _commandColumnWidth)); } if (includeParameters) { helpString.Append(FormatCommandDescription(commandRule.Command.Description, _commandColumnWidth, MaxWidth - _commandColumnWidth)); if (Type.GetType("Mono.Runtime") != null) { exampleString.Append("mono "); } exampleString.Append(applicationInfo.ExeFileName + " "); exampleString.Append(commandRule.Command.Name + " "); alternativeExampleString.Append(exampleString); foreach (RequiredCommandParameter requiredCommandParameter in commandRule.Command.RequiredParameters) { helpString.Append(FormatCommandParameter("/" + requiredCommandParameter.Name)); helpString.Append(FormatCommandDescription(string.Format("[Required] {0} Alternative parameter name: /{1}", requiredCommandParameter.Description, requiredCommandParameter.AlternativeName), _commandColumnWidth, MaxWidth - _commandColumnWidth)); exampleString.Append(string.Format("/{0}=\"{1}\" ", requiredCommandParameter.Name, valueConverter.ObjectValue2String(requiredCommandParameter.ExampleValue))); if (!string.IsNullOrEmpty(requiredCommandParameter.AlternativeName)) { alternativeExampleString.Append(string.Format("/{0}=\"{1}\" ", requiredCommandParameter.AlternativeName, valueConverter.ObjectValue2String(requiredCommandParameter.ExampleValue))); } else { alternativeExampleString.Append(string.Format("/{0}=\"{1}\" ", requiredCommandParameter.Name, valueConverter.ObjectValue2String(requiredCommandParameter.ExampleValue))); } } foreach (OptionalCommandParameter optionalCommandParameter in commandRule.Command.OptionalParameters) { helpString.Append(FormatCommandParameter("/" + optionalCommandParameter.Name)); helpString.Append( FormatCommandDescription( string.Format("[Optional] {0} Alternative parameter name: /{1}. Default value: {2} ", optionalCommandParameter.Description, optionalCommandParameter.AlternativeName, valueConverter.ObjectValue2String(optionalCommandParameter.DefaultValue)), _commandColumnWidth, MaxWidth - _commandColumnWidth)); exampleString.Append(string.Format("/{0}=\"{1}\" ", optionalCommandParameter.Name, valueConverter.ObjectValue2String(optionalCommandParameter.ExampleValue))); if (!string.IsNullOrEmpty(optionalCommandParameter.AlternativeName)) { alternativeExampleString.Append(string.Format("/{0}=\"{1}\" ", optionalCommandParameter.AlternativeName, valueConverter.ObjectValue2String(optionalCommandParameter.ExampleValue))); } else { alternativeExampleString.Append(string.Format("/{0}=\"{1}\" ", optionalCommandParameter.Name, valueConverter.ObjectValue2String(optionalCommandParameter.ExampleValue))); } } helpString.Append(Environment.NewLine); helpString.Append("".PadLeft(3) + "Example: " + exampleString + Environment.NewLine); helpString.Append("".PadLeft(3) + "Example (alternative): " + alternativeExampleString + Environment.NewLine); helpString.Append(Environment.NewLine); helpString.Append(Environment.NewLine); } var messenger = _messengerFactory.Invoke(); messenger.Write(helpString.ToString()); }
/// <summary> Shows help. </summary> /// /// <remarks> trond, 2013-05-01. </remarks> /// /// <param name="commandRules"> The command rules. </param> /// <param name="helpForCommandRule"> The help for command rule. </param> /// <param name="applicationInfo"> Information describing the application. </param> public void ShowHelp(List <CommandRule> commandRules, CommandRule helpForCommandRule, IApplicationInfo applicationInfo) { var messenger = _messengerFactory.Invoke(); messenger.WriteLine("{0} {1} - {2}", applicationInfo.Name, applicationInfo.Version, applicationInfo.Description); messenger.WriteLine("{0}", applicationInfo.Copyright); if (!string.IsNullOrEmpty(applicationInfo.Authors)) { if (applicationInfo.Authors.Contains(",")) { messenger.WriteLine("Authors: {0}", applicationInfo.Authors); } else { messenger.WriteLine("Author: {0}", applicationInfo.Authors); } } messenger.WriteLine("Usage: {0} <command> [parameters]", applicationInfo.ExeFileName); messenger.WriteLine(string.Empty); _commandColumnWidth = CalculateCommandColumnWitdth(commandRules); if (helpForCommandRule != null) { ShowCommandRuleHelp(helpForCommandRule, true, applicationInfo); } else { messenger.WriteLine("Commands:"); messenger.WriteLine("---------"); ShowCommandRuleHelp( new CommandRule { Command = new Command { Description = "Display this help text", Name = "Help" } }, false, applicationInfo); ShowCommandRuleHelp( new CommandRule { Command = new Command { Description = "Display license", Name = "License" } }, false, applicationInfo); ShowCommandRuleHelp( new CommandRule { Command = new Command { Description = "Display credits", Name = "Credits" } }, false, applicationInfo); foreach (CommandRule commandRule in commandRules) { ShowCommandRuleHelp(commandRule, false, applicationInfo); } messenger.WriteLine(string.Empty); messenger.WriteLine("Commands and parameters:"); messenger.WriteLine("------------------------"); foreach (CommandRule commandRule in commandRules) { ShowCommandRuleHelp(commandRule, true, applicationInfo); } //_messenger.WriteLine(); } messenger.Show(); }
public CommandRule GetCommandRule(MethodInfo methodInfo, object targetObject) { if (methodInfo == null) { throw new ArgumentNullException("methodInfo"); } var customAttributes = methodInfo.GetCustomAttributes(false); CommandAttribute commandAttribute = null; foreach (var customAttribute in customAttributes) { if (customAttribute is CommandAttribute) { //if (!methodInfo.IsStatic)throw new CommandMehtodNotStaticException("Command method is not a static method: " + methodInfo.Name); commandAttribute = (CommandAttribute)customAttribute; } } if (commandAttribute == null) { throw new MissingCommandAttributeException("Method is not decorate with the [Command] attribute: " + methodInfo.Name); } CommandRule commandRule = new CommandRule(); commandRule.Method = methodInfo; commandRule.Instance = targetObject; commandRule.Command = new Command { Name = methodInfo.Name, Description = commandAttribute.Description, Summary = commandAttribute.Summary }; bool optionalParamterFound = false; foreach (ParameterInfo parameter in methodInfo.GetParameters()) { var attributes = parameter.GetCustomAttributes(typeof(CommandParameterAttribute), false).ToList(); if (attributes.Count == 0) { throw new MissingCommandParameterAttributeException( string.Format( "Command parameter attribute is not decorating the parameter '{0}' in the method '{1}'", parameter.Name, methodInfo.Name)); } if (attributes.Count > 1) { throw new DuplicateCommandParameterAttributeException( string.Format( "More than one command parameter attribute decorates the parameter '{0}' in the method '{1}'.", parameter.Name, methodInfo.Name)); } if (attributes[0] is OptionalCommandParameterAttribute) { optionalParamterFound = true; OptionalCommandParameterAttribute optionalCommandParameterAttribute = (OptionalCommandParameterAttribute)attributes[0]; commandRule.Command.OptionalParameters.Add( new OptionalCommandParameter(optionalCommandParameterAttribute.DefaultValue) { Name = parameter.Name, Description = optionalCommandParameterAttribute.Description, ExampleValue = optionalCommandParameterAttribute.ExampleValue, AlternativeName = optionalCommandParameterAttribute.AlternativeName }); } else if (attributes[0] is RequiredCommandParameterAttribute) { if (optionalParamterFound) { throw new RequiredParameterFoundAfterOptionalParameterExecption( string.Format( "Required parameter '{0}' in method '{1}' must be defined before any optional parameters.", parameter.Name, methodInfo.Name)); } RequiredCommandParameterAttribute requiredCommandParameterAttribute = (RequiredCommandParameterAttribute)attributes[0]; commandRule.Command.RequiredParameters.Add(new RequiredCommandParameter { Name = parameter.Name, Description = requiredCommandParameterAttribute.Description, ExampleValue = requiredCommandParameterAttribute.ExampleValue, AlternativeName = requiredCommandParameterAttribute.AlternativeName }); } } return(commandRule); }
public int Run(List <CommandRule> commandRules, string[] args) { var applicationInfo = _applicationInfoFactory.Invoke(); var helpProvider = _helpProviderFactory.Invoke(); if (args.Length == 0) { helpProvider.ShowHelp(commandRules, null, applicationInfo); throw new MissingCommandException("Command not specified."); } string commandName = args[0]; if (helpProvider.IsHelpRequested(commandName)) { CommandRule helpForCommandRule = null; if (args.Length > 1) { string helpForCommandName = args[1]; helpForCommandRule = commandRules.Find(rule => rule.Command.Name == helpForCommandName); } helpProvider.ShowHelp(commandRules, helpForCommandRule, applicationInfo); return(0); } if (helpProvider.IsLicenseRequested(commandName)) { helpProvider.ShowLicense(applicationInfo); return(0); } if (helpProvider.IsCreditsRequested(commandName)) { helpProvider.ShowCredits(applicationInfo); return(0); } CommandRule commandRule = commandRules.Find(rule => rule.Command.Name == commandName); if (commandRule == null) { throw new UnknownCommandException("Unknown command: " + commandName); } _commandRuleValidator.Validate(args, commandRule); object[] parameterArrray = _methodParameterBuilder.BuildMethodParameters(commandRule); try { object returnValue = commandRule.Method.Invoke(commandRule.Instance, parameterArrray); if (returnValue is int) { return((int)returnValue); } return(0); } catch (TargetInvocationException ex) { if (ex.InnerException != null) { var innerException = ex.InnerException; //var preparedException = ex.InnerException.PrepForRemoting(); //throw preparedException; //MethodInfo prepForRemoting = typeof(Exception).GetMethodEx("PrepForRemoting", BindingFlags.NonPublic | BindingFlags.Instance); //if (prepForRemoting != null) //{ // //Preserve stack trace before re-throwing inner exception // prepForRemoting.Invoke(ex.InnerException, new object[0]); // throw ex.InnerException; //} innerException.PrepForRemotingAndThrow(); //var prepForRemoting = typeof(Exception).GetMethodEx("PrepForRemoting", BindingFlags.NonPublic | BindingFlags.Instance); //if (prepForRemoting != null) //{ // prepForRemoting.Invoke(innerException, new object[0]); // throw innerException; //} //else //{ // var exceptionDispatchInfo = ExceptionDispatchInfo.Capture(innerException); // exceptionDispatchInfo.Throw(); //} } throw; } }
public void Validate(string[] args, CommandRule commandRule) { if (args == null) { throw new ArgumentNullException(nameof(args)); } if (commandRule == null) { throw new ArgumentNullException(nameof(commandRule)); } if (commandRule.Command == null) { throw new NullReferenceException("Command object has not been initialized."); } if (args.Length == 0) { throw new MissingCommandException("No command was specified."); } string command = args[0]; if (commandRule.Command.Name.ToLower() != command.ToLower()) { throw new InvalidCommandException("Invalid command: " + command + ". Valid command is: " + commandRule.Command.Name); } if (!(commandRule.Command.RequiredParameters.Count == 0 && commandRule.Command.OptionalParameters.Count == 0)) { Dictionary <string, CommandLineParameter> commandLineParameters = new ArgumentsParser().GetCommandLineParameters(args); Dictionary <string, CommandParameter> validCommandParameters = GetValidCommandParameters(commandRule.Command); foreach (string commandLineParameterName in commandLineParameters.Keys) { if (!validCommandParameters.ContainsKey(commandLineParameterName)) { throw new InvalidCommandParameterException("Invalid command line parameter: " + commandLineParameterName); } } foreach (RequiredCommandParameter requiredParameter in commandRule.Command.RequiredParameters) { bool commandLineHasParameterName = commandLineParameters.ContainsKey(requiredParameter.ToString()); bool commandLineHasAlternativeParameterName = !(string.IsNullOrEmpty(requiredParameter.AlternativeName)) && commandLineParameters.ContainsKey(requiredParameter.AlternativeName); if ( !commandLineHasParameterName && !commandLineHasAlternativeParameterName ) { throw new MissingCommandParameterException("Required parameter is missing: " + requiredParameter.Name); } if (commandLineHasParameterName) { requiredParameter.Value = commandLineParameters[requiredParameter.ToString()].Value; } else if (commandLineHasAlternativeParameterName) { requiredParameter.Value = commandLineParameters[requiredParameter.AlternativeName].Value; } //Check if example value has been specified if (requiredParameter.ExampleValue == null) { throw new MissingExampleValueException( string.Format("Example vaue has not been specified for parameter '{0}' in command '{1}'", requiredParameter, commandRule.Command.Name)); } } foreach (OptionalCommandParameter optionaParameter in commandRule.Command.OptionalParameters) { if (commandLineParameters.ContainsKey(optionaParameter.ToString())) { optionaParameter.Value = commandLineParameters[optionaParameter.ToString()].Value; } else if (!(string.IsNullOrEmpty(optionaParameter.AlternativeName)) && commandLineParameters.ContainsKey(optionaParameter.AlternativeName)) { optionaParameter.Value = commandLineParameters[optionaParameter.AlternativeName].Value; } if (optionaParameter.Value == null) { throw new MissingCommandParameterException("Optional parameter does not have a value: " + optionaParameter.Name); } //Check if example value has been specified if (optionaParameter.ExampleValue == null) { throw new MissingExampleValueException( string.Format("Example vaue has not been specified for parameter '{0}' in command '{1}'", optionaParameter, commandRule.Command.Name)); } } } commandRule.IsValid = true; }