-
Notifications
You must be signed in to change notification settings - Fork 481
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
issue #482: reorder options in auto help text #484
Conversation
I 've finally moved to a fluent API design as I found static properties are hell. var message = HelpText.CreateWith(parseResult)
.WithComparison(HelpText.RequiredThenAlphaComparison)
.OnError(error => {
throw new InvalidOperationException($"help text build failed. {error.ToString()}");
})
.OnExample(ex =>
{
return null;
})
.Build(); |
Thanks Olivier Duhart for your effort. |
@moh-hassan , CI fails on a sensless unit test. So wouldnt it be easier to just remove this unit test and let CI succeed ?
but implicit options (--help and --version) does not have short name and then appeared before "real" options with my naive implementation of the comparison function. My bad I did not even try my UT before pushing it ! shame on me. I have a local version of the UT that is OK : I 've simply modify the comparison function to take account of this particular edge case. |
The fail at line 186 |
Good that you discovered the fail reason. |
you can benefit from NameText : Gets a formatted text with unified name information. |
@moh-hassan concerning unit tests, as order is defined using a custom Comparison function, I simply test with 3 cases :
More tests are not that usefull I guess |
@olivier |
This reverts commit 113a21c.
I 've reverted all fluent API code. I 'll come back with the fluent API enhancement later if PR accepted and merged in develop. Comparison<ComparableOption> myComparison= (ComparableOption attr1, ComparableOption attr2) => {
// some sensible comparison code in here
return 1; }
string message = HelpText.AutoBuild(
parseResult,
error => {return null;},
ex => { return null;},
comparison:comparison
); |
src/CommandLine/Text/HelpText.cs
Outdated
{ | ||
OptionSpecification option = spec as OptionSpecification; | ||
ValueSpecification value = spec as ValueSpecification; | ||
bool required = option != null ? option.Required : false; |
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.
Simplify to:
bool required = option?.Required ?? false;
|
||
public Comparison<ComparableOption> OptionComparison = null; | ||
|
||
public static Comparison<ComparableOption> RequiredThenAlphaComparison = (ComparableOption attr1, ComparableOption attr2) => |
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.
Remove redundant else and braces, and use StringComparison.Ordinal
public static Comparison<ComparableOption> RequiredThenAlphaComparison = (attr1, attr2) =>
{
if (attr1.IsOption && attr2.IsOption)
{
if (attr1.Required && !attr2.Required)
return -1;
if (!attr1.Required && attr2.Required)
return 1;
int t = string.Compare(attr1.LongName, attr2.LongName, StringComparison.Ordinal);
return t;
}
return attr1.IsOption && attr2.IsValue ? -1 : 1;
};
public class HelpText | ||
{ | ||
|
||
|
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.
#region Option ordering
return 1; | ||
} | ||
}; | ||
|
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.
#endregion
.WithNotParsed(errors => { throw new InvalidOperationException("Must be parsed."); }) | ||
.WithParsed(args => {; }); | ||
|
||
Comparison<ComparableOption> orderOnShortName = (ComparableOption attr1, ComparableOption attr2) => |
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.
Remove redundant else and braces, and use StringComparison.Ordinal as done here
|
@moh-hassan About your test case asking : my test case is the one you describe
Could you give an example of a test case, please ? About the wiki, I will do it when all dev done and checked, and when time available . |
All help configuration is supposed to be done using
I can merge PR #467 to develop. |
@moh-hassan I would be easier if you merge #467 to develop, then I will rebase my branch with develop and do the fix according to #467 fix. thanks Olivier |
It's merged.
|
* develop: Add errs.Output extension method to auto direct help/version to Console.Out and errors to Console.Error Simplify if-else clause move IsHelp/Isversion to separate file with scope public Fix issue #259 for HelpText.AutoBuild configuration
src/CommandLine/Text/HelpText.cs
Outdated
/// <remarks>The parameter <paramref name="verbsIndex"/> is not ontly a metter of formatting, it controls whether to handle verbs or options.</remarks> | ||
public static HelpText AutoBuild<T>( | ||
ParserResult<T> parserResult, | ||
Func<HelpText, HelpText> onError, | ||
Func<Example, Example> onExample, | ||
bool verbsIndex = false, | ||
int maxDisplayWidth = DefaultMaximumLength) | ||
int maxDisplayWidth = DefaultMaximumLength, | ||
Comparison<ComparableOption> comparison = null) |
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.
//remove this line, no more parameters are used
//Comparison comparison = null
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.
working on it.
src/CommandLine/Text/HelpText.cs
Outdated
{ | ||
var auto = new HelpText | ||
{ | ||
Heading = HeadingInfo.Empty, | ||
Copyright = CopyrightInfo.Empty, | ||
AdditionalNewLineAfterOption = true, | ||
AddDashesToOption = !verbsIndex, | ||
MaximumDisplayWidth = maxDisplayWidth | ||
MaximumDisplayWidth = maxDisplayWidth, | ||
OptionComparison = comparison |
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.
//remove this line, no more parameters are used
// OptionComparison = comparison
return error; | ||
}, | ||
ex => ex, | ||
comparison: comparison); |
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.
//remove this line
//comparison: comparison
ex => ex, | ||
false, | ||
80, | ||
orderOnShortName); |
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.
//remove the line orderOnShortName
//Enough to call without extra parameters:
string message = HelpText.AutoBuild(parseResult,
error =>
{
error.OptionComparison = orderOnShortName;
return error;
},
ex => ex);
I have trouble with onerror action. I sync my fork with upstream , I see your commandline#439 merge but it seems it does not call onerror when parse is ok. |
That is correct.
Note: This is the official way to test help: either by passing args '--help' or parser errors. It's not tested on parser success. |
ok I didnot see the --help in test case. I correct it right now |
@moh-hassan last build seems to have failed on upload failure. I can not restart and it does not seem to relate to my PR. Could you check it and maybe restart the build ? |
@moh-hassan : code seems ok, maybe you are looking at a stale version. |
+1 |
@moh-hassan thank you for merging . Glad to have help a bit this project. |
this PR allows to redefine order using a Comparison function.
I choose to create a new ComparableOption struct from the Specification class to not break existing visibility rules (Specification is internal).
To redefine order you then have to provide a Comparison object as a static property of HelpText class before calling AutoBuild :
Maybe not the perfect solution but it works well.
PR comes with the order that @tehkyle proposed.
When no comparison is provided before calling AutoBuild then it defaults to the current behavior (declaration order)
Unit test is also provided
Maybe a better and more elegant solution would be to provide a fluent API to configure HelpText AutoBuild.
Something like
@maintaners what do you think ? do you prefer I rework it with fluent API or can we stay with it ?