forked from dotnet/try
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCommandLineBuilderExtensions.cs
More file actions
141 lines (117 loc) · 4 KB
/
CommandLineBuilderExtensions.cs
File metadata and controls
141 lines (117 loc) · 4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// code adapted from https://github.com/dotnet/command-line-api/blob/166610c56ff732093f0145a2911d4f6c40b786da/src/System.CommandLine.DragonFruit/CommandLine.cs
using System;
using System.Collections.Generic;
using System.CommandLine;
using System.CommandLine.Binding;
using System.CommandLine.Builder;
using System.CommandLine.Invocation;
using System.Linq;
using System.Reflection;
using System.Threading;
namespace MLS.WasmCodeRunner
{
internal static class CommandLineBuilderExtensions
{
public static CommandLineBuilder ConfigureRootCommandFromMethod(
this CommandLineBuilder builder,
MethodInfo method)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
if (method == null)
{
throw new ArgumentNullException(nameof(method));
}
builder.Command.ConfigureFromMethod(method);
return builder;
}
private static readonly string[] _argumentParameterNames =
{
"arguments",
"argument",
"args"
};
public static void ConfigureFromMethod(
this Command command,
MethodInfo method)
{
if (command == null)
{
throw new ArgumentNullException(nameof(command));
}
if (method == null)
{
throw new ArgumentNullException(nameof(method));
}
foreach (var option in method.BuildOptions())
{
command.AddOption(option);
}
if (method.GetParameters()
.FirstOrDefault(p => _argumentParameterNames.Contains(p.Name)) is ParameterInfo argsParam)
{
command.Argument = new Argument
{
ArgumentType = argsParam.ParameterType,
Name = argsParam.Name
};
}
command.Handler = CommandHandler.Create(method);
}
public static IEnumerable<Option> BuildOptions(this MethodInfo type)
{
var descriptor = HandlerDescriptor.FromMethodInfo(type);
var omittedTypes = new[]
{
typeof(IConsole),
typeof(InvocationContext),
typeof(BindingContext),
typeof(ParseResult),
typeof(CancellationToken),
};
foreach (var option in descriptor.ParameterDescriptors
.Where(d => !omittedTypes.Contains(d.Type))
.Where(d => !_argumentParameterNames.Contains(d.Name))
.Select(p => p.BuildOption()))
{
yield return option;
}
}
public static Option BuildOption(this ParameterDescriptor parameter)
{
var argument = new Argument
{
ArgumentType = parameter.Type
};
if (parameter.HasDefaultValue)
{
argument.SetDefaultValue(parameter.GetDefaultValue);
}
var option = new Option(
parameter.BuildAlias(),
parameter.Name,
argument);
return option;
}
public static string BuildAlias(this IValueDescriptor descriptor)
{
if (descriptor == null)
{
throw new ArgumentNullException(nameof(descriptor));
}
return BuildAlias(descriptor.Name);
}
internal static string BuildAlias(string parameterName)
{
if (String.IsNullOrWhiteSpace(parameterName))
{
throw new ArgumentException("Value cannot be null or whitespace.", nameof(parameterName));
}
return parameterName.Length > 1
? $"--{parameterName.ToKebabCase()}"
: $"-{parameterName.ToLowerInvariant()}";
}
}
}