I want to add a custom help section after OptionsSection. As of System.CommandLine 2.0.0-beta4.22272.1, HelpBuilder.Default.GetLayout() returns the sections in this order:
The documentation "Add or replace help sections" suggests using Enumerable.Skip, i.e. trusting that the positions of the sections never change, but that seems risky to me. If a future version of System.CommandLine adds a new section between SynopsisSection and CommandUsageSection, and I keep adding my section between the fourth and fifth default section, then my section will go above OptionsSection even though I want it to go below.
So, I'm considering this kind of code instead:
private static IEnumerable<HelpSectionDelegate> GetLayout(HelpContext helpContext)
{
var layout = new List<HelpSectionDelegate>(HelpBuilder.Default.GetLayout());
int index = layout.IndexOf(HelpBuilder.Default.OptionsSection());
layout.Insert(index + 1, ShowOptionDetails);
return layout;
}
i.e. locate the OptionsSection in the list and then insert after that. However, does the System.CommandLine API promise that this kind of search will find the delegate in the list? I mean, the list might contain a different delegate instance that does not compare equal to the delegate that HelpBuilder.Default.OptionsSection() returns, even though both delegates do the same thing. The OptionsSection() method returns a delegate constructed from an anonymous function:
and ECMA-334:2022 §11.11.9 (Delegate equality operators) seems to say that invocation list entries constructed that way are not necessarily equal. So the questions are:
Will future versions of System.CommandLine ensure that such a search keeps working?
Is System.CommandLine relying on Roslyn implementation-specific behavior to keep the delegates equal?
The order of these sections is very standard as a broad CLI convention so I wouldn't expect a change, but I agree the API should provide clearer support for a deterministic way of modifying the defaults.
I want to add a custom help section after OptionsSection. As of System.CommandLine 2.0.0-beta4.22272.1, HelpBuilder.Default.GetLayout() returns the sections in this order:
https://github.com/dotnet/command-line-api/blob/209b724a3c843253d3071e8348c353b297b0b8b5/src/System.CommandLine/Help/HelpBuilder.Default.cs#L141-L152
The documentation "Add or replace help sections" suggests using Enumerable.Skip, i.e. trusting that the positions of the sections never change, but that seems risky to me. If a future version of System.CommandLine adds a new section between SynopsisSection and CommandUsageSection, and I keep adding my section between the fourth and fifth default section, then my section will go above OptionsSection even though I want it to go below.
So, I'm considering this kind of code instead:
i.e. locate the OptionsSection in the list and then insert after that. However, does the System.CommandLine API promise that this kind of search will find the delegate in the list? I mean, the list might contain a different delegate instance that does not compare equal to the delegate that HelpBuilder.Default.OptionsSection() returns, even though both delegates do the same thing. The OptionsSection() method returns a delegate constructed from an anonymous function:
https://github.com/dotnet/command-line-api/blob/209b724a3c843253d3071e8348c353b297b0b8b5/src/System.CommandLine/Help/HelpBuilder.Default.cs#L199-L201
and ECMA-334:2022 §11.11.9 (Delegate equality operators) seems to say that invocation list entries constructed that way are not necessarily equal. So the questions are: