Skip to content

Commit 3a307a9

Browse files
committed
wip
1 parent ee3100e commit 3a307a9

17 files changed

+87
-152
lines changed

src/Common/ArgumentBuilder.cs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
2+
using System;
3+
using System.CommandLine;
4+
using System.Reflection;
5+
6+
internal static class ArgumentBuilder
7+
{
8+
private static readonly ConstructorInfo _ctor;
9+
10+
static ArgumentBuilder()
11+
{
12+
_ctor = typeof(Argument<string>).GetConstructor(new[] { typeof(string), typeof(string) });
13+
}
14+
15+
public static Argument CreateArgument(Type valueType, string name = "value")
16+
{
17+
var argumentType = typeof(Argument<>).MakeGenericType(valueType);
18+
19+
#if NET6_0_OR_GREATER
20+
var ctor = (ConstructorInfo)argumentType.GetMemberWithSameMetadataDefinitionAs(_ctor);
21+
#else
22+
var ctor = argumentType.GetConstructor(new[] { typeof(string), typeof(string) });
23+
#endif
24+
25+
var option = (Argument)ctor.Invoke(new object[] { name, null });
26+
27+
return option;
28+
}
29+
}

src/Common/OptionBuilder.cs

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,30 +3,29 @@
33

44
using System.Reflection;
55

6-
namespace System.CommandLine.Utility
6+
namespace System.CommandLine.Utility;
7+
8+
internal static class OptionBuilder
79
{
8-
internal static class OptionBuilder
9-
{
10-
private static readonly ConstructorInfo _ctor;
10+
private static readonly ConstructorInfo _ctor;
1111

12-
static OptionBuilder()
13-
{
14-
_ctor = typeof(Option<string>).GetConstructor(new[] { typeof(string), typeof(string) });
15-
}
12+
static OptionBuilder()
13+
{
14+
_ctor = typeof(Option<string>).GetConstructor(new[] { typeof(string), typeof(string) });
15+
}
1616

17-
public static Option CreateOption(string name, Type valueType)
18-
{
19-
var optionType = typeof(Option<>).MakeGenericType(valueType);
17+
public static Option CreateOption(string name, Type valueType)
18+
{
19+
var optionType = typeof(Option<>).MakeGenericType(valueType);
2020

2121
#if NET6_0_OR_GREATER
2222
var ctor = (ConstructorInfo)optionType.GetMemberWithSameMetadataDefinitionAs(_ctor);
2323
#else
24-
var ctor = optionType.GetConstructor(new[] { typeof(string), typeof(string) });
24+
var ctor = optionType.GetConstructor(new[] { typeof(string), typeof(string) });
2525
#endif
2626

27-
var option = (Option)ctor.Invoke(new object[] { name, null });
27+
var option = (Option)ctor.Invoke(new object[] { name, null });
2828

29-
return option;
30-
}
29+
return option;
3130
}
3231
}

src/System.CommandLine.DragonFruit/CommandLine.cs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -164,18 +164,13 @@ public static void ConfigureFromMethod(
164164
command.AddOption(option);
165165
}
166166

167-
if (method.GetParameters()
168-
.FirstOrDefault(p => _argumentParameterNames.Contains(p.Name)) is ParameterInfo argsParam)
167+
if (method.GetParameters().FirstOrDefault(p => _argumentParameterNames.Contains(p.Name)) is { } argsParam)
169168
{
170-
var argument = new Argument
171-
{
172-
ValueType = argsParam.ParameterType,
173-
Name = argsParam.Name
174-
};
169+
var argument = ArgumentBuilder.CreateArgument(argsParam.ParameterType, argsParam.Name);
175170

176171
if (argsParam.HasDefaultValue)
177172
{
178-
if (argsParam.DefaultValue != null)
173+
if (argsParam.DefaultValue is not null)
179174
{
180175
argument.SetDefaultValue(argsParam.DefaultValue);
181176
}

src/System.CommandLine.DragonFruit/System.CommandLine.DragonFruit.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
</ItemGroup>
1515

1616
<ItemGroup>
17+
<Compile Include="..\Common\ArgumentBuilder.cs" Link="Utility\ArgumentBuilder.cs" />
1718
<Compile Include="..\Common\OptionBuilder.cs" Link="Utility\OptionBuilder.cs" />
1819
</ItemGroup>
1920
</Project>

src/System.CommandLine.NamingConventionBinder.Tests/ModelBinderTests.cs

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,7 @@ public void Command_arguments_are_bound_by_name_to_constructor_parameters(
5858

5959
var command = new Command("the-command")
6060
{
61-
new Argument
62-
{
63-
Name = "value",
64-
ValueType = type
65-
}
61+
ArgumentBuilder.CreateArgument(type)
6662
};
6763

6864
var bindingContext = new InvocationContext(command.Parse(commandLine)).BindingContext;
@@ -85,11 +81,7 @@ public void Command_arguments_are_bound_by_name_to_complex_constructor_parameter
8581

8682
var command = new Command("the-command")
8783
{
88-
new Argument
89-
{
90-
Name = "value",
91-
ValueType = type
92-
}
84+
ArgumentBuilder.CreateArgument(type)
9385
};
9486

9587
var bindingContext = new InvocationContext(command.Parse(commandLine)).BindingContext;
@@ -164,11 +156,7 @@ public void Command_arguments_are_bound_by_name_to_property_setters(
164156

165157
var command = new Command("the-command")
166158
{
167-
new Argument
168-
{
169-
Name = "value",
170-
ValueType = type
171-
}
159+
ArgumentBuilder.CreateArgument(type)
172160
};
173161
var parser = new Parser(command);
174162

src/System.CommandLine.NamingConventionBinder.Tests/ModelBindingCommandHandlerTests.BindingByName.cs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -127,11 +127,7 @@ public async Task Command_arguments_are_bound_by_name_to_handler_method_paramete
127127

128128
var command = new Command("the-command")
129129
{
130-
new Argument
131-
{
132-
Name = "value",
133-
ValueType = type
134-
}
130+
ArgumentBuilder.CreateArgument(type)
135131
};
136132

137133
var console = new TestConsole();

src/System.CommandLine.NamingConventionBinder.Tests/ModelBindingCommandHandlerTests.cs

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -165,8 +165,7 @@ public async Task When_binding_fails_due_to_parameter_naming_mismatch_then_handl
165165
[InlineData(typeof(List<string>))]
166166
[InlineData(typeof(int[]))]
167167
[InlineData(typeof(List<int>))]
168-
public async Task Handler_method_receives_command_arguments_bound_to_the_specified_type(
169-
Type type)
168+
public async Task Handler_method_receives_command_arguments_bound_to_the_specified_type(Type type)
170169
{
171170
var testCase = BindingCases[type];
172171

@@ -176,14 +175,9 @@ public async Task Handler_method_receives_command_arguments_bound_to_the_specifi
176175

177176
var handler = CommandHandler.Create(captureMethod);
178177

179-
var command = new Command(
180-
"command")
178+
var command = new Command("command")
181179
{
182-
new Argument
183-
{
184-
Name = "value",
185-
ValueType = testCase.ParameterType
186-
}
180+
ArgumentBuilder.CreateArgument(type)
187181
};
188182
command.Handler = handler;
189183

@@ -226,14 +220,9 @@ public async Task Handler_method_receives_command_arguments_explicitly_bound_to_
226220

227221
var handler = CommandHandler.Create(captureMethod);
228222

229-
var argument = new Argument
230-
{
231-
Name = "value",
232-
ValueType = testCase.ParameterType
233-
};
223+
var argument = ArgumentBuilder.CreateArgument(testCase.ParameterType, "value");
234224

235-
var command = new Command(
236-
"command")
225+
var command = new Command("command")
237226
{
238227
argument
239228
};

src/System.CommandLine.NamingConventionBinder.Tests/System.CommandLine.NamingConventionBinder.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
</ItemGroup>
1515

1616
<ItemGroup>
17+
<Compile Include="..\Common\ArgumentBuilder.cs" Link="Utility\ArgumentBuilder.cs" />
1718
<Compile Include="..\Common\OptionBuilder.cs" Link="Utility\OptionBuilder.cs" />
1819
<Compile Include="..\System.CommandLine.Tests\Binding\TestModels.cs" Link="TestModels.cs" />
1920
<Compile Include="..\System.CommandLine.Tests\Utility\AssertionExtensions.cs" Link="Utility\AssertionExtensions.cs" />

src/System.CommandLine.Tests/ArgumentTests.cs

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -56,26 +56,6 @@ public void When_there_is_no_default_value_then_GetDefaultValue_throws()
5656
.Be("Argument \"the-arg\" does not have a default value");
5757
}
5858

59-
[Fact]
60-
public void When_argument_type_is_set_to_null_then_it_throws()
61-
{
62-
var argument = new Argument();
63-
64-
argument.Invoking(a => a.ValueType = null)
65-
.Should()
66-
.Throw<ArgumentNullException>();
67-
}
68-
69-
[Fact]
70-
public void By_default_the_argument_type_is_string()
71-
{
72-
var argument = new Argument();
73-
74-
argument.ValueType
75-
.Should()
76-
.Be(typeof(string));
77-
}
78-
7959
public class CustomParsing
8060
{
8161
[Fact]

src/System.CommandLine.Tests/Binding/TypeConversionTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ public void Command_Argument_defaults_arity_to_ZeroOrOne_for_nullable_types()
113113
[InlineData(typeof(List<int>))]
114114
public void Argument_infers_arity_of_IEnumerable_types_as_OneOrMore(Type type)
115115
{
116-
var argument = new Argument { ValueType = type };
116+
var argument = ArgumentBuilder.CreateArgument(type);
117117

118118
argument.Arity.Should().BeEquivalentTo(ArgumentArity.OneOrMore);
119119
}

src/System.CommandLine.Tests/Help/HelpBuilderTests.cs

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -508,9 +508,8 @@ public void Arguments_section_uses_description_if_provided()
508508
{
509509
var command = new Command("the-command", "Help text from description")
510510
{
511-
new Argument
511+
new Argument<string>
512512
{
513-
Arity = ArgumentArity.ExactlyOne,
514513
Name = "the-arg",
515514
Description = "Help text from HelpDetail"
516515
}
@@ -563,7 +562,7 @@ public void Arguments_section_does_not_contain_hidden_argument()
563562
[Fact]
564563
public void Arguments_section_does_not_repeat_arguments_that_appear_on_parent_command()
565564
{
566-
var reused = new Argument
565+
var reused = new Argument<string>
567566
{
568567
Name = "reused",
569568
Description = "This argument is valid on both outer and inner commands"
@@ -621,11 +620,10 @@ public void Arguments_section_keeps_added_newlines()
621620
{
622621
var command = new Command("outer", "Help text for the outer command")
623622
{
624-
new Argument
623+
new Argument<string>
625624
{
626625
Name = "outer-command-arg",
627-
Description = $"The argument\r\nfor the\ninner command",
628-
Arity = ArgumentArity.ExactlyOne
626+
Description = $"The argument\r\nfor the\ninner command"
629627
}
630628
};
631629

@@ -645,11 +643,10 @@ public void Arguments_section_keeps_added_newlines_when_width_is_very_small()
645643
{
646644
var command = new Command("outer", "Help text for the outer command")
647645
{
648-
new Argument
646+
new Argument<string>
649647
{
650648
Name = "outer-command-arg",
651649
Description = $"The argument\r\nfor the\ninner command",
652-
Arity = ArgumentArity.ExactlyOne
653650
}
654651
};
655652

@@ -678,9 +675,8 @@ public void Arguments_section_properly_wraps_description()
678675

679676
var command = new Command("outer", "Help text for the outer command")
680677
{
681-
new Argument
678+
new Argument<string>
682679
{
683-
Arity = ArgumentArity.ExactlyOne,
684680
Name = "outer-command-arg",
685681
Description = longCmdText
686682
}
@@ -706,7 +702,7 @@ public void Arguments_section_properly_wraps()
706702

707703
var command = new RootCommand
708704
{
709-
new Argument
705+
new Argument<string>
710706
{
711707
Name = name,
712708
Description = description
@@ -727,19 +723,20 @@ public void Arguments_section_properly_wraps()
727723
}
728724

729725
[Theory]
730-
[InlineData(typeof(FileAccess))]
731-
[InlineData(typeof(FileAccess?))]
732-
public void Command_argument_usage_indicates_enums_values(Type type)
726+
[InlineData(true)]
727+
[InlineData(false)]
728+
public void Command_argument_usage_indicates_enums_values(bool nullable)
733729
{
734730
var description = "This is the argument description";
735731

732+
Argument argument = nullable
733+
? new Argument<FileAccess?>()
734+
: new Argument<FileAccess>();
735+
argument.Description = description;
736+
736737
var command = new Command("outer", "Help text for the outer command")
737738
{
738-
new Argument
739-
{
740-
Description = description,
741-
ValueType = type
742-
}
739+
argument
743740
};
744741

745742
HelpBuilder helpBuilder = GetHelpBuilder(SmallMaxWidth);
@@ -847,7 +844,7 @@ public void Help_describes_default_value_for_argument()
847844
[Fact]
848845
public void Help_does_not_show_default_value_for_argument_when_default_value_is_empty()
849846
{
850-
var argument = new Argument("the-arg", "The argument description");
847+
var argument = new Argument<string>("the-arg", "The argument description");
851848
argument.SetDefaultValue("");
852849

853850
var command = new Command("the-command", "The command description")
@@ -887,12 +884,12 @@ public void Help_does_not_show_default_value_for_option_when_default_value_is_em
887884
[Fact]
888885
public void Command_arguments_default_value_provided()
889886
{
890-
var argument = new Argument
887+
var argument = new Argument<string>
891888
{
892889
Name = "the-arg",
893890
};
894891

895-
var otherArgument = new Argument
892+
var otherArgument = new Argument<string>
896893
{
897894
Name = "the-other-arg",
898895
};

src/System.CommandLine.Tests/ParserTests.MultipleArguments.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -238,14 +238,12 @@ public void tokens_that_cannot_be_converted_by_multiple_arity_argument_flow_to_n
238238
[Fact]
239239
public void Unsatisfied_subsequent_argument_with_min_arity_0_parses_as_default_value()
240240
{
241-
var arg1 = new Argument("arg1")
241+
var arg1 = new Argument<string>("arg1")
242242
{
243-
ValueType = typeof(string),
244243
Arity = ArgumentArity.ExactlyOne
245244
};
246-
var arg2 = new Argument("arg2")
245+
var arg2 = new Argument<string>("arg2")
247246
{
248-
ValueType = typeof(string),
249247
Arity = ArgumentArity.ZeroOrOne,
250248
};
251249
arg2.SetDefaultValue("the-default");

src/System.CommandLine.Tests/System.CommandLine.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
</ItemGroup>
3131

3232
<ItemGroup>
33+
<Compile Include="..\Common\ArgumentBuilder.cs" Link="Utility\ArgumentBuilder.cs" />
3334
<Compile Include="..\Common\OptionBuilder.cs" Link="Utility\OptionBuilder.cs" />
3435
<Compile Include="..\System.CommandLine.Suggest\DotnetMuxer.cs" Link="Utility\DotnetMuxer.cs" />
3536
</ItemGroup>

0 commit comments

Comments
 (0)