Last active
August 3, 2016 11:33
-
-
Save robertkruis/82b794ded5d16a390d89eb2071035388 to your computer and use it in GitHub Desktop.
CommandLine: Display help text without ParseArguments call using reflection
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Options | |
{ | |
[Option('i', "install", | |
HelpText = "Installs the given packages into the project.")] | |
public IEnumerable<string> Packages { get; set; } | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
static class ParserResultExtensions | |
{ | |
/// <summary> | |
/// Gets the AutoBuild help text from the result. | |
/// </summary> | |
/// <typeparam name="T">The type of options</typeparam> | |
/// <returns>The AutoBuild help text in its string representation, or an empty string.</returns> | |
public static string GetAutoBuildHelpText<T>(this ParserResult<T> result) | |
{ | |
var typeInfo = GetTypeInfoInstance<T>(); | |
if (typeInfo != null) | |
{ | |
var notParsed = GetNotParsedInstanceAs<T>(typeInfo, Enumerable.Empty<Error>()); | |
if (notParsed != null) | |
{ | |
return HelpText | |
.AutoBuild(notParsed) | |
.ToString(); | |
} | |
} | |
return string.Empty; | |
} | |
private static object GetTypeInfoInstance<T>() | |
{ | |
return Type | |
.GetType($"{CommandLineTypeInfoTypeName},{CommandLineAssembly}") | |
?.GetMethod(CommandLineTypeInfoCreateMethodName, CommandLineTypeInfoCreateArgumentTypes) | |
?.Invoke(null, new object[] { typeof(T) }); | |
} | |
private static ParserResult<T> GetNotParsedInstanceAs<T>(object typeInfo, IEnumerable<Error> errors) | |
{ | |
return Type | |
.GetType($"{CommandLineNotParsedTypeName},{CommandLineAssembly}") | |
?.MakeGenericType(typeof(T)) | |
?.GetTypeInfo() | |
?.DeclaredConstructors | |
?.First() | |
?.Invoke(new object[] { typeInfo, errors }) as ParserResult<T>; | |
} | |
private const string CommandLineAssembly = "CommandLine"; | |
private const string CommandLineTypeInfoTypeName = "CommandLine.TypeInfo"; | |
private const string CommandLineNotParsedTypeName = "CommandLine.NotParsed`1"; | |
private const string CommandLineTypeInfoCreateMethodName = "Create"; | |
private static readonly Type[] CommandLineTypeInfoCreateArgumentTypes = new Type[] { typeof(Type) }; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
enum ExitCode : int | |
{ | |
Standard = 0, | |
Error = 1 | |
} | |
class Program | |
{ | |
static int Main(string[] args) | |
{ | |
var result = CommandLine.Parser.Default.ParseArguments<Options>(args); | |
var exitCode = result.MapResult( | |
options => | |
{ | |
if (options.Packages.Count() == 0) | |
{ | |
Console.WriteLine(result.GetAutoBuildHelpText()); | |
return (int)ExitCode.Error; | |
} | |
return (int)ExitCode.Standard; | |
}, | |
errors => | |
{ | |
return (int)ExitCode.Error; | |
} | |
); | |
return exitCode; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment