-
Notifications
You must be signed in to change notification settings - Fork 402
make HelpBuilder and related APIs internal #2563
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
e7038d7
e99a785
6a7281d
2fb6d6b
45281b1
f788bed
e978cf8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -194,6 +194,48 @@ public void When_an_option_and_argument_use_same_name_on_the_same_level_of_the_t | |
.Where(ex => ex.Message == $"Command {command.Name} has more than one child named \"{sameName}\"."); | ||
} | ||
|
||
[Fact] | ||
public void When_options_use_same_name_on_different_levels_of_the_tree_no_exception_is_thrown() | ||
{ | ||
const string sameName = "same"; | ||
|
||
RootCommand command = new() | ||
{ | ||
new Command("left") | ||
{ | ||
new Option<int>(sameName) | ||
}, | ||
new Command("right") | ||
{ | ||
new Option<int>(sameName) | ||
}, | ||
}; | ||
|
||
command.Parse($"left {sameName} 1").GetValue<int>(sameName).Should().Be(1); | ||
command.Parse($"right {sameName} 2").GetValue<int>(sameName).Should().Be(2); | ||
} | ||
|
||
[Fact] | ||
public void When_the_same_option_used_in_different_levels_of_the_tree_no_exception_is_thrown() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a test for a bug I've hit while working on dotnet/sdk#49181:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd quibble about the test name here. The intent is that the option is correctly attributed to the correct descendant. |
||
{ | ||
Option<int> multipleParents = new("--int"); | ||
|
||
RootCommand command = new() | ||
{ | ||
new Command("left") | ||
{ | ||
multipleParents | ||
}, | ||
new Command("right") | ||
{ | ||
multipleParents | ||
}, | ||
}; | ||
|
||
command.Parse($"left {multipleParents.Name} 1").GetValue<int>(multipleParents.Name).Should().Be(1); | ||
command.Parse($"right {multipleParents.Name} 2").GetValue<int>(multipleParents.Name).Should().Be(2); | ||
} | ||
|
||
[Fact] | ||
public void When_an_option_and_argument_use_same_name_on_different_levels_of_the_tree_the_value_which_belongs_to_parsed_command_is_returned() | ||
{ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
using System.CommandLine.Invocation; | ||
|
||
namespace System.CommandLine.Help | ||
{ | ||
/// <summary> | ||
/// Provides command line help. | ||
/// </summary> | ||
public sealed class CustomHelpAction : SynchronousCommandLineAction | ||
{ | ||
private HelpBuilder? _builder; | ||
|
||
/// <summary> | ||
/// Specifies an <see cref="Builder"/> to be used to format help output when help is requested. | ||
/// </summary> | ||
internal HelpBuilder Builder | ||
{ | ||
get => _builder ??= new HelpBuilder(Console.IsOutputRedirected ? int.MaxValue : Console.WindowWidth); | ||
set => _builder = value ?? throw new ArgumentNullException(nameof(value)); | ||
} | ||
|
||
/// <inheritdoc /> | ||
public override int Invoke(ParseResult parseResult) | ||
{ | ||
var output = parseResult.Configuration.Output; | ||
|
||
var helpContext = new HelpContext(Builder, | ||
parseResult.CommandResult.Command, | ||
output); | ||
|
||
Builder.Write(helpContext); | ||
|
||
return 0; | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -94,7 +94,7 @@ public void Option_can_customize_first_column_text_based_on_parse_result() | |
: optionBFirstColumnText); | ||
command.Options.Add(new HelpOption() | ||
{ | ||
Action = new HelpAction() | ||
Action = new CustomHelpAction() | ||
{ | ||
Builder = helpBuilder | ||
} | ||
|
@@ -140,7 +140,7 @@ public void Option_can_customize_second_column_text_based_on_parse_result() | |
: optionBDescription); | ||
command.Options.Add(new HelpOption | ||
{ | ||
Action = new HelpAction | ||
Action = new CustomHelpAction | ||
{ | ||
Builder = helpBuilder | ||
} | ||
|
@@ -269,7 +269,7 @@ public void Option_can_fallback_to_default_when_customizing(bool conditionA, boo | |
|
||
command.Options.Add(new HelpOption | ||
{ | ||
Action = new HelpAction | ||
Action = new CustomHelpAction | ||
{ | ||
Builder = helpBuilder | ||
} | ||
|
@@ -317,7 +317,7 @@ public void Argument_can_fallback_to_default_when_customizing( | |
|
||
command.Options.Add(new HelpOption | ||
{ | ||
Action = new HelpAction | ||
Action = new CustomHelpAction | ||
{ | ||
Builder = helpBuilder | ||
} | ||
|
@@ -336,11 +336,20 @@ public void Individual_symbols_can_be_customized() | |
var option = new Option<int>("-x") { Description = "The default option description" }; | ||
var argument = new Argument<int>("int-value") { Description = "The default argument description" }; | ||
|
||
var rootCommand = new RootCommand | ||
CustomHelpAction helpAction = new(); | ||
helpAction.Builder.CustomizeSymbol(subcommand, secondColumnText: "The custom command description"); | ||
helpAction.Builder.CustomizeSymbol(option, secondColumnText: "The custom option description"); | ||
helpAction.Builder.CustomizeSymbol(argument, secondColumnText: "The custom argument description"); | ||
|
||
var rootCommand = new Command("name") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am using |
||
{ | ||
subcommand, | ||
option, | ||
argument, | ||
new HelpOption() | ||
{ | ||
Action = helpAction | ||
} | ||
}; | ||
|
||
CommandLineConfiguration config = new(rootCommand) | ||
|
@@ -350,13 +359,6 @@ public void Individual_symbols_can_be_customized() | |
|
||
ParseResult parseResult = rootCommand.Parse("-h", config); | ||
|
||
if (parseResult.Action is HelpAction helpAction) | ||
{ | ||
helpAction.Builder.CustomizeSymbol(subcommand, secondColumnText: "The custom command description"); | ||
helpAction.Builder.CustomizeSymbol(option, secondColumnText: "The custom option description"); | ||
helpAction.Builder.CustomizeSymbol(argument, secondColumnText: "The custom argument description"); | ||
} | ||
|
||
parseResult.Invoke(); | ||
|
||
config.Output | ||
|
@@ -370,18 +372,16 @@ public void Individual_symbols_can_be_customized() | |
[Fact] | ||
public void Help_sections_can_be_replaced() | ||
{ | ||
CommandLineConfiguration config = new(new RootCommand()) | ||
CustomHelpAction helpAction = new(); | ||
helpAction.Builder.CustomizeLayout(CustomLayout); | ||
|
||
CommandLineConfiguration config = new(new Command("name") { new HelpOption() { Action = helpAction} }) | ||
{ | ||
Output = new StringWriter() | ||
}; | ||
|
||
ParseResult parseResult = config.Parse("-h"); | ||
|
||
if (parseResult.Action is HelpAction helpAction) | ||
{ | ||
helpAction.Builder.CustomizeLayout(CustomLayout); | ||
} | ||
|
||
parseResult.Invoke(); | ||
|
||
config.Output.ToString().Should().Be($"one{NewLine}{NewLine}two{NewLine}{NewLine}three{NewLine}{NewLine}"); | ||
|
@@ -397,20 +397,18 @@ IEnumerable<Func<HelpContext, bool>> CustomLayout(HelpContext _) | |
[Fact] | ||
public void Help_sections_can_be_supplemented() | ||
{ | ||
CommandLineConfiguration config = new(new RootCommand("hello")) | ||
CustomHelpAction helpAction = new(); | ||
helpAction.Builder.CustomizeLayout(CustomLayout); | ||
|
||
CommandLineConfiguration config = new(new Command("hello") { new HelpOption() { Action = helpAction } }) | ||
{ | ||
Output = new StringWriter(), | ||
}; | ||
|
||
var defaultHelp = GetDefaultHelp(config.RootCommand); | ||
var defaultHelp = GetDefaultHelp(new Command("hello")); | ||
|
||
ParseResult parseResult = config.Parse("-h"); | ||
|
||
if (parseResult.Action is HelpAction helpAction) | ||
{ | ||
helpAction.Builder.CustomizeLayout(CustomLayout); | ||
} | ||
|
||
parseResult.Invoke(); | ||
|
||
var output = config.Output.ToString(); | ||
|
@@ -444,7 +442,7 @@ public void Layout_can_be_composed_dynamically_based_on_context() | |
commandWithCustomHelp | ||
}; | ||
|
||
command.Options.OfType<HelpOption>().Single().Action = new HelpAction | ||
command.Options.OfType<HelpOption>().Single().Action = new CustomHelpAction | ||
{ | ||
Builder = helpBuilder | ||
}; | ||
|
@@ -480,7 +478,7 @@ public void Help_default_sections_can_be_wrapped() | |
}, | ||
new HelpOption | ||
{ | ||
Action = new HelpAction | ||
Action = new CustomHelpAction | ||
{ | ||
Builder = new HelpBuilder(30) | ||
} | ||
|
@@ -509,19 +507,17 @@ public void Help_default_sections_can_be_wrapped() | |
[Fact] | ||
public void Help_customized_sections_can_be_wrapped() | ||
{ | ||
CommandLineConfiguration config = new(new RootCommand()) | ||
CustomHelpAction helpAction = new(); | ||
helpAction.Builder = new HelpBuilder(10); | ||
helpAction.Builder.CustomizeLayout(CustomLayout); | ||
|
||
CommandLineConfiguration config = new(new Command("name") { new HelpOption() { Action = helpAction } }) | ||
{ | ||
Output = new StringWriter() | ||
}; | ||
|
||
ParseResult parseResult = config.Parse("-h"); | ||
|
||
if (parseResult.Action is HelpAction helpAction) | ||
{ | ||
helpAction.Builder = new HelpBuilder(10); | ||
helpAction.Builder.CustomizeLayout(CustomLayout); | ||
} | ||
|
||
parseResult.Invoke(); | ||
|
||
string result = config.Output.ToString(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I needed this to be able to avoid using
Option.Argument
(internal getter), it contributes to #2526