private void WriteParameters(InputCommandDef def) { base.Out.Standard.WriteLine(); base.Out.Standard.WriteLine("PARAMETERS"); foreach (var param in def.Parameters) { base.Out.Standard.WriteLine(); // write name base.Out.Standard.WriteLine(string.Format("{0}{1}", TAB, param.Name)); // write attributes base.Out.Standard.WriteLine(); WriteAttribute("Synopsis:", param.Synopsis); WriteAttribute("Aliases:", param.Aliases.Count() == 0 ? string.Empty : string.Join(", ", param.Aliases)); WriteAttribute("IsRequired:", param.IsRequired); WriteAttribute("OrdinalPosition:", param.OrdinalPosition < 1 ? string.Empty : param.OrdinalPosition.ToString()); WriteAttribute("ParameterSet:", param.ParameterSet); WriteAttribute("AutoComplete:", string.IsNullOrWhiteSpace(param.AutoCompleteValuesFunction)); } }
private static void ValidateAutoCompleteFunctions(InputCommandDef def) { foreach (var param in def.Parameters) { if (param.AutoCompleteValuesFunction != null) { if (def.InputCommandType.GetMethod(param.AutoCompleteValuesFunction) == null) { throw new InvalidCommandException(def.InputCommandType , string.Format("The parameter '{0}' for command {1} defines an auto complete values function '{2}' which cannot be found" , param.Name, def.InputCommandType, param.AutoCompleteValuesFunction)); } else { var methodInfo = def.InputCommandType.GetMethod(param.AutoCompleteValuesFunction); var parameters = methodInfo.GetParameters(); if (parameters.Count() != 1 && parameters[0].ParameterType != typeof(AutoCompleteValuesFunctionContext)) { throw new InvalidCommandException(def.InputCommandType , string.Format("The parameter '{0}' for command {1} must define an auto complete values function {2} which defines a single input parameter of type {3}" , param.Name, def.InputCommandType, param.AutoCompleteValuesFunction, typeof(AutoCompleteValuesFunctionContext).FullName)); } } } else if (param.UseAutoCompleteForValidation) { throw new InvalidCommandException(def.InputCommandType , string.Format("The parameter '{0}' specifies that the auto complete function should be used for validation, but no auto complete function could be found" , param.Name)); } } }
public static void Validate(InputCommandDef def) { ValidateAliases(def); ValidateParameterSets(def); ValidateAutoCompleteFunctions(def); ValidateValidationFunctions(def); ValidateParameterTypes(def); }
/// <summary> /// Returns an <typeparamref name="BitPantry.Console.API.InputCommandInfo" object/> /// </summary> /// <param name="inputCommandType">The type to define</param> /// <returns>Returns an <typeparamref name="BitPantry.Console.API.InputCommandInfo" object. Or NULL if the type is not an Input Command</returns> public static InputCommandDef DescribeInputCommand(this Type inputCommandType) { // check base type if (!inputCommandType.IsSubclassOf(typeof(InputCommand))) { throw new ArgumentException(string.Format("The input command {0} does not extend {1}" , inputCommandType.FullName, typeof(InputCommand).FullName)); } // check for command attribute Command commandAttr = GetAttributes <Command>(inputCommandType).FirstOrDefault(); if (commandAttr == null) { throw new ArgumentException(string.Format("The input command {0} does not have the {1} attribute" , inputCommandType.FullName, typeof(Command).FullName)); } // return if already cached if (!definitionCache.Keys.Any(k => k.Equals(inputCommandType))) { // initialize info for new InputCommandDef info = new InputCommandDef(); info.InputCommandType = inputCommandType; info.CommandName = commandAttr.Name ?? inputCommandType.Name; info.DefaultParameterSet = commandAttr.DefaultParameterSet; // parse aliases info.AddAliases(GetAttributes <Alias>(inputCommandType).Select(a => a.Value)); // parse parameter definitions info.Add(GetParameterDefinitions(inputCommandType)); // parse switches info.Add(GetSwitchDefinitions(inputCommandType)); // parse synopsis Synopsis synopsisAttribute = GetAttributes <Synopsis>(inputCommandType).FirstOrDefault(); info.Synopsis = synopsisAttribute == null ? null : synopsisAttribute.Value; CommandValidator.Validate(info); // cache new definition definitionCache.Add(inputCommandType, info); } return(definitionCache[inputCommandType]); }
private static void ValidateParameterTypes(InputCommandDef def) { foreach (var param in def.Parameters) { if (param.PropertyInfo.PropertyType != typeof(string) && StringParsing.GetParser(param.PropertyInfo.PropertyType) == null) { throw new InvalidCommandException(def.InputCommandType , string.Format("The parameter '{0}' for command {1} has a property type of {2}. There are no available property input TypeParsers available for that type." , param.Name, def.InputCommandType, param.PropertyInfo.PropertyType)); } } }
private void WriteSyntax(InputCommandDef def) { base.Out.Standard.WriteLine(); base.Out.Standard.WriteLine("SYNTAX"); if (!string.IsNullOrWhiteSpace(def.DefaultParameterSet)) { var noSetParameters = def.Parameters.Where(p => string.IsNullOrWhiteSpace(p.ParameterSet)); foreach (var parameterSet in def.Parameters.Where(p => !string.IsNullOrWhiteSpace(p.ParameterSet)).Select(p => p.ParameterSet).Distinct()) { base.Out.Standard.WriteLine(); base.Out.Standard.WriteLine("{0}For parameter set '{1}':", TAB, parameterSet); StringBuilder sb = new StringBuilder(); sb.AppendFormat("{0} ", def.CommandName); foreach (var param in def.Parameters.Where(p => !string.IsNullOrWhiteSpace(p.ParameterSet) && p.ParameterSet.Equals(parameterSet)).Union(noSetParameters)) { sb.AppendFormat("-{0} <value> ", param.Name); } foreach (var param in def.Switches) { sb.AppendFormat("/{0} ", param.Name); } base.Out.Standard.WriteLine(); base.Out.Standard.WriteLine(string.Format("{0}{1}{2}", TAB, TAB, sb.ToString())); } } else { StringBuilder sb = new StringBuilder(); sb.AppendFormat("{0} ", def.CommandName); foreach (var param in def.Parameters) { sb.AppendFormat("-{0} <value> ", param.Name); } foreach (var param in def.Switches) { sb.AppendFormat("/{0} ", param.Name); } base.Out.Standard.WriteLine(string.Format("{0}{1}", TAB, sb.ToString())); } }
private static void ValidateParameterSets(InputCommandDef info) { var usedParameterSets = info.Parameters.Where(p => !string.IsNullOrEmpty(p.ParameterSet)).Select(p => p.ParameterSet).Distinct().ToList(); if (usedParameterSets.Count > 0 && string.IsNullOrEmpty(info.DefaultParameterSet)) { throw new InvalidCommandException(info.InputCommandType , string.Format("The input command {0} has parameters that define parameter sets, but a default parameter set is not defined", info.InputCommandType.FullName)); } if (!string.IsNullOrEmpty(info.DefaultParameterSet) && !usedParameterSets.Contains(info.DefaultParameterSet)) { throw new InvalidCommandException(info.InputCommandType , string.Format("The input command {0} defines a default parameter set, but no parameters are in the defined set" , info.InputCommandType.FullName)); } }
private static void ValidateAliases(InputCommandDef def) { // validate parameters List <string> uniqueParameterNames = new List <string>(); foreach (var param in def.Parameters) { if (uniqueParameterNames.Contains(param.Name, StringComparer.OrdinalIgnoreCase)) { throw new InvalidCommandException(def.InputCommandType , string.Format("The command {0} contains a duplicate parameter name or alias '{1}'", param.Name)); } uniqueParameterNames.Add(param.Name); foreach (var alias in param.Aliases) { if (uniqueParameterNames.Contains(alias, StringComparer.OrdinalIgnoreCase)) { throw new InvalidCommandException(def.InputCommandType , string.Format("The command {0} contains a duplicate parameter name or alias '{1}'", param.Name)); } uniqueParameterNames.Add(alias); } } // validate command aliases List <string> commandNames = new List <string>(); commandNames.Add(def.CommandName); foreach (var alias in def.Aliases) { if (commandNames.Contains(alias, StringComparer.OrdinalIgnoreCase)) { throw new InvalidCommandException(def.InputCommandType , string.Format("The command {0} contains a duplicate command name or alias '{1}'", alias)); } } }
private void WriteSwitches(InputCommandDef def) { base.Out.Standard.WriteLine(); base.Out.Standard.WriteLine("SWITCHES"); foreach (var item in def.Switches) { base.Out.Standard.WriteLine(); // write name base.Out.Standard.WriteLine(string.Format("{0}{1}", TAB, item.Name)); // write attributes base.Out.Standard.WriteLine(); WriteAttribute("Synopsis:", item.Synopsis); WriteAttribute("Aliases:", item.Aliases.Count() == 0 ? string.Empty : string.Join(", ", item.Aliases)); } }
private void WriteHeaderHelp(InputCommandDef def) { // write command name base.Out.Standard.WriteLine(); base.Out.Standard.WriteLine("NAME"); base.Out.Standard.WriteLine(string.Format("{0}{1}", TAB, def.CommandName)); // write synopsis if (!string.IsNullOrWhiteSpace(def.Synopsis)) { base.Out.Standard.WriteLine(); base.Out.Standard.WriteLine("SYNOPSIS"); base.Out.Standard.WriteLine(string.Format("{0}{1}", TAB, def.Synopsis)); } // write module var module = base.Host.Modules.Where(m => m.CommandTypes.Contains(def.InputCommandType)).FirstOrDefault(); if (module != null) { base.Out.Standard.WriteLine(); base.Out.Standard.WriteLine("MODULE"); base.Out.Standard.WriteLine(string.Format("{0}{1}", TAB, module.Name)); } // write aliases if (def.Aliases.Count() > 0) { base.Out.Standard.WriteLine(); base.Out.Standard.WriteLine("ALIASES"); base.Out.Standard.WriteLine(string.Format("{0}{1}", TAB, string.Join(", ", def.Aliases))); } }