Skip to content

Commit 2538622

Browse files
committed
fix #2640
1 parent 0a63bad commit 2538622

File tree

4 files changed

+43
-3
lines changed

4 files changed

+43
-3
lines changed

src/System.CommandLine.Tests/HelpOptionTests.cs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.CommandLine.Invocation;
77
using System.CommandLine.Tests.Utility;
88
using System.IO;
9+
using System.Linq;
910
using System.Threading;
1011
using System.Threading.Tasks;
1112
using Xunit;
@@ -255,6 +256,41 @@ public void The_users_can_set_max_width()
255256
output.ToString().Should().Contain($" {secondPart}{Environment.NewLine}");
256257
}
257258

259+
[Fact] // https://github.com/dotnet/command-line-api/issues/2640
260+
public void DefaultValueFactory_does_not_throw_when_help_is_invoked()
261+
{
262+
var invocationConfiguration = new InvocationConfiguration
263+
{
264+
Output = new StringWriter(),
265+
Error = new StringWriter()
266+
};
267+
268+
Command subcommand = new("do")
269+
{
270+
new Option<DirectoryInfo>("-x")
271+
{
272+
DefaultValueFactory = result =>
273+
{
274+
result.AddError("Oops!");
275+
return null;
276+
277+
}
278+
}
279+
};
280+
subcommand.SetAction(_ =>
281+
{
282+
});
283+
RootCommand rootCommand = new()
284+
{
285+
subcommand
286+
};
287+
288+
rootCommand.Parse("do --help").Invoke(invocationConfiguration);
289+
290+
invocationConfiguration.Error.ToString().Should().Be("");
291+
}
292+
293+
258294
private sealed class CustomizedHelpAction : SynchronousCommandLineAction
259295
{
260296
internal const string CustomUsageText = "This is custom command usage example.";

src/System.CommandLine/Argument.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,11 @@ public List<Func<CompletionContext, IEnumerable<CompletionItem>>> CompletionSour
112112
/// <returns>Returns the default value for the argument, if defined. Null otherwise.</returns>
113113
public object? GetDefaultValue()
114114
{
115-
return GetDefaultValue(new ArgumentResult(this, null!, null));
115+
var command = Parents.FlattenBreadthFirst(x => x.Parents)
116+
.OfType<Command>()
117+
.FirstOrDefault();
118+
119+
return GetDefaultValue(new ArgumentResult(this, new SymbolResultTree(command!), null));
116120
}
117121

118122
internal abstract object? GetDefaultValue(ArgumentResult argumentResult);

src/System.CommandLine/Parsing/SymbolResult.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public abstract class SymbolResult
1515

1616
private protected SymbolResult(SymbolResultTree symbolResultTree, SymbolResult? parent)
1717
{
18-
SymbolResultTree = symbolResultTree;
18+
SymbolResultTree = symbolResultTree ?? throw new ArgumentNullException(nameof(symbolResultTree));
1919
Parent = parent;
2020
}
2121

src/System.CommandLine/Parsing/SymbolResultTree.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ internal sealed class SymbolResultTree : Dictionary<Symbol, SymbolResult>
1414

1515
internal SymbolResultTree(
1616
Command rootCommand,
17-
List<string>? tokenizeErrors)
17+
List<string>? tokenizeErrors = null)
1818
{
1919
_rootCommand = rootCommand;
2020

0 commit comments

Comments
 (0)