in wwauth/Google.Solutions.WWAuth/Util/CommandLineParser.cs [48:111]
private static IEnumerable<PropertyInfo> GetSupportedProperties<TOptions>()
=> typeof(TOptions)
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.Where(p => p.CustomAttributes
.EnsureNotNull()
.Any(a => a.AttributeType == typeof(CommandLineArgumentAttribute)))
.Where(p => p.PropertyType.IsEnum || p.PropertyType == typeof(string));
public static TOptions Parse<TOptions>(string commandLine)
where TOptions : class, ICommandLineOptions, new()
{
var commandLineParts = commandLine
.SplitQuotedString(' ')
.Select(arg => arg.Trim())
.Where(arg => !string.IsNullOrWhiteSpace(arg));
var options = new TOptions()
{
Executable = commandLineParts.FirstOrDefault()
};
var arguments = commandLineParts
.Skip(1) // Ignore the executable path
.ToList();
if ((arguments.Count % 2) != 0)
{
throw new ArgumentException(
"Command line contains too many options");
}
var properties = GetSupportedProperties<TOptions>();
for (int i = 0; i < arguments.Count / 2; i++)
{
var key = arguments[i * 2];
var value = arguments[i * 2 + 1];
if (!key.StartsWith("/"))
{
throw new ArgumentException(
"Unrecognized command line option: " + key);
}
var property = properties.FirstOrDefault(
p => p.Name.Equals(key.Substring(1), StringComparison.OrdinalIgnoreCase));
if (property == null)
{
throw new ArgumentException(
"Unrecognized command line option: " + key);
}
if (property.PropertyType.IsEnum)
{
property.SetValue(options, Enum.Parse(property.PropertyType, value));
}
else
{
property.SetValue(options, value);
}
}
return options;
}