Skip to content

Commit 1524f56

Browse files
committed
Merge branch 'feature/default-value' into main (#421)
2 parents 3eb90d7 + 8c2a3d2 commit 1524f56

25 files changed

+586
-135
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,6 @@
11
name: CI
22

3-
on:
4-
push:
5-
branches:
6-
- main
7-
- 'release/*'
8-
pull_request:
9-
branches:
10-
- main
11-
- 'release/*'
3+
on: [push, pull_request]
124

135
env:
146
BUILD_NUMBER: ${{ github.run_number }}

Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
<PropertyGroup>
3131
<SuppressNETCoreSdkPreviewMessage>true</SuppressNETCoreSdkPreviewMessage>
3232
<WarningsNotAsErrors>$(WarningsNotAsErrors);1591</WarningsNotAsErrors>
33-
<LangVersion>8.0</LangVersion>
33+
<LangVersion>9.0</LangVersion>
3434
<Nullable>annotations</Nullable>
3535
<AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)src\StrongName.snk</AssemblyOriginatorKeyFile>
3636
<SignAssembly>true</SignAssembly>

README.md

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -81,21 +81,19 @@ using McMaster.Extensions.CommandLineUtils;
8181
var app = new CommandLineApplication();
8282

8383
app.HelpOption();
84-
var optionSubject = app.Option("-s|--subject <SUBJECT>", "The subject", CommandOptionType.SingleValue);
85-
var optionRepeat = app.Option<int>("-n|--count <N>", "Repeat", CommandOptionType.SingleValue);
84+
85+
var subject = app.Option("-s|--subject <SUBJECT>", "The subject", CommandOptionType.SingleValue);
86+
subject.DefaultValue = "world";
87+
88+
var repeat = app.Option<int>("-n|--count <N>", "Repeat", CommandOptionType.SingleValue);
89+
repeat.DefaultValue = 1;
8690

8791
app.OnExecute(() =>
8892
{
89-
var subject = optionSubject.HasValue()
90-
? optionSubject.Value()
91-
: "world";
92-
93-
var count = optionRepeat.HasValue() ? optionRepeat.ParsedValue : 1;
94-
for (var i = 0; i < count; i++)
93+
for (var i = 0; i < repeat.ParsedValue; i++)
9594
{
96-
Console.WriteLine($"Hello {subject}!");
95+
Console.WriteLine($"Hello {subject.Value()}!");
9796
}
98-
return 0;
9997
});
10098

10199
return app.Execute(args);

docs/docs/intro.md

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,15 +64,12 @@ public class Program
6464
var app = new CommandLineApplication();
6565

6666
app.HelpOption();
67-
var optionSubject = app.Option("-s|--subject <SUBJECT>", "The subject", CommandOptionType.SingleValue);
67+
var subject = app.Option("-s|--subject <SUBJECT>", "The subject", CommandOptionType.SingleValue);
68+
subject.DefaultValue = "world";
6869

6970
app.OnExecute(() =>
7071
{
71-
var subject = optionSubject.HasValue()
72-
? optionSubject.Value()
73-
: "world";
74-
75-
Console.WriteLine($"Hello {subject}!");
72+
Console.WriteLine($"Hello {subject.Value()}!");
7673
return 0;
7774
});
7875

docs/samples/custom-attribute/Program.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,10 @@ public void Apply(ConventionContext context, MemberInfo member)
4444
if (member is FieldInfo field)
4545
{
4646
var opt = context.Application.Option("--working-dir", "The working directory", CommandOptionType.SingleOrNoValue);
47+
opt.DefaultValue = context.Application.WorkingDirectory;
4748
context.Application.OnParsingComplete(_ =>
4849
{
49-
var cwd = opt.HasValue()
50-
? opt.Value()
51-
: context.Application.WorkingDirectory;
52-
field.SetValue(context.ModelAccessor.GetModel(), cwd);
50+
field.SetValue(context.ModelAccessor.GetModel(), opt.Value());
5351
});
5452
}
5553
}

docs/samples/helloworld-async/Program.cs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,22 @@
55
var app = new CommandLineApplication();
66

77
app.HelpOption();
8-
var optionSubject = app.Option("-s|--subject <SUBJECT>", "The subject", CommandOptionType.SingleValue);
9-
var optionRepeat = app.Option<int>("-n|--count <N>", "Repeat", CommandOptionType.SingleValue);
8+
var subject = app.Option("-s|--subject <SUBJECT>", "The subject", CommandOptionType.SingleValue);
9+
subject.DefaultValue = "world";
10+
11+
var repeat = app.Option<int>("-n|--count <N>", "Repeat", CommandOptionType.SingleValue);
12+
repeat.DefaultValue = 1;
1013

1114
app.OnExecuteAsync(async cancellationToken =>
1215
{
13-
var subject = optionSubject.HasValue()
14-
? optionSubject.Value()
15-
: "world";
16-
17-
var count = optionRepeat.HasValue() ? optionRepeat.ParsedValue : 1;
18-
for (var i = 0; i < count; i++)
16+
for (var i = 0; i < repeat.ParsedValue; i++)
1917
{
2018
Console.Write($"Hello");
2119

2220
// Pause for dramatic effect
2321
await Task.Delay(2000, cancellationToken);
2422

25-
Console.WriteLine($" {subject}!");
23+
Console.WriteLine($" {subject.Value()}!");
2624
}
2725
});
2826

docs/samples/helloworld/HelloWorld.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
55
<TargetFramework>net5.0</TargetFramework>
6+
<Nullable>enable</Nullable>
67
</PropertyGroup>
78

89
<ItemGroup>

docs/samples/helloworld/Program.cs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,17 @@
44
var app = new CommandLineApplication();
55

66
app.HelpOption();
7-
var optionSubject = app.Option("-s|--subject <SUBJECT>", "The subject", CommandOptionType.SingleValue);
8-
var optionRepeat = app.Option<int>("-n|--count <N>", "Repeat", CommandOptionType.SingleValue);
7+
var subject = app.Option("-s|--subject <SUBJECT>", "The subject", CommandOptionType.SingleValue);
8+
subject.DefaultValue = "world";
9+
var repeat = app.Option<int?>("-n|--count <N>", "Repeat", CommandOptionType.SingleValue);
10+
repeat.DefaultValue = 1;
911

1012
app.OnExecute(() =>
1113
{
12-
var subject = optionSubject.HasValue()
13-
? optionSubject.Value()
14-
: "world";
15-
16-
var count = optionRepeat.HasValue() ? optionRepeat.ParsedValue : 1;
17-
for (var i = 0; i < count; i++)
14+
for (var i = 0; i < repeat.ParsedValue; i++)
1815
{
19-
Console.WriteLine($"Hello {subject}!");
16+
Console.WriteLine($"Hello {subject.Value()}!");
2017
}
21-
return 0;
2218
});
2319

2420
return app.Execute(args);

src/CommandLineUtils/Abstractions/ValueParserProvider.cs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ public IValueParser GetParser(Type type)
101101
return parser;
102102
}
103103

104-
if (ReflectionHelper.IsNullableType(type, out var wrappedType) && wrappedType != null)
104+
if (ReflectionHelper.IsNullableType(type, out var wrappedType))
105105
{
106106
if (wrappedType.IsEnum)
107107
{
@@ -114,15 +114,9 @@ public IValueParser GetParser(Type type)
114114
}
115115
}
116116

117-
if (!type.IsGenericType)
117+
if (ReflectionHelper.IsSpecialValueTupleType(type, out var wrappedType2))
118118
{
119-
return null;
120-
}
121-
122-
var typeDef = type.GetGenericTypeDefinition();
123-
if (typeDef == typeof(ValueTuple<,>) && type.GenericTypeArguments[0] == typeof(bool))
124-
{
125-
var innerParser = GetParser(type.GenericTypeArguments[1]);
119+
var innerParser = GetParser(wrappedType2);
126120
if (innerParser == null)
127121
{
128122
return null;

src/CommandLineUtils/CommandArgument.cs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,20 +36,35 @@ public class CommandArgument
3636
/// <summary>
3737
/// All values specified, if any.
3838
/// </summary>
39-
public IReadOnlyList<string?> Values => _values;
39+
public IReadOnlyList<string?> Values
40+
{
41+
get
42+
{
43+
if (_values.Count == 0 && DefaultValue != null)
44+
{
45+
return new List<string?> { DefaultValue };
46+
}
47+
return _values;
48+
}
49+
}
4050

4151
/// <summary>
4252
/// Allow multiple values.
4353
/// </summary>
4454
public bool MultipleValues { get; set; }
4555

4656
/// <summary>
47-
/// The first value from <see cref="Values"/>, if any.
57+
/// The first value from <see cref="Values"/>, if any, or <see cref="DefaultValue" />.
4858
/// </summary>
4959
public string? Value => Values.FirstOrDefault();
5060

5161
/// <summary>
52-
/// True if this argument has been assigned values.
62+
/// The default value of the argument.
63+
/// </summary>
64+
public string? DefaultValue { get; set; }
65+
66+
/// <summary>
67+
/// True when <see cref="Values"/> is not empty or when a <see cref="DefaultValue" /> is given.
5368
/// </summary>
5469
public bool HasValue => Values.Any();
5570

0 commit comments

Comments
 (0)