static string[] MergeArgs <T>(string[] passedArgs) { var optionAlias = GetOptions <T>(); var envArgsDict = GetEnvironmentValues(optionAlias); var passedArgsDict = GetArguments(passedArgs, optionAlias); var configFileOptionAlias = new OptionAlias(BaseSettings.ConfigFileArgName, ""); var configFilePath = ""; var configFileArgsDict = new Dictionary <OptionAlias, string>(); if (passedArgsDict.TryGetValue(configFileOptionAlias, out configFilePath) || envArgsDict.TryGetValue(configFileOptionAlias, out configFilePath)) { configFileArgsDict = GetConfigValues(configFilePath, optionAlias); } //override config by env variables var merged = OverrideValues(configFileArgsDict, envArgsDict); //override config and env variables by passed arguments merged = OverrideValues(passedArgsDict, merged); return(merged .SelectMany(a => new string[] { a.Key.FullArgumentName, a.Value }) .Where(a => a != null) .ToArray()); }
static bool TryGetVerb <T>(out OptionAlias alias) { alias = default; var type = typeof(T); if (type.IsDefined(typeof(VerbAttribute), false)) { var verb = (VerbAttribute)type.GetCustomAttributes(typeof(VerbAttribute), true).First(); alias = new OptionAlias(verb.Name, "", true); return(true); } return(false); }
public override bool Equals(object obj) { if (obj == null) { return(false); } if (obj.GetType() != GetType()) { return(false); } OptionAlias other = (OptionAlias)obj; return(other.LongName == LongName && other.ShortName == ShortName); }
static Dictionary <OptionAlias, string> GetArguments(string[] args, List <OptionAlias> options) { var data = new Dictionary <OptionAlias, string>(); var i = 0; while (i < args.Length) { var currentArg = args[i]; if (!IsArgumentName(currentArg) && i != 0) // first arg should be verb (alpha or auditor) { throw new Exception("Invalid arguments format"); } //trim dash after check currentArg = currentArg.TrimStart('-'); var currentOption = options.FirstOrDefault(x => x.LongName == currentArg || x.ShortName == currentArg); //create new option if not found if (currentOption.Equals(default(OptionAlias))) { currentOption = new OptionAlias(currentArg, "", i == 0); // first arg should be verb } string currentArgValue = null; //check if next argument exists if (i + 1 < args.Length) { //check if next argument is current argument value var nextArgument = args[i + 1]; if (!IsArgumentName(nextArgument)) { currentArgValue = nextArgument; //we already processed the value i++; } } data.Add(currentOption, currentArgValue); i++; } return(data); }
/// <summary> /// Generates a signature for a single option alias /// </summary> /// <param name="option"> /// Option to create a partial signature for /// </param> /// <param name="alias">Particular option alias</param> /// <returns>Signature for a single option alias</returns> private string GeneratePartialOptionSignature( Option option, OptionAlias alias) { return alias + GenerateOptionArgument( option, alias.Type ); }
/// <summary> /// Parse and process short option argument /// </summary> /// <param name="optionAlias">Option alias.</param> /// <param name="option">Option.</param> private void ProcessShortOptionArgument( OptionAlias optionAlias, Option option) { // Remove processed option from arguments list Args.Dequeue(); if ( option.Argument == null ) { // No argument specified for the Option return; } var stringValue = Args.Any() ? Args.First() : ""; // An argument is expected and its value is set dynamic value = null; string exceptionMessage = null; try { if ( stringValue.Length == 0 ) { throw new ArgumentNullException(); } value = option.Argument .Parse( stringValue, Converter ); option.Argument.AssertConditions( value ); } catch ( ArgumentNullException ) { // Argument is mandatory and no value is provided exceptionMessage = "No option value specified for option {0}"; } catch ( ArgumentOutOfRangeException ) { // Value does not satisfy Argument Conditions exceptionMessage = "Value for option {0} does not meet conditions"; } catch ( Exception ) { // Value cannot be converted to specified format exceptionMessage = "Value for option {0} is not of required type"; } if ( exceptionMessage != null ) { if ( option.Argument.DefaultValueIsSet ) { // Provided value is not valid and a default value exists value = option.Argument.DefaultValue; } else if ( !option.Argument.Optional ) { // Provided value is not valid and it is mandatory throw new ParseException( exceptionMessage, optionAlias.ToString() ); } } else { // Remove correct Option argument from the argument list Args.Dequeue(); } option.Argument.InvokeActions( value ); SetCommandLineOptionValue( option, value ); }
/// <summary> /// Parse and process long option argument. /// </summary> /// <param name="optionAlias">Option alias.</param> /// <param name="option">Option.</param> private void ProcessLongOptionArgument( OptionAlias optionAlias, Option option) { var stringValue = ExtractLongOptionValue( Args.First() ); if ( stringValue.Length > 0 && option.Argument == null ) { // There is an Option value present, but it should not be there throw new ParseException( "Unexpected long option value: {0}", Args.First() ); } if ( stringValue.Length == 0 && option.Argument != null ) { // An argument or default value is expected if ( !option.Argument.Optional ) { // Argument is mandatory and no value is provided throw new ParseException( "No option value specified for option {0}", Args.First() ); } option.Argument.InvokeActions( option.Argument.DefaultValue ); SetCommandLineOptionValue( option, option.Argument.DefaultValue ); } else if ( stringValue.Length > 0 && option.Argument != null ) { // An argument is expected and its value is set dynamic value; try { value = option.Argument .Parse( stringValue, Converter ); option.Argument.AssertConditions( value ); } catch ( ArgumentOutOfRangeException ) { // Value does not satisfy Argument Conditions throw new ParseException( "Value for option {0} does not meet conditions", optionAlias.ToString() ); } catch ( Exception ) { // Value cannot be converted to specified format throw new ParseException( "Value for option {0} is not of required type", optionAlias.ToString() ); } option.Argument.InvokeActions( value ); SetCommandLineOptionValue( option, value ); } // Remove processed option from arguments list Args.Dequeue(); }
/// <summary> /// Processes detected Option, i.e. invokes user specified callbacks /// and checks potential Option arguments /// </summary> /// <param name="optionAlias">Option specified by its alias</param> private void ProcessDetectedOption( OptionAlias optionAlias ) { // locate corresponding Option var option = Options[ optionAlias ]; // set default value to null SetCommandLineOptionIsSet( option ); // invoke user callbacks option.InvokeActions(); if ( optionAlias.Type == OptionType.Long ) { ProcessLongOptionArgument( optionAlias, option ); } else { ProcessShortOptionArgument( optionAlias, option ); } }