From 1811ce4d8c14a68e32b1f28700ec6b178dd1e727 Mon Sep 17 00:00:00 2001 From: b3b00 Date: Mon, 22 Jul 2019 13:37:02 +0200 Subject: [PATCH 01/12] issue #482 : fix --- src/CommandLine/Core/ReflectionExtensions.cs | 38 +++++++- .../Infrastructure/ReflectionHelper.cs | 2 +- src/CommandLine/Text/HelpText.cs | 27 +++--- .../Fakes/OPtions_HelpText_Ordering.cs | 48 ++++++++++ tests/CommandLine.Tests/Unit/Issue482Tests.cs | 90 +++++++++++++++++++ .../Unit/Text/HelpTextTests.cs | 9 +- 6 files changed, 197 insertions(+), 17 deletions(-) create mode 100644 tests/CommandLine.Tests/Fakes/OPtions_HelpText_Ordering.cs create mode 100644 tests/CommandLine.Tests/Unit/Issue482Tests.cs diff --git a/src/CommandLine/Core/ReflectionExtensions.cs b/src/CommandLine/Core/ReflectionExtensions.cs index 9b6f858c..2cb52b98 100644 --- a/src/CommandLine/Core/ReflectionExtensions.cs +++ b/src/CommandLine/Core/ReflectionExtensions.cs @@ -14,15 +14,49 @@ namespace CommandLine.Core { static class ReflectionExtensions { - public static IEnumerable GetSpecifications(this Type type, Func selector) + public static IEnumerable GetSpecifications(this Type type, Func selector,Comparison comparison = null) { - return from pi in type.FlattenHierarchy().SelectMany(x => x.GetTypeInfo().GetProperties()) + var properties = type.FlattenHierarchy().SelectMany(x => x.GetTypeInfo().GetProperties()); + var optionsProps = properties.SelectMany(x => + { + var attrs = x.GetCustomAttributes(); + return attrs.OfType(); + }).ToList(); + + var names = optionsProps.Select(o => o.LongName).ToList(); + + if (comparison != null) + { + optionsProps.Sort(comparison); + } + + var namesSort = optionsProps.Select(o => o.LongName).ToList(); + + var valueProps = properties.SelectMany(x => + { + var attrs = x.GetCustomAttributes(); + return attrs.OfType(); + }).ToList(); + + /* + from pi in type.FlattenHierarchy().SelectMany(x => x.GetTypeInfo().GetProperties()) + let attrs = pi.GetCustomAttributes(true) + where + attrs.OfType().Any() + group pi by pi.Name into g + select selector(g.First()); + */ + var unordered = from pi in type.FlattenHierarchy().SelectMany(x => x.GetTypeInfo().GetProperties()) let attrs = pi.GetCustomAttributes(true) where attrs.OfType().Any() || attrs.OfType().Any() group pi by pi.Name into g select selector(g.First()); + + + return unordered; + } public static Maybe GetVerbSpecification(this Type type) diff --git a/src/CommandLine/Infrastructure/ReflectionHelper.cs b/src/CommandLine/Infrastructure/ReflectionHelper.cs index e2177947..9fcd9902 100644 --- a/src/CommandLine/Infrastructure/ReflectionHelper.cs +++ b/src/CommandLine/Infrastructure/ReflectionHelper.cs @@ -103,4 +103,4 @@ private static Assembly GetExecutingOrEntryAssembly() return Assembly.GetEntryAssembly()??Assembly.GetCallingAssembly(); } } -} \ No newline at end of file +} diff --git a/src/CommandLine/Text/HelpText.cs b/src/CommandLine/Text/HelpText.cs index cd11a475..e39c483b 100644 --- a/src/CommandLine/Text/HelpText.cs +++ b/src/CommandLine/Text/HelpText.cs @@ -230,7 +230,7 @@ public SentenceBuilder SentenceBuilder /// The maximum width of the display. /// The parameter is not ontly a metter of formatting, it controls whether to handle verbs or options. public static HelpText AutoBuild( - ParserResult parserResult, + ParserResult parserResult,Comparison comparison, Func onError, Func onExample, bool verbsIndex = false, @@ -269,8 +269,10 @@ public static HelpText AutoBuild( .Do(license => license.AddToHelpText(auto, true)); var usageAttr = ReflectionHelper.GetAttribute(); + + + var usageLines = HelpText.RenderUsageTextAsLines(parserResult, onExample).ToMaybe(); - if (usageAttr.IsJust() || usageLines.IsJust()) { var heading = auto.SentenceBuilder.UsageHeadingText(); @@ -291,7 +293,7 @@ public static HelpText AutoBuild( auto.AddVerbs(parserResult.TypeInfo.Choices.ToArray()); } else - auto.AddOptions(parserResult); + auto.AddOptions(parserResult,comparison); return auto; } @@ -318,13 +320,13 @@ public static HelpText AutoBuild(ParserResult parserResult, int maxDisplay return new HelpText(HeadingInfo.Default){MaximumDisplayWidth = maxDisplayWidth }.AddPreOptionsLine(Environment.NewLine); if (!errors.Any(e => e.Tag == ErrorType.HelpVerbRequestedError)) - return AutoBuild(parserResult, current => DefaultParsingErrorsHandler(parserResult, current), e => e, maxDisplayWidth: maxDisplayWidth); + return AutoBuild(parserResult,null, current => DefaultParsingErrorsHandler(parserResult, current), e => e, maxDisplayWidth: maxDisplayWidth); var err = errors.OfType().Single(); var pr = new NotParsed(TypeInfo.Create(err.Type), Enumerable.Empty()); return err.Matched - ? AutoBuild(pr, current => DefaultParsingErrorsHandler(pr, current), e => e, maxDisplayWidth: maxDisplayWidth) - : AutoBuild(parserResult, current => DefaultParsingErrorsHandler(parserResult, current), e => e, true, maxDisplayWidth); + ? AutoBuild(pr,null, current => DefaultParsingErrorsHandler(pr, current), e => e, maxDisplayWidth: maxDisplayWidth) + : AutoBuild(parserResult, null,current => DefaultParsingErrorsHandler(parserResult, current), e => e, true, maxDisplayWidth); } /// @@ -436,12 +438,14 @@ public HelpText AddPostOptionsText(string text) /// /// A parsing computation result. /// Thrown when parameter is null. - public HelpText AddOptions(ParserResult result) + public HelpText AddOptions(ParserResult result,Comparison comparison = null) { if (result == null) throw new ArgumentNullException("result"); + var specs = GetSpecificationsFromType((result.TypeInfo.Current),comparison); + return AddOptionsImpl( - GetSpecificationsFromType(result.TypeInfo.Current), + GetSpecificationsFromType(result.TypeInfo.Current,null), SentenceBuilder.RequiredWord(), MaximumDisplayWidth); } @@ -698,9 +702,10 @@ internal static void AddLine(StringBuilder builder, string value, int maximumLen builder.Append(value); } - private IEnumerable GetSpecificationsFromType(Type type) + private IEnumerable GetSpecificationsFromType(Type type,Comparison comparison = null) { - var specs = type.GetSpecifications(Specification.FromProperty); + var specs = type.GetSpecifications(Specification.FromProperty, comparison); + var optionSpecs = specs .OfType(); if (autoHelp) @@ -998,4 +1003,4 @@ private static string FormatDefaultValue(T value) : string.Empty; } } -} \ No newline at end of file +} diff --git a/tests/CommandLine.Tests/Fakes/OPtions_HelpText_Ordering.cs b/tests/CommandLine.Tests/Fakes/OPtions_HelpText_Ordering.cs new file mode 100644 index 00000000..8e7cac70 --- /dev/null +++ b/tests/CommandLine.Tests/Fakes/OPtions_HelpText_Ordering.cs @@ -0,0 +1,48 @@ +// Copyright 2005-2015 Giacomo Stelluti Scala & Contributors. All rights reserved. See License.md in the project root for license information. + +using System.Collections.Generic; +using System.Runtime.CompilerServices; + +namespace CommandLine.Tests.Fakes +{ + + [Verb("verb1")] + class Options_HelpText_Ordering_Verb1 + { + [Option('a',"alpha",Required = true)] + public string alphaOption { get; set; } + + [Option('b',"alpha2",Required = true)] + public string alphaTwoOption { get; set; } + + [Option('d',"charlie",Required = false)] + public string deltaOption { get; set; } + + [Option('c',"bravo",Required = false)] + public string charlieOption { get; set; } + + [Option('f',"foxtrot",Required = false)] + public string foxOption { get; set; } + + [Option('e',"echo",Required = false)] + public string echoOption { get; set; } + + } + + [Verb("verb2")] + class Options_HelpText_Ordering_Verb2 + { + [Option('a',"alpha",Required = true)] + public string alphaOption { get; set; } + + [Option('b',"alpha2",Required = true)] + public string alphaTwoOption { get; set; } + + [Option('c',"bravo",Required = false)] + public string charlieOption { get; set; } + + [Option('d',"charlie",Required = false)] + public string deltaOption { get; set; } + + } +} diff --git a/tests/CommandLine.Tests/Unit/Issue482Tests.cs b/tests/CommandLine.Tests/Unit/Issue482Tests.cs new file mode 100644 index 00000000..abc6414e --- /dev/null +++ b/tests/CommandLine.Tests/Unit/Issue482Tests.cs @@ -0,0 +1,90 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using CommandLine.Core; +using System.Linq; +using System.Reflection; +using CommandLine.Infrastructure; +using CommandLine.Tests.Fakes; +using CommandLine.Text; +using FluentAssertions; +using Xunit; +using System.Text; +using Xunit.Sdk; + +namespace CommandLine.Tests.Unit +{ + public class Issue482Tests + { + [Fact] + public void AutoBuild_with_ordering() + { + string expectedCompany = "Company"; + + + var parser = Parser.Default; + var parseResult = parser.ParseArguments( + new[] {"verb1", "--alpha", "alpaga", "--alpha2", "alala", "--charlie", "charlot"}) + .WithNotParsed(errors => { throw new InvalidOperationException("Must be parsed."); }) + .WithParsed(args => { ; }); + + Comparison comparison = (OptionAttribute option1, OptionAttribute option2) => + { + if (option1 == null) + { + return -1; + } + + if (option2 == null) + { + return 1; + } + + if (option1.Required && !option2.Required) + { + return -1; + } + else if (!option1.Required && option2.Required) + { + return 1; + } + else + { + return String.Compare(option1.LongName, option2.LongName, StringComparison.CurrentCulture); + } + }; + + + var toto = HelpText.AutoBuild(parseResult, comparison, + err => { throw new InvalidOperationException($"help text build failed. {err.ToString()}"); }, + ex => + { + Console.WriteLine(ex.ToString()); + return null; + }); + + string helpMessage = toto.ToString(); + var helps = helpMessage.Split(new[] {'\r', '\n'}, StringSplitOptions.RemoveEmptyEntries).Skip(2).ToList(); + List expected = new List() + { + " -a, --alpha Required.", + " -b, --alpha2 Required.", + " -d, --charlie", + " -c, --bravo", + "-f, --foxtrot", + "-e, --echo", + "--help Display this help screen.", + "--version Display version information." + }; + Assert.Equal(expected.Count,helps.Count); + int i = 0; + foreach (var expect in expected) + { + Assert.Equal(expect.Trim(),helps[i].Trim()); + i++; + } + + ; + } + } +} diff --git a/tests/CommandLine.Tests/Unit/Text/HelpTextTests.cs b/tests/CommandLine.Tests/Unit/Text/HelpTextTests.cs index 7c4d7590..f70d9d4f 100644 --- a/tests/CommandLine.Tests/Unit/Text/HelpTextTests.cs +++ b/tests/CommandLine.Tests/Unit/Text/HelpTextTests.cs @@ -574,6 +574,7 @@ public void Default_set_to_sequence_should_be_properly_printed() } #endif + [Fact] public void AutoBuild_when_no_assembly_attributes() { @@ -584,7 +585,7 @@ public void AutoBuild_when_no_assembly_attributes() ParserResult fakeResult = new NotParsed( TypeInfo.Create(typeof (Simple_Options)), new Error[0]); bool onErrorCalled = false; - HelpText actualResult = HelpText.AutoBuild(fakeResult, ht => + HelpText actualResult = HelpText.AutoBuild(fakeResult,null, ht => { onErrorCalled = true; return ht; @@ -609,7 +610,7 @@ public void AutoBuild_with_assembly_title_and_version_attributes_only() ParserResult fakeResult = new NotParsed( TypeInfo.Create(typeof (Simple_Options)), new Error[0]); bool onErrorCalled = false; - HelpText actualResult = HelpText.AutoBuild(fakeResult, ht => + HelpText actualResult = HelpText.AutoBuild(fakeResult, null, ht => { onErrorCalled = true; return ht; @@ -619,6 +620,8 @@ public void AutoBuild_with_assembly_title_and_version_attributes_only() actualResult.Heading.Should().Be(string.Format("{0} {1}", expectedTitle, expectedVersion)); } + + [Fact] public void AutoBuild_with_assembly_company_attribute_only() @@ -633,7 +636,7 @@ public void AutoBuild_with_assembly_company_attribute_only() ParserResult fakeResult = new NotParsed( TypeInfo.Create(typeof (Simple_Options)), new Error[0]); bool onErrorCalled = false; - HelpText actualResult = HelpText.AutoBuild(fakeResult, ht => + HelpText actualResult = HelpText.AutoBuild(fakeResult, null,ht => { onErrorCalled = true; return ht; From 11beecaa8f4986c5801b690baab4b53e644273d5 Mon Sep 17 00:00:00 2001 From: b3b00 Date: Mon, 22 Jul 2019 14:42:06 +0200 Subject: [PATCH 02/12] Revert "issue #482 : fix" This reverts commit 1811ce4d8c14a68e32b1f28700ec6b178dd1e727. --- src/CommandLine/Core/ReflectionExtensions.cs | 38 +------------------ .../Infrastructure/ReflectionHelper.cs | 2 +- src/CommandLine/Text/HelpText.cs | 27 ++++++------- .../Unit/Text/HelpTextTests.cs | 9 ++--- 4 files changed, 17 insertions(+), 59 deletions(-) diff --git a/src/CommandLine/Core/ReflectionExtensions.cs b/src/CommandLine/Core/ReflectionExtensions.cs index 2cb52b98..9b6f858c 100644 --- a/src/CommandLine/Core/ReflectionExtensions.cs +++ b/src/CommandLine/Core/ReflectionExtensions.cs @@ -14,49 +14,15 @@ namespace CommandLine.Core { static class ReflectionExtensions { - public static IEnumerable GetSpecifications(this Type type, Func selector,Comparison comparison = null) + public static IEnumerable GetSpecifications(this Type type, Func selector) { - var properties = type.FlattenHierarchy().SelectMany(x => x.GetTypeInfo().GetProperties()); - var optionsProps = properties.SelectMany(x => - { - var attrs = x.GetCustomAttributes(); - return attrs.OfType(); - }).ToList(); - - var names = optionsProps.Select(o => o.LongName).ToList(); - - if (comparison != null) - { - optionsProps.Sort(comparison); - } - - var namesSort = optionsProps.Select(o => o.LongName).ToList(); - - var valueProps = properties.SelectMany(x => - { - var attrs = x.GetCustomAttributes(); - return attrs.OfType(); - }).ToList(); - - /* - from pi in type.FlattenHierarchy().SelectMany(x => x.GetTypeInfo().GetProperties()) - let attrs = pi.GetCustomAttributes(true) - where - attrs.OfType().Any() - group pi by pi.Name into g - select selector(g.First()); - */ - var unordered = from pi in type.FlattenHierarchy().SelectMany(x => x.GetTypeInfo().GetProperties()) + return from pi in type.FlattenHierarchy().SelectMany(x => x.GetTypeInfo().GetProperties()) let attrs = pi.GetCustomAttributes(true) where attrs.OfType().Any() || attrs.OfType().Any() group pi by pi.Name into g select selector(g.First()); - - - return unordered; - } public static Maybe GetVerbSpecification(this Type type) diff --git a/src/CommandLine/Infrastructure/ReflectionHelper.cs b/src/CommandLine/Infrastructure/ReflectionHelper.cs index 9fcd9902..e2177947 100644 --- a/src/CommandLine/Infrastructure/ReflectionHelper.cs +++ b/src/CommandLine/Infrastructure/ReflectionHelper.cs @@ -103,4 +103,4 @@ private static Assembly GetExecutingOrEntryAssembly() return Assembly.GetEntryAssembly()??Assembly.GetCallingAssembly(); } } -} +} \ No newline at end of file diff --git a/src/CommandLine/Text/HelpText.cs b/src/CommandLine/Text/HelpText.cs index e39c483b..cd11a475 100644 --- a/src/CommandLine/Text/HelpText.cs +++ b/src/CommandLine/Text/HelpText.cs @@ -230,7 +230,7 @@ public SentenceBuilder SentenceBuilder /// The maximum width of the display. /// The parameter is not ontly a metter of formatting, it controls whether to handle verbs or options. public static HelpText AutoBuild( - ParserResult parserResult,Comparison comparison, + ParserResult parserResult, Func onError, Func onExample, bool verbsIndex = false, @@ -269,10 +269,8 @@ public static HelpText AutoBuild( .Do(license => license.AddToHelpText(auto, true)); var usageAttr = ReflectionHelper.GetAttribute(); - - - var usageLines = HelpText.RenderUsageTextAsLines(parserResult, onExample).ToMaybe(); + if (usageAttr.IsJust() || usageLines.IsJust()) { var heading = auto.SentenceBuilder.UsageHeadingText(); @@ -293,7 +291,7 @@ public static HelpText AutoBuild( auto.AddVerbs(parserResult.TypeInfo.Choices.ToArray()); } else - auto.AddOptions(parserResult,comparison); + auto.AddOptions(parserResult); return auto; } @@ -320,13 +318,13 @@ public static HelpText AutoBuild(ParserResult parserResult, int maxDisplay return new HelpText(HeadingInfo.Default){MaximumDisplayWidth = maxDisplayWidth }.AddPreOptionsLine(Environment.NewLine); if (!errors.Any(e => e.Tag == ErrorType.HelpVerbRequestedError)) - return AutoBuild(parserResult,null, current => DefaultParsingErrorsHandler(parserResult, current), e => e, maxDisplayWidth: maxDisplayWidth); + return AutoBuild(parserResult, current => DefaultParsingErrorsHandler(parserResult, current), e => e, maxDisplayWidth: maxDisplayWidth); var err = errors.OfType().Single(); var pr = new NotParsed(TypeInfo.Create(err.Type), Enumerable.Empty()); return err.Matched - ? AutoBuild(pr,null, current => DefaultParsingErrorsHandler(pr, current), e => e, maxDisplayWidth: maxDisplayWidth) - : AutoBuild(parserResult, null,current => DefaultParsingErrorsHandler(parserResult, current), e => e, true, maxDisplayWidth); + ? AutoBuild(pr, current => DefaultParsingErrorsHandler(pr, current), e => e, maxDisplayWidth: maxDisplayWidth) + : AutoBuild(parserResult, current => DefaultParsingErrorsHandler(parserResult, current), e => e, true, maxDisplayWidth); } /// @@ -438,14 +436,12 @@ public HelpText AddPostOptionsText(string text) /// /// A parsing computation result. /// Thrown when parameter is null. - public HelpText AddOptions(ParserResult result,Comparison comparison = null) + public HelpText AddOptions(ParserResult result) { if (result == null) throw new ArgumentNullException("result"); - var specs = GetSpecificationsFromType((result.TypeInfo.Current),comparison); - return AddOptionsImpl( - GetSpecificationsFromType(result.TypeInfo.Current,null), + GetSpecificationsFromType(result.TypeInfo.Current), SentenceBuilder.RequiredWord(), MaximumDisplayWidth); } @@ -702,10 +698,9 @@ internal static void AddLine(StringBuilder builder, string value, int maximumLen builder.Append(value); } - private IEnumerable GetSpecificationsFromType(Type type,Comparison comparison = null) + private IEnumerable GetSpecificationsFromType(Type type) { - var specs = type.GetSpecifications(Specification.FromProperty, comparison); - + var specs = type.GetSpecifications(Specification.FromProperty); var optionSpecs = specs .OfType(); if (autoHelp) @@ -1003,4 +998,4 @@ private static string FormatDefaultValue(T value) : string.Empty; } } -} +} \ No newline at end of file diff --git a/tests/CommandLine.Tests/Unit/Text/HelpTextTests.cs b/tests/CommandLine.Tests/Unit/Text/HelpTextTests.cs index f70d9d4f..7c4d7590 100644 --- a/tests/CommandLine.Tests/Unit/Text/HelpTextTests.cs +++ b/tests/CommandLine.Tests/Unit/Text/HelpTextTests.cs @@ -574,7 +574,6 @@ public void Default_set_to_sequence_should_be_properly_printed() } #endif - [Fact] public void AutoBuild_when_no_assembly_attributes() { @@ -585,7 +584,7 @@ public void AutoBuild_when_no_assembly_attributes() ParserResult fakeResult = new NotParsed( TypeInfo.Create(typeof (Simple_Options)), new Error[0]); bool onErrorCalled = false; - HelpText actualResult = HelpText.AutoBuild(fakeResult,null, ht => + HelpText actualResult = HelpText.AutoBuild(fakeResult, ht => { onErrorCalled = true; return ht; @@ -610,7 +609,7 @@ public void AutoBuild_with_assembly_title_and_version_attributes_only() ParserResult fakeResult = new NotParsed( TypeInfo.Create(typeof (Simple_Options)), new Error[0]); bool onErrorCalled = false; - HelpText actualResult = HelpText.AutoBuild(fakeResult, null, ht => + HelpText actualResult = HelpText.AutoBuild(fakeResult, ht => { onErrorCalled = true; return ht; @@ -620,8 +619,6 @@ public void AutoBuild_with_assembly_title_and_version_attributes_only() actualResult.Heading.Should().Be(string.Format("{0} {1}", expectedTitle, expectedVersion)); } - - [Fact] public void AutoBuild_with_assembly_company_attribute_only() @@ -636,7 +633,7 @@ public void AutoBuild_with_assembly_company_attribute_only() ParserResult fakeResult = new NotParsed( TypeInfo.Create(typeof (Simple_Options)), new Error[0]); bool onErrorCalled = false; - HelpText actualResult = HelpText.AutoBuild(fakeResult, null,ht => + HelpText actualResult = HelpText.AutoBuild(fakeResult, ht => { onErrorCalled = true; return ht; From f8d26bc7ca613e0c044276c628e6bc31b7ce742c Mon Sep 17 00:00:00 2001 From: b3b00 Date: Mon, 22 Jul 2019 16:06:46 +0200 Subject: [PATCH 03/12] #482 rework --- src/CommandLine/Text/HelpText.cs | 94 ++++++++++++++++++- .../Fakes/OPtions_HelpText_Ordering.cs | 76 +++++++-------- tests/CommandLine.Tests/Unit/Issue482Tests.cs | 34 ++----- 3 files changed, 134 insertions(+), 70 deletions(-) diff --git a/src/CommandLine/Text/HelpText.cs b/src/CommandLine/Text/HelpText.cs index cd11a475..d4660fed 100644 --- a/src/CommandLine/Text/HelpText.cs +++ b/src/CommandLine/Text/HelpText.cs @@ -17,8 +17,71 @@ namespace CommandLine.Text /// Provides means to format an help screen. /// You can assign it in place of a instance. /// + + + + public struct ComparableOption + { + public bool Required; + public bool IsOption; + public bool IsValue; + public string LongName; + public int Index; + } + public class HelpText { + + + ComparableOption ToComparableOption(Specification spec, int index) + { + OptionSpecification option = spec as OptionSpecification; + ValueSpecification value = spec as ValueSpecification; + bool required = option != null ? option.Required : false; + string name = option?.LongName; + + return new ComparableOption() + { + Required = required, + IsOption = option != null, + IsValue = value != null, + LongName = name, + Index = index + }; + + } + + + public static Comparison OptionComparison = null; + + public static Comparison RequiredThenAlphaComparison = (ComparableOption attr1, ComparableOption attr2) => + { + if (attr1.IsOption && attr2.IsOption) + { + if (attr1.Required && !attr2.Required) + { + return -1; + } + else if (!attr1.Required && attr2.Required) + { + return 1; + } + else + { + int t = String.Compare(attr1.LongName, attr2.LongName, StringComparison.CurrentCulture); + return t; + } + } + else if (attr1.IsOption && attr2.IsValue) + { + return -1; + } + else + { + return 1; + } + }; + private const int BuilderCapacity = 128; private const int DefaultMaximumLength = 80; // default console width private readonly StringBuilder preOptionsHelp; @@ -754,14 +817,37 @@ private HelpText AddOptionsImpl( int maximumLength) { var maxLength = GetMaxLength(specifications); + + optionsHelp = new StringBuilder(BuilderCapacity); var remainingSpace = maximumLength - (maxLength + 6); - specifications.ForEach( - option => - AddOption(requiredWord, maxLength, option, remainingSpace)); + if (OptionComparison != null) + { + int i = -1; + var comparables = specifications.ToList().Select(s => + { + i++; + return ToComparableOption(s, i); + }).ToList(); + comparables.Sort(OptionComparison); + + + foreach (var comparable in comparables) + { + Specification spec = specifications.ElementAt(comparable.Index); + AddOption(requiredWord, maxLength, spec, remainingSpace); + } + } + else + { + specifications.ForEach( + option => + AddOption(requiredWord, maxLength, option, remainingSpace)); + + } return this; } @@ -998,4 +1084,4 @@ private static string FormatDefaultValue(T value) : string.Empty; } } -} \ No newline at end of file +} diff --git a/tests/CommandLine.Tests/Fakes/OPtions_HelpText_Ordering.cs b/tests/CommandLine.Tests/Fakes/OPtions_HelpText_Ordering.cs index 8e7cac70..3896ab67 100644 --- a/tests/CommandLine.Tests/Fakes/OPtions_HelpText_Ordering.cs +++ b/tests/CommandLine.Tests/Fakes/OPtions_HelpText_Ordering.cs @@ -7,42 +7,42 @@ namespace CommandLine.Tests.Fakes { [Verb("verb1")] - class Options_HelpText_Ordering_Verb1 - { - [Option('a',"alpha",Required = true)] - public string alphaOption { get; set; } - - [Option('b',"alpha2",Required = true)] - public string alphaTwoOption { get; set; } - - [Option('d',"charlie",Required = false)] - public string deltaOption { get; set; } - - [Option('c',"bravo",Required = false)] - public string charlieOption { get; set; } - - [Option('f',"foxtrot",Required = false)] - public string foxOption { get; set; } - - [Option('e',"echo",Required = false)] - public string echoOption { get; set; } - - } - - [Verb("verb2")] - class Options_HelpText_Ordering_Verb2 - { - [Option('a',"alpha",Required = true)] - public string alphaOption { get; set; } - - [Option('b',"alpha2",Required = true)] - public string alphaTwoOption { get; set; } - - [Option('c',"bravo",Required = false)] - public string charlieOption { get; set; } - - [Option('d',"charlie",Required = false)] - public string deltaOption { get; set; } - - } + class Options_HelpText_Ordering_Verb1 + { + [Option('a', "alpha", Required = true)] + public string alphaOption { get; set; } + + [Option('b', "alpha2", Required = true)] + public string alphaTwoOption { get; set; } + + [Option('d', "charlie", Required = false)] + public string deltaOption { get; set; } + + [Option('c', "bravo", Required = false)] + public string charlieOption { get; set; } + + [Option('f', "foxtrot", Required = false)] + public string foxOption { get; set; } + + [Option('e', "echo", Required = false)] + public string echoOption { get; set; } + + [Value(0)] public string someExtraOption { get; set; } + } + + [Verb("verb2")] + class Options_HelpText_Ordering_Verb2 + { + [Option('a', "alpha", Required = true)] + public string alphaOption { get; set; } + + [Option('b', "alpha2", Required = true)] + public string alphaTwoOption { get; set; } + + [Option('c', "bravo", Required = false)] + public string charlieOption { get; set; } + + [Option('d', "charlie", Required = false)] + public string deltaOption { get; set; } + } } diff --git a/tests/CommandLine.Tests/Unit/Issue482Tests.cs b/tests/CommandLine.Tests/Unit/Issue482Tests.cs index abc6414e..fb7290a6 100644 --- a/tests/CommandLine.Tests/Unit/Issue482Tests.cs +++ b/tests/CommandLine.Tests/Unit/Issue482Tests.cs @@ -28,38 +28,13 @@ public void AutoBuild_with_ordering() .WithNotParsed(errors => { throw new InvalidOperationException("Must be parsed."); }) .WithParsed(args => { ; }); - Comparison comparison = (OptionAttribute option1, OptionAttribute option2) => - { - if (option1 == null) - { - return -1; - } - - if (option2 == null) - { - return 1; - } - - if (option1.Required && !option2.Required) - { - return -1; - } - else if (!option1.Required && option2.Required) - { - return 1; - } - else - { - return String.Compare(option1.LongName, option2.LongName, StringComparison.CurrentCulture); - } - }; + Comparison comparison = HelpText.RequiredThenAlphaComparison; - var toto = HelpText.AutoBuild(parseResult, comparison, + var toto = HelpText.AutoBuild(parseResult, err => { throw new InvalidOperationException($"help text build failed. {err.ToString()}"); }, ex => { - Console.WriteLine(ex.ToString()); return null; }); @@ -74,7 +49,8 @@ public void AutoBuild_with_ordering() "-f, --foxtrot", "-e, --echo", "--help Display this help screen.", - "--version Display version information." + "--version Display version information.", + "value pos. 0" }; Assert.Equal(expected.Count,helps.Count); int i = 0; @@ -86,5 +62,7 @@ public void AutoBuild_with_ordering() ; } + + } } From 113a21c66a1ebbedfd633a32f4d25bccdc99a1ee Mon Sep 17 00:00:00 2001 From: b3b00 Date: Tue, 23 Jul 2019 11:43:39 +0200 Subject: [PATCH 04/12] HelpText fluent API, initial --- src/CommandLine/Text/HelpText.cs | 196 ++++++++++++++---- tests/CommandLine.Tests/Unit/Issue482Tests.cs | 55 +++++ 2 files changed, 215 insertions(+), 36 deletions(-) diff --git a/src/CommandLine/Text/HelpText.cs b/src/CommandLine/Text/HelpText.cs index acc67b41..0762eac9 100644 --- a/src/CommandLine/Text/HelpText.cs +++ b/src/CommandLine/Text/HelpText.cs @@ -17,9 +17,9 @@ namespace CommandLine.Text /// Provides means to format an help screen. /// You can assign it in place of a instance. /// - - - + + + public struct ComparableOption { public bool Required; @@ -28,7 +28,125 @@ public struct ComparableOption public string LongName; public int Index; } - + + public class HelpTextBuilder + { + + private Func onError; + private ParserResult parserResult; + private Func onExample; + + private bool verbsIndex = false; + + private int maxDisplayWidth = HelpText.DefaultMaximumLength; + + private Comparison optionComparison; + + internal HelpTextBuilder(ParserResult result) + { + parserResult = result; + } + + public HelpTextBuilder OnError(Func error) + { + onError = error; + return this; + } + public HelpTextBuilder OnExample(Func example) + { + onExample = example; + return this; + } + + public HelpTextBuilder WithMaxDisplayWidth(int width) { + maxDisplayWidth = width; + return this; + } + + public HelpTextBuilder WithVerbsIndex(bool index) { + verbsIndex = index; + return this; + } + + public HelpTextBuilder WithComparison(Comparison comparison) + { + optionComparison = comparison; + return this; + } + + public string Build() + { + + //TODO : call HelpText.AutoBuild according to set parameters. + + // if (onError) + // HelpText.AutoBuild(parserResult,onError,onExample,verbsIndex,maxDisplayWidth); + // HelpText.AutoBuild(parserResult,maxDisplayWidth); + + var auto = new HelpText + { + Heading = HeadingInfo.Empty, + Copyright = CopyrightInfo.Empty, + AdditionalNewLineAfterOption = true, + AddDashesToOption = !verbsIndex, + MaximumDisplayWidth = maxDisplayWidth, + OptionComparison = optionComparison + }; + + try + { + auto.Heading = HeadingInfo.Default; + auto.Copyright = CopyrightInfo.Default; + } + catch (Exception) + { + auto = onError(auto); + } + + var errors = Enumerable.Empty(); + + if (onError != null && parserResult.Tag == ParserResultType.NotParsed) + { + errors = ((NotParsed)parserResult).Errors; + + if (errors.OnlyMeaningfulOnes().Any()) + auto = onError(auto); + } + + ReflectionHelper.GetAttribute() + .Do(license => license.AddToHelpText(auto, true)); + + var usageAttr = ReflectionHelper.GetAttribute(); + var usageLines = HelpText.RenderUsageTextAsLines(parserResult, onExample).ToMaybe(); + + if (usageAttr.IsJust() || usageLines.IsJust()) + { + var heading = auto.SentenceBuilder.UsageHeadingText(); + if (heading.Length > 0) + auto.AddPreOptionsLine(heading); + } + + usageAttr.Do( + usage => usage.AddToHelpText(auto, true)); + + usageLines.Do( + lines => auto.AddPreOptionsLines(lines)); + + if ((verbsIndex && parserResult.TypeInfo.Choices.Any()) + || errors.Any(e => e.Tag == ErrorType.NoVerbSelectedError)) + { + auto.AddDashesToOption = false; + auto.AddVerbs(parserResult.TypeInfo.Choices.ToArray()); + } + else + auto.AddOptions(parserResult); + + return auto; + } + } + + + public class HelpText { @@ -48,46 +166,46 @@ ComparableOption ToComparableOption(Specification spec, int index) LongName = name, Index = index }; - + } - public static Comparison OptionComparison = null; + public Comparison OptionComparison {get; set;} = null; + + public static Comparison RequiredThenAlphaComparison = (ComparableOption attr1, ComparableOption attr2) => + { + if (attr1.IsOption && attr2.IsOption) + { + if (attr1.Required && !attr2.Required) + { + return -1; + } + else if (!attr1.Required && attr2.Required) + { + return 1; + } + else + { + int t = String.Compare(attr1.LongName, attr2.LongName, StringComparison.CurrentCulture); + return t; + } + } + else if (attr1.IsOption && attr2.IsValue) + { + return -1; + } + else + { + return 1; + } + }; - public static Comparison RequiredThenAlphaComparison = (ComparableOption attr1, ComparableOption attr2) => - { - if (attr1.IsOption && attr2.IsOption) - { - if (attr1.Required && !attr2.Required) - { - return -1; - } - else if (!attr1.Required && attr2.Required) - { - return 1; - } - else - { - int t = String.Compare(attr1.LongName, attr2.LongName, StringComparison.CurrentCulture); - return t; - } - } - else if (attr1.IsOption && attr2.IsValue) - { - return -1; - } - else - { - return 1; - } - }; - private const int BuilderCapacity = 128; - private const int DefaultMaximumLength = 80; // default console width + public const int DefaultMaximumLength = 80; // default console width /// /// The number of spaces between an option and its associated help text /// - private const int OptionToHelpTextSeparatorWidth = 4; + private const int OptionToHelpTextSeparatorWidth = 4; /// /// The width of the option prefix (either "--" or " " /// @@ -304,6 +422,12 @@ public SentenceBuilder SentenceBuilder /// If true the output style is consistent with verb commands (no dashes), otherwise it outputs options. /// The maximum width of the display. /// The parameter is not ontly a metter of formatting, it controls whether to handle verbs or options. + + public static HelpTextBuilder CreateWith(ParserResult parserResult) + { + return new HelpTextBuilder(parserResult); + } + public static HelpText AutoBuild( ParserResult parserResult, Func onError, diff --git a/tests/CommandLine.Tests/Unit/Issue482Tests.cs b/tests/CommandLine.Tests/Unit/Issue482Tests.cs index fb7290a6..6c3aded0 100644 --- a/tests/CommandLine.Tests/Unit/Issue482Tests.cs +++ b/tests/CommandLine.Tests/Unit/Issue482Tests.cs @@ -62,6 +62,61 @@ public void AutoBuild_with_ordering() ; } + + [Fact] + public void AutoBuild_with_ordering_fluent() + { + string expectedCompany = "Company"; + + + var parser = Parser.Default; + var parseResult = parser.ParseArguments( + new[] {"verb1", "--alpha", "alpaga", "--alpha2", "alala", "--charlie", "charlot"}) + .WithNotParsed(errors => { throw new InvalidOperationException("Must be parsed."); }) + .WithParsed(args => { ; }); + + Comparison comparison = HelpText.RequiredThenAlphaComparison; + + + var message = HelpText.CreateWith(parseResult) + .WithComparison(HelpText.RequiredThenAlphaComparison) + .OnError(error => { + throw new InvalidOperationException($"help text build failed. {error.ToString()}"); + }) + .OnExample(ex => + { + return null; + }) + .Build(); + + + + + + string helpMessage = message.ToString(); + var helps = helpMessage.Split(new[] {'\r', '\n'}, StringSplitOptions.RemoveEmptyEntries).Skip(2).ToList(); + List expected = new List() + { + " -a, --alpha Required.", + " -b, --alpha2 Required.", + " -c, --bravo", + " -d, --charlie", + "-e, --echo", + "-f, --foxtrot", + "--help Display this help screen.", + "--version Display version information.", + "value pos. 0" + }; + Assert.Equal(expected.Count,helps.Count); + int i = 0; + foreach (var expect in expected) + { + Assert.Equal(expect.Trim(),helps[i].Trim()); + i++; + } + + ; + } } From 6fc506db3d1d8027aa97b3bc26db4be47b4b1282 Mon Sep 17 00:00:00 2001 From: b3b00 Date: Tue, 23 Jul 2019 14:11:39 +0200 Subject: [PATCH 05/12] fluent API for help message options ordering --- src/CommandLine/Text/HelpText.cs | 132 +++++++++--------- tests/CommandLine.Tests/Unit/Issue482Tests.cs | 5 +- .../Unit/Text/HelpTextTests.cs | 2 +- 3 files changed, 69 insertions(+), 70 deletions(-) diff --git a/src/CommandLine/Text/HelpText.cs b/src/CommandLine/Text/HelpText.cs index 0762eac9..a70542b1 100644 --- a/src/CommandLine/Text/HelpText.cs +++ b/src/CommandLine/Text/HelpText.cs @@ -76,72 +76,72 @@ public HelpTextBuilder WithComparison(Comparison comparison public string Build() { - - //TODO : call HelpText.AutoBuild according to set parameters. - - // if (onError) - // HelpText.AutoBuild(parserResult,onError,onExample,verbsIndex,maxDisplayWidth); - // HelpText.AutoBuild(parserResult,maxDisplayWidth); - - var auto = new HelpText - { - Heading = HeadingInfo.Empty, - Copyright = CopyrightInfo.Empty, - AdditionalNewLineAfterOption = true, - AddDashesToOption = !verbsIndex, - MaximumDisplayWidth = maxDisplayWidth, - OptionComparison = optionComparison - }; - - try - { - auto.Heading = HeadingInfo.Default; - auto.Copyright = CopyrightInfo.Default; + if (onError != null || onExample != null || optionComparison != null) { + return HelpText.AutoBuild(parserResult,onError,onExample,verbsIndex,maxDisplayWidth,optionComparison); } - catch (Exception) - { - auto = onError(auto); + else { + return HelpText.AutoBuild(parserResult,maxDisplayWidth); } - var errors = Enumerable.Empty(); - - if (onError != null && parserResult.Tag == ParserResultType.NotParsed) - { - errors = ((NotParsed)parserResult).Errors; - - if (errors.OnlyMeaningfulOnes().Any()) - auto = onError(auto); - } - - ReflectionHelper.GetAttribute() - .Do(license => license.AddToHelpText(auto, true)); - - var usageAttr = ReflectionHelper.GetAttribute(); - var usageLines = HelpText.RenderUsageTextAsLines(parserResult, onExample).ToMaybe(); - - if (usageAttr.IsJust() || usageLines.IsJust()) - { - var heading = auto.SentenceBuilder.UsageHeadingText(); - if (heading.Length > 0) - auto.AddPreOptionsLine(heading); - } - - usageAttr.Do( - usage => usage.AddToHelpText(auto, true)); - - usageLines.Do( - lines => auto.AddPreOptionsLines(lines)); - - if ((verbsIndex && parserResult.TypeInfo.Choices.Any()) - || errors.Any(e => e.Tag == ErrorType.NoVerbSelectedError)) - { - auto.AddDashesToOption = false; - auto.AddVerbs(parserResult.TypeInfo.Choices.ToArray()); - } - else - auto.AddOptions(parserResult); - - return auto; + // var auto = new HelpText + // { + // Heading = HeadingInfo.Empty, + // Copyright = CopyrightInfo.Empty, + // AdditionalNewLineAfterOption = true, + // AddDashesToOption = !verbsIndex, + // MaximumDisplayWidth = maxDisplayWidth, + // OptionComparison = optionComparison + // }; + + // try + // { + // auto.Heading = HeadingInfo.Default; + // auto.Copyright = CopyrightInfo.Default; + // } + // catch (Exception) + // { + // auto = onError(auto); + // } + + // var errors = Enumerable.Empty(); + + // if (onError != null && parserResult.Tag == ParserResultType.NotParsed) + // { + // errors = ((NotParsed)parserResult).Errors; + + // if (errors.OnlyMeaningfulOnes().Any()) + // auto = onError(auto); + // } + + // ReflectionHelper.GetAttribute() + // .Do(license => license.AddToHelpText(auto, true)); + + // var usageAttr = ReflectionHelper.GetAttribute(); + // var usageLines = HelpText.RenderUsageTextAsLines(parserResult, onExample).ToMaybe(); + + // if (usageAttr.IsJust() || usageLines.IsJust()) + // { + // var heading = auto.SentenceBuilder.UsageHeadingText(); + // if (heading.Length > 0) + // auto.AddPreOptionsLine(heading); + // } + + // usageAttr.Do( + // usage => usage.AddToHelpText(auto, true)); + + // usageLines.Do( + // lines => auto.AddPreOptionsLines(lines)); + + // if ((verbsIndex && parserResult.TypeInfo.Choices.Any()) + // || errors.Any(e => e.Tag == ErrorType.NoVerbSelectedError)) + // { + // auto.AddDashesToOption = false; + // auto.AddVerbs(parserResult.TypeInfo.Choices.ToArray()); + // } + // else + // auto.AddOptions(parserResult); + + // return auto; } } @@ -433,7 +433,8 @@ public static HelpText AutoBuild( Func onError, Func onExample, bool verbsIndex = false, - int maxDisplayWidth = DefaultMaximumLength) + int maxDisplayWidth = DefaultMaximumLength, + Comparison comparison = null) { var auto = new HelpText { @@ -441,7 +442,8 @@ public static HelpText AutoBuild( Copyright = CopyrightInfo.Empty, AdditionalNewLineAfterOption = true, AddDashesToOption = !verbsIndex, - MaximumDisplayWidth = maxDisplayWidth + MaximumDisplayWidth = maxDisplayWidth, + OptionComparison = comparison }; try diff --git a/tests/CommandLine.Tests/Unit/Issue482Tests.cs b/tests/CommandLine.Tests/Unit/Issue482Tests.cs index 6c3aded0..2c569798 100644 --- a/tests/CommandLine.Tests/Unit/Issue482Tests.cs +++ b/tests/CommandLine.Tests/Unit/Issue482Tests.cs @@ -17,7 +17,7 @@ namespace CommandLine.Tests.Unit public class Issue482Tests { [Fact] - public void AutoBuild_with_ordering() + public void AutoBuild_without_ordering() { string expectedCompany = "Company"; @@ -28,9 +28,6 @@ public void AutoBuild_with_ordering() .WithNotParsed(errors => { throw new InvalidOperationException("Must be parsed."); }) .WithParsed(args => { ; }); - Comparison comparison = HelpText.RequiredThenAlphaComparison; - - var toto = HelpText.AutoBuild(parseResult, err => { throw new InvalidOperationException($"help text build failed. {err.ToString()}"); }, ex => diff --git a/tests/CommandLine.Tests/Unit/Text/HelpTextTests.cs b/tests/CommandLine.Tests/Unit/Text/HelpTextTests.cs index 1dd8d45f..b1edab8f 100644 --- a/tests/CommandLine.Tests/Unit/Text/HelpTextTests.cs +++ b/tests/CommandLine.Tests/Unit/Text/HelpTextTests.cs @@ -317,7 +317,7 @@ public void Invoke_AutoBuild_for_Options_returns_appropriate_formatted_text() }); // Exercize system - var helpText = HelpText.AutoBuild(fakeResult); + var helpText = HelpText.CreateWith(fakeResult).Build(); // Verify outcome var lines = helpText.ToString().ToNotEmptyLines().TrimStringArray(); From 04a9bcf59633b644d1df5614ca7e7e90ead7f3a3 Mon Sep 17 00:00:00 2001 From: b3b00 Date: Tue, 23 Jul 2019 14:50:58 +0200 Subject: [PATCH 06/12] cleaning --- src/CommandLine/Text/HelpText.cs | 18 ++-- tests/CommandLine.Tests/Unit/Issue482Tests.cs | 89 +++++++++++++++++-- 2 files changed, 94 insertions(+), 13 deletions(-) diff --git a/src/CommandLine/Text/HelpText.cs b/src/CommandLine/Text/HelpText.cs index a70542b1..cb202e3b 100644 --- a/src/CommandLine/Text/HelpText.cs +++ b/src/CommandLine/Text/HelpText.cs @@ -26,6 +26,8 @@ public struct ComparableOption public bool IsOption; public bool IsValue; public string LongName; + + public string ShortName; public int Index; } @@ -156,14 +158,14 @@ ComparableOption ToComparableOption(Specification spec, int index) OptionSpecification option = spec as OptionSpecification; ValueSpecification value = spec as ValueSpecification; bool required = option != null ? option.Required : false; - string name = option?.LongName; return new ComparableOption() { Required = required, IsOption = option != null, IsValue = value != null, - LongName = name, + LongName = option?.LongName, + ShortName = option?.ShortName, Index = index }; @@ -410,6 +412,12 @@ public SentenceBuilder SentenceBuilder get { return sentenceBuilder; } } + + public static HelpTextBuilder CreateWith(ParserResult parserResult) + { + return new HelpTextBuilder(parserResult); + } + /// /// Creates a new instance of the class using common defaults. /// @@ -421,12 +429,10 @@ public SentenceBuilder SentenceBuilder /// A delegate used to customize model used to render text block of usage examples. /// If true the output style is consistent with verb commands (no dashes), otherwise it outputs options. /// The maximum width of the display. + /// a comparison lambda to order options in help text /// The parameter is not ontly a metter of formatting, it controls whether to handle verbs or options. - public static HelpTextBuilder CreateWith(ParserResult parserResult) - { - return new HelpTextBuilder(parserResult); - } + public static HelpText AutoBuild( ParserResult parserResult, diff --git a/tests/CommandLine.Tests/Unit/Issue482Tests.cs b/tests/CommandLine.Tests/Unit/Issue482Tests.cs index 2c569798..b8138454 100644 --- a/tests/CommandLine.Tests/Unit/Issue482Tests.cs +++ b/tests/CommandLine.Tests/Unit/Issue482Tests.cs @@ -76,14 +76,89 @@ public void AutoBuild_with_ordering_fluent() var message = HelpText.CreateWith(parseResult) - .WithComparison(HelpText.RequiredThenAlphaComparison) - .OnError(error => { - throw new InvalidOperationException($"help text build failed. {error.ToString()}"); - }) - .OnExample(ex => - { - return null; + .WithComparison(HelpText.RequiredThenAlphaComparison) + .OnError(error => { + throw new InvalidOperationException($"help text build failed. {error.ToString()}"); }) + .OnExample(ex => + { + return null; + }) + .Build(); + + + + + + string helpMessage = message.ToString(); + var helps = helpMessage.Split(new[] {'\r', '\n'}, StringSplitOptions.RemoveEmptyEntries).Skip(2).ToList(); + List expected = new List() + { + " -a, --alpha Required.", + " -b, --alpha2 Required.", + " -c, --bravo", + " -d, --charlie", + "-e, --echo", + "-f, --foxtrot", + "--help Display this help screen.", + "--version Display version information.", + "value pos. 0" + }; + Assert.Equal(expected.Count,helps.Count); + int i = 0; + foreach (var expect in expected) + { + Assert.Equal(expect.Trim(),helps[i].Trim()); + i++; + } + + ; + } + + [Fact] + public void otherOrdering() + { + string expectedCompany = "Company"; + + + var parser = Parser.Default; + var parseResult = parser.ParseArguments( + new[] {"verb1", "--alpha", "alpaga", "--alpha2", "alala", "--charlie", "charlot"}) + .WithNotParsed(errors => { throw new InvalidOperationException("Must be parsed."); }) + .WithParsed(args => { ; }); + +Comparison orderOnShortName = (ComparableOption attr1, ComparableOption attr2) => + { + if (attr1.IsOption && attr2.IsOption) + { + if (attr1.Required && !attr2.Required) + { + return -1; + } + else if (!attr1.Required && attr2.Required) + { + return 1; + } + else + { + int t = String.Compare(attr1.ShortName, attr2.ShortName, StringComparison.CurrentCulture); + return t; + } + } + else if (attr1.IsOption && attr2.IsValue) + { + return -1; + } + else + { + return 1; + } + }; + + + + var message = HelpText.CreateWith(parseResult) + .WithComparison(orderOnShortName) .Build(); From db7c20ae9a392af153993182f1075fa71d773ac5 Mon Sep 17 00:00:00 2001 From: b3b00 Date: Wed, 24 Jul 2019 07:58:58 +0200 Subject: [PATCH 07/12] correct UT --- tests/CommandLine.Tests/Unit/Issue482Tests.cs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/tests/CommandLine.Tests/Unit/Issue482Tests.cs b/tests/CommandLine.Tests/Unit/Issue482Tests.cs index b8138454..dad84caa 100644 --- a/tests/CommandLine.Tests/Unit/Issue482Tests.cs +++ b/tests/CommandLine.Tests/Unit/Issue482Tests.cs @@ -141,6 +141,12 @@ public void otherOrdering() } else { + if (string.IsNullOrEmpty(attr1.ShortName) && !string.IsNullOrEmpty(attr2.ShortName)) { + return 1; + } + else if (!string.IsNullOrEmpty(attr1.ShortName) && string.IsNullOrEmpty(attr2.ShortName)) { + return -1; + } int t = String.Compare(attr1.ShortName, attr2.ShortName, StringComparison.CurrentCulture); return t; } @@ -170,12 +176,12 @@ public void otherOrdering() List expected = new List() { " -a, --alpha Required.", - " -b, --alpha2 Required.", + " -b, --alpha2 Required.", " -c, --bravo", " -d, --charlie", "-e, --echo", - "-f, --foxtrot", - "--help Display this help screen.", + "-f, --foxtrot", + "--help Display this help screen.", "--version Display version information.", "value pos. 0" }; From a1ff10093c9579b3d755bd909285d40e1a8f9359 Mon Sep 17 00:00:00 2001 From: b3b00 Date: Wed, 24 Jul 2019 10:39:53 +0200 Subject: [PATCH 08/12] Revert "HelpText fluent API, initial" This reverts commit 113a21c66a1ebbedfd633a32f4d25bccdc99a1ee. --- src/CommandLine/Text/HelpText.cs | 199 +++--------------- tests/CommandLine.Tests/Unit/Issue482Tests.cs | 175 ++++++++------- .../Unit/Text/HelpTextTests.cs | 2 +- 3 files changed, 123 insertions(+), 253 deletions(-) diff --git a/src/CommandLine/Text/HelpText.cs b/src/CommandLine/Text/HelpText.cs index cb202e3b..cae46ca4 100644 --- a/src/CommandLine/Text/HelpText.cs +++ b/src/CommandLine/Text/HelpText.cs @@ -17,138 +17,19 @@ namespace CommandLine.Text /// Provides means to format an help screen. /// You can assign it in place of a instance. /// - - - + + + public struct ComparableOption { public bool Required; public bool IsOption; public bool IsValue; public string LongName; - public string ShortName; public int Index; } - - public class HelpTextBuilder - { - - private Func onError; - private ParserResult parserResult; - private Func onExample; - - private bool verbsIndex = false; - - private int maxDisplayWidth = HelpText.DefaultMaximumLength; - - private Comparison optionComparison; - - internal HelpTextBuilder(ParserResult result) - { - parserResult = result; - } - - public HelpTextBuilder OnError(Func error) - { - onError = error; - return this; - } - public HelpTextBuilder OnExample(Func example) - { - onExample = example; - return this; - } - - public HelpTextBuilder WithMaxDisplayWidth(int width) { - maxDisplayWidth = width; - return this; - } - - public HelpTextBuilder WithVerbsIndex(bool index) { - verbsIndex = index; - return this; - } - - public HelpTextBuilder WithComparison(Comparison comparison) - { - optionComparison = comparison; - return this; - } - - public string Build() - { - if (onError != null || onExample != null || optionComparison != null) { - return HelpText.AutoBuild(parserResult,onError,onExample,verbsIndex,maxDisplayWidth,optionComparison); - } - else { - return HelpText.AutoBuild(parserResult,maxDisplayWidth); - } - - // var auto = new HelpText - // { - // Heading = HeadingInfo.Empty, - // Copyright = CopyrightInfo.Empty, - // AdditionalNewLineAfterOption = true, - // AddDashesToOption = !verbsIndex, - // MaximumDisplayWidth = maxDisplayWidth, - // OptionComparison = optionComparison - // }; - - // try - // { - // auto.Heading = HeadingInfo.Default; - // auto.Copyright = CopyrightInfo.Default; - // } - // catch (Exception) - // { - // auto = onError(auto); - // } - - // var errors = Enumerable.Empty(); - - // if (onError != null && parserResult.Tag == ParserResultType.NotParsed) - // { - // errors = ((NotParsed)parserResult).Errors; - - // if (errors.OnlyMeaningfulOnes().Any()) - // auto = onError(auto); - // } - - // ReflectionHelper.GetAttribute() - // .Do(license => license.AddToHelpText(auto, true)); - - // var usageAttr = ReflectionHelper.GetAttribute(); - // var usageLines = HelpText.RenderUsageTextAsLines(parserResult, onExample).ToMaybe(); - - // if (usageAttr.IsJust() || usageLines.IsJust()) - // { - // var heading = auto.SentenceBuilder.UsageHeadingText(); - // if (heading.Length > 0) - // auto.AddPreOptionsLine(heading); - // } - - // usageAttr.Do( - // usage => usage.AddToHelpText(auto, true)); - - // usageLines.Do( - // lines => auto.AddPreOptionsLines(lines)); - - // if ((verbsIndex && parserResult.TypeInfo.Choices.Any()) - // || errors.Any(e => e.Tag == ErrorType.NoVerbSelectedError)) - // { - // auto.AddDashesToOption = false; - // auto.AddVerbs(parserResult.TypeInfo.Choices.ToArray()); - // } - // else - // auto.AddOptions(parserResult); - - // return auto; - } - } - - - + public class HelpText { @@ -168,46 +49,45 @@ ComparableOption ToComparableOption(Specification spec, int index) ShortName = option?.ShortName, Index = index }; - } - public Comparison OptionComparison {get; set;} = null; - - public static Comparison RequiredThenAlphaComparison = (ComparableOption attr1, ComparableOption attr2) => - { - if (attr1.IsOption && attr2.IsOption) - { - if (attr1.Required && !attr2.Required) - { - return -1; - } - else if (!attr1.Required && attr2.Required) - { - return 1; - } - else - { - int t = String.Compare(attr1.LongName, attr2.LongName, StringComparison.CurrentCulture); - return t; - } - } - else if (attr1.IsOption && attr2.IsValue) - { - return -1; - } - else - { - return 1; - } - }; + public Comparison OptionComparison = null; + public static Comparison RequiredThenAlphaComparison = (ComparableOption attr1, ComparableOption attr2) => + { + if (attr1.IsOption && attr2.IsOption) + { + if (attr1.Required && !attr2.Required) + { + return -1; + } + else if (!attr1.Required && attr2.Required) + { + return 1; + } + else + { + int t = String.Compare(attr1.LongName, attr2.LongName, StringComparison.CurrentCulture); + return t; + } + } + else if (attr1.IsOption && attr2.IsValue) + { + return -1; + } + else + { + return 1; + } + }; + private const int BuilderCapacity = 128; - public const int DefaultMaximumLength = 80; // default console width + private const int DefaultMaximumLength = 80; // default console width /// /// The number of spaces between an option and its associated help text /// - private const int OptionToHelpTextSeparatorWidth = 4; + private const int OptionToHelpTextSeparatorWidth = 4; /// /// The width of the option prefix (either "--" or " " /// @@ -412,12 +292,6 @@ public SentenceBuilder SentenceBuilder get { return sentenceBuilder; } } - - public static HelpTextBuilder CreateWith(ParserResult parserResult) - { - return new HelpTextBuilder(parserResult); - } - /// /// Creates a new instance of the class using common defaults. /// @@ -431,9 +305,6 @@ public static HelpTextBuilder CreateWith(ParserResult parserResult) /// The maximum width of the display. /// a comparison lambda to order options in help text /// The parameter is not ontly a metter of formatting, it controls whether to handle verbs or options. - - - public static HelpText AutoBuild( ParserResult parserResult, Func onError, diff --git a/tests/CommandLine.Tests/Unit/Issue482Tests.cs b/tests/CommandLine.Tests/Unit/Issue482Tests.cs index dad84caa..6f847ba5 100644 --- a/tests/CommandLine.Tests/Unit/Issue482Tests.cs +++ b/tests/CommandLine.Tests/Unit/Issue482Tests.cs @@ -24,19 +24,19 @@ public void AutoBuild_without_ordering() var parser = Parser.Default; var parseResult = parser.ParseArguments( - new[] {"verb1", "--alpha", "alpaga", "--alpha2", "alala", "--charlie", "charlot"}) + new[] { "verb1", "--alpha", "alpaga", "--alpha2", "alala", "--charlie", "charlot" }) .WithNotParsed(errors => { throw new InvalidOperationException("Must be parsed."); }) - .WithParsed(args => { ; }); + .WithParsed(args => {; }); - var toto = HelpText.AutoBuild(parseResult, + var message = HelpText.AutoBuild(parseResult, err => { throw new InvalidOperationException($"help text build failed. {err.ToString()}"); }, ex => { return null; }); - string helpMessage = toto.ToString(); - var helps = helpMessage.Split(new[] {'\r', '\n'}, StringSplitOptions.RemoveEmptyEntries).Skip(2).ToList(); + string helpMessage = message.ToString(); + var helps = helpMessage.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries).Skip(2).ToList(); List expected = new List() { " -a, --alpha Required.", @@ -47,13 +47,13 @@ public void AutoBuild_without_ordering() "-e, --echo", "--help Display this help screen.", "--version Display version information.", - "value pos. 0" + "value pos. 0" }; - Assert.Equal(expected.Count,helps.Count); + Assert.Equal(expected.Count, helps.Count); int i = 0; foreach (var expect in expected) { - Assert.Equal(expect.Trim(),helps[i].Trim()); + Assert.Equal(expect.Trim(), helps[i].Trim()); i++; } @@ -61,141 +61,140 @@ public void AutoBuild_without_ordering() } [Fact] - public void AutoBuild_with_ordering_fluent() + public void AutoBuild_with_ordering() { string expectedCompany = "Company"; var parser = Parser.Default; var parseResult = parser.ParseArguments( - new[] {"verb1", "--alpha", "alpaga", "--alpha2", "alala", "--charlie", "charlot"}) + new[] { "verb1", "--alpha", "alpaga", "--alpha2", "alala", "--charlie", "charlot" }) .WithNotParsed(errors => { throw new InvalidOperationException("Must be parsed."); }) - .WithParsed(args => { ; }); + .WithParsed(args => {; }); Comparison comparison = HelpText.RequiredThenAlphaComparison; - - var message = HelpText.CreateWith(parseResult) - .WithComparison(HelpText.RequiredThenAlphaComparison) - .OnError(error => { - throw new InvalidOperationException($"help text build failed. {error.ToString()}"); - }) - .OnExample(ex => + string message = HelpText.AutoBuild(parseResult, error => + { + throw new InvalidOperationException($"help text build failed. {error.ToString()}"); + }, + ex => { return null; - }) - .Build(); + }, + false, + 80, + comparison); - - - string helpMessage = message.ToString(); - var helps = helpMessage.Split(new[] {'\r', '\n'}, StringSplitOptions.RemoveEmptyEntries).Skip(2).ToList(); + var helps = helpMessage.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries).Skip(2).ToList(); List expected = new List() { " -a, --alpha Required.", - " -b, --alpha2 Required.", + " -b, --alpha2 Required.", " -c, --bravo", " -d, --charlie", "-e, --echo", "-f, --foxtrot", "--help Display this help screen.", "--version Display version information.", - "value pos. 0" + "value pos. 0" }; - Assert.Equal(expected.Count,helps.Count); + Assert.Equal(expected.Count, helps.Count); int i = 0; foreach (var expect in expected) { - Assert.Equal(expect.Trim(),helps[i].Trim()); + Assert.Equal(expect.Trim(), helps[i].Trim()); i++; } ; } - [Fact] - public void otherOrdering() + [Fact] + public void AutoBuild_with_ordering_on_shortName() { string expectedCompany = "Company"; var parser = Parser.Default; var parseResult = parser.ParseArguments( - new[] {"verb1", "--alpha", "alpaga", "--alpha2", "alala", "--charlie", "charlot"}) + new[] { "verb1", "--alpha", "alpaga", "--alpha2", "alala", "--charlie", "charlot" }) .WithNotParsed(errors => { throw new InvalidOperationException("Must be parsed."); }) - .WithParsed(args => { ; }); - -Comparison orderOnShortName = (ComparableOption attr1, ComparableOption attr2) => - { - if (attr1.IsOption && attr2.IsOption) - { - if (attr1.Required && !attr2.Required) - { - return -1; - } - else if (!attr1.Required && attr2.Required) - { - return 1; - } - else - { - if (string.IsNullOrEmpty(attr1.ShortName) && !string.IsNullOrEmpty(attr2.ShortName)) { - return 1; - } - else if (!string.IsNullOrEmpty(attr1.ShortName) && string.IsNullOrEmpty(attr2.ShortName)) { - return -1; - } - int t = String.Compare(attr1.ShortName, attr2.ShortName, StringComparison.CurrentCulture); - return t; - } - } - else if (attr1.IsOption && attr2.IsValue) - { - return -1; - } - else - { - return 1; - } - }; - - - - var message = HelpText.CreateWith(parseResult) - .WithComparison(orderOnShortName) - .Build(); - - - - - - string helpMessage = message.ToString(); - var helps = helpMessage.Split(new[] {'\r', '\n'}, StringSplitOptions.RemoveEmptyEntries).Skip(2).ToList(); + .WithParsed(args => {; }); + + Comparison orderOnShortName = (ComparableOption attr1, ComparableOption attr2) => + { + if (attr1.IsOption && attr2.IsOption) + { + if (attr1.Required && !attr2.Required) + { + return -1; + } + else if (!attr1.Required && attr2.Required) + { + return 1; + } + else + { + if (string.IsNullOrEmpty(attr1.ShortName) && !string.IsNullOrEmpty(attr2.ShortName)) + { + return 1; + } + else if (!string.IsNullOrEmpty(attr1.ShortName) && string.IsNullOrEmpty(attr2.ShortName)) + { + return -1; + } + int t = String.Compare(attr1.ShortName, attr2.ShortName, StringComparison.CurrentCulture); + return t; + } + } + else if (attr1.IsOption && attr2.IsValue) + { + return -1; + } + else + { + return 1; + } + }; + + string message = HelpText.AutoBuild(parseResult, error => + { + throw new InvalidOperationException($"help text build failed. {error.ToString()}"); + }, + ex => + { + return null; + }, + false, + 80, + orderOnShortName); + + + var helps = message.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries).Skip(2).ToList(); List expected = new List() { " -a, --alpha Required.", - " -b, --alpha2 Required.", + " -b, --alpha2 Required.", " -c, --bravo", " -d, --charlie", "-e, --echo", - "-f, --foxtrot", + "-f, --foxtrot", "--help Display this help screen.", "--version Display version information.", - "value pos. 0" + "value pos. 0" }; - Assert.Equal(expected.Count,helps.Count); + Assert.Equal(expected.Count, helps.Count); int i = 0; foreach (var expect in expected) { - Assert.Equal(expect.Trim(),helps[i].Trim()); + Assert.Equal(expect.Trim(), helps[i].Trim()); i++; } - - ; } - - + + } } diff --git a/tests/CommandLine.Tests/Unit/Text/HelpTextTests.cs b/tests/CommandLine.Tests/Unit/Text/HelpTextTests.cs index b1edab8f..1dd8d45f 100644 --- a/tests/CommandLine.Tests/Unit/Text/HelpTextTests.cs +++ b/tests/CommandLine.Tests/Unit/Text/HelpTextTests.cs @@ -317,7 +317,7 @@ public void Invoke_AutoBuild_for_Options_returns_appropriate_formatted_text() }); // Exercize system - var helpText = HelpText.CreateWith(fakeResult).Build(); + var helpText = HelpText.AutoBuild(fakeResult); // Verify outcome var lines = helpText.ToString().ToNotEmptyLines().TrimStringArray(); From 727f10c6278385f8bebf48bbaa309268cb050ebd Mon Sep 17 00:00:00 2001 From: b3b00 Date: Thu, 25 Jul 2019 08:06:16 +0200 Subject: [PATCH 09/12] correction after Pull-Request remarks --- src/CommandLine/Text/HelpText.cs | 17 +++++----- tests/CommandLine.Tests/Unit/Issue482Tests.cs | 34 +++++++------------ 2 files changed, 21 insertions(+), 30 deletions(-) diff --git a/src/CommandLine/Text/HelpText.cs b/src/CommandLine/Text/HelpText.cs index cae46ca4..787b82ab 100644 --- a/src/CommandLine/Text/HelpText.cs +++ b/src/CommandLine/Text/HelpText.cs @@ -33,26 +33,27 @@ public struct ComparableOption public class HelpText { + #region ordering ComparableOption ToComparableOption(Specification spec, int index) { OptionSpecification option = spec as OptionSpecification; ValueSpecification value = spec as ValueSpecification; - bool required = option != null ? option.Required : false; + bool required = option?.Required ?? false; return new ComparableOption() { Required = required, IsOption = option != null, IsValue = value != null, - LongName = option?.LongName, + LongName = option?.LongName ?? value?.MetaName, ShortName = option?.ShortName, Index = index }; } - public Comparison OptionComparison = null; + public Comparison OptionComparison { get; set; } = null; public static Comparison RequiredThenAlphaComparison = (ComparableOption attr1, ComparableOption attr2) => { @@ -66,11 +67,9 @@ ComparableOption ToComparableOption(Specification spec, int index) { return 1; } - else - { - int t = String.Compare(attr1.LongName, attr2.LongName, StringComparison.CurrentCulture); - return t; - } + + return String.Compare(attr1.LongName, attr2.LongName, StringComparison.Ordinal); + } else if (attr1.IsOption && attr2.IsValue) { @@ -82,6 +81,8 @@ ComparableOption ToComparableOption(Specification spec, int index) } }; + #endregion + private const int BuilderCapacity = 128; private const int DefaultMaximumLength = 80; // default console width /// diff --git a/tests/CommandLine.Tests/Unit/Issue482Tests.cs b/tests/CommandLine.Tests/Unit/Issue482Tests.cs index 6f847ba5..d94feab1 100644 --- a/tests/CommandLine.Tests/Unit/Issue482Tests.cs +++ b/tests/CommandLine.Tests/Unit/Issue482Tests.cs @@ -74,18 +74,11 @@ public void AutoBuild_with_ordering() Comparison comparison = HelpText.RequiredThenAlphaComparison; - string message = HelpText.AutoBuild(parseResult, error => - { - throw new InvalidOperationException($"help text build failed. {error.ToString()}"); - }, - ex => - { - return null; - }, - false, - 80, - comparison); - + string message = HelpText.AutoBuild(parseResult, + error => {return null;}, + ex => { return null;}, + comparison:comparison); + string helpMessage = message.ToString(); var helps = helpMessage.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries).Skip(2).ToList(); @@ -146,8 +139,7 @@ public void AutoBuild_with_ordering_on_shortName() { return -1; } - int t = String.Compare(attr1.ShortName, attr2.ShortName, StringComparison.CurrentCulture); - return t; + return String.Compare(attr1.ShortName, attr2.ShortName, StringComparison.Ordinal); } } else if (attr1.IsOption && attr2.IsValue) @@ -160,14 +152,12 @@ public void AutoBuild_with_ordering_on_shortName() } }; - string message = HelpText.AutoBuild(parseResult, error => - { - throw new InvalidOperationException($"help text build failed. {error.ToString()}"); - }, - ex => - { - return null; - }, + string message = HelpText.AutoBuild(parseResult, + error => + { + throw new InvalidOperationException($"help text build failed. {error.ToString()}"); + }, + ex => { return null; }, false, 80, orderOnShortName); From 59db0cdff0d44fde56b8579856f269744b0c05e2 Mon Sep 17 00:00:00 2001 From: b3b00 Date: Fri, 26 Jul 2019 10:46:01 +0200 Subject: [PATCH 10/12] set comparison on error action --- tests/CommandLine.Tests/Unit/Issue482Tests.cs | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/tests/CommandLine.Tests/Unit/Issue482Tests.cs b/tests/CommandLine.Tests/Unit/Issue482Tests.cs index d94feab1..2e824d80 100644 --- a/tests/CommandLine.Tests/Unit/Issue482Tests.cs +++ b/tests/CommandLine.Tests/Unit/Issue482Tests.cs @@ -29,11 +29,13 @@ public void AutoBuild_without_ordering() .WithParsed(args => {; }); var message = HelpText.AutoBuild(parseResult, - err => { throw new InvalidOperationException($"help text build failed. {err.ToString()}"); }, - ex => + error => { - return null; - }); + error.OptionComparison = HelpText.RequiredThenAlphaComparison; + return error; + }, + ex => ex + ); string helpMessage = message.ToString(); var helps = helpMessage.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries).Skip(2).ToList(); @@ -74,10 +76,14 @@ public void AutoBuild_with_ordering() Comparison comparison = HelpText.RequiredThenAlphaComparison; - string message = HelpText.AutoBuild(parseResult, - error => {return null;}, - ex => { return null;}, - comparison:comparison); + string message = HelpText.AutoBuild(parseResult, + error => + { + error.OptionComparison = HelpText.RequiredThenAlphaComparison; + return error; + }, + ex => ex, + comparison: comparison); string helpMessage = message.ToString(); @@ -152,12 +158,13 @@ public void AutoBuild_with_ordering_on_shortName() } }; - string message = HelpText.AutoBuild(parseResult, + string message = HelpText.AutoBuild(parseResult, error => { - throw new InvalidOperationException($"help text build failed. {error.ToString()}"); + error.OptionComparison = orderOnShortName; + return error; }, - ex => { return null; }, + ex => ex, false, 80, orderOnShortName); From cff9fd1b4c1cf9e6c8a0c86ebcf2dac5b40e9fd2 Mon Sep 17 00:00:00 2001 From: b3b00 Date: Fri, 26 Jul 2019 12:03:56 +0200 Subject: [PATCH 11/12] fix --- tests/CommandLine.Tests/Unit/Issue482Tests.cs | 25 ++++++++----------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/tests/CommandLine.Tests/Unit/Issue482Tests.cs b/tests/CommandLine.Tests/Unit/Issue482Tests.cs index 2e824d80..61bc1f25 100644 --- a/tests/CommandLine.Tests/Unit/Issue482Tests.cs +++ b/tests/CommandLine.Tests/Unit/Issue482Tests.cs @@ -24,16 +24,12 @@ public void AutoBuild_without_ordering() var parser = Parser.Default; var parseResult = parser.ParseArguments( - new[] { "verb1", "--alpha", "alpaga", "--alpha2", "alala", "--charlie", "charlot" }) - .WithNotParsed(errors => { throw new InvalidOperationException("Must be parsed."); }) + new[] { "verb1", "--help" }) + .WithNotParsed(errors => { ; }) .WithParsed(args => {; }); var message = HelpText.AutoBuild(parseResult, - error => - { - error.OptionComparison = HelpText.RequiredThenAlphaComparison; - return error; - }, + error =>error, ex => ex ); @@ -70,8 +66,8 @@ public void AutoBuild_with_ordering() var parser = Parser.Default; var parseResult = parser.ParseArguments( - new[] { "verb1", "--alpha", "alpaga", "--alpha2", "alala", "--charlie", "charlot" }) - .WithNotParsed(errors => { throw new InvalidOperationException("Must be parsed."); }) + new[] { "verb1", "--help" }) + .WithNotParsed(errors => { ; }) .WithParsed(args => {; }); Comparison comparison = HelpText.RequiredThenAlphaComparison; @@ -82,8 +78,7 @@ public void AutoBuild_with_ordering() error.OptionComparison = HelpText.RequiredThenAlphaComparison; return error; }, - ex => ex, - comparison: comparison); + ex => ex); string helpMessage = message.ToString(); @@ -119,8 +114,8 @@ public void AutoBuild_with_ordering_on_shortName() var parser = Parser.Default; var parseResult = parser.ParseArguments( - new[] { "verb1", "--alpha", "alpaga", "--alpha2", "alala", "--charlie", "charlot" }) - .WithNotParsed(errors => { throw new InvalidOperationException("Must be parsed."); }) + new[] { "verb1", "--help" }) + .WithNotParsed(errors => { ; }) .WithParsed(args => {; }); Comparison orderOnShortName = (ComparableOption attr1, ComparableOption attr2) => @@ -166,8 +161,8 @@ public void AutoBuild_with_ordering_on_shortName() }, ex => ex, false, - 80, - orderOnShortName); + 80 + ); var helps = message.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries).Skip(2).ToList(); From 11c3a6e68d9b39cea078592be2f3c56838ce5357 Mon Sep 17 00:00:00 2001 From: b3b00 Date: Mon, 29 Jul 2019 16:54:24 +0200 Subject: [PATCH 12/12] cleaning --- src/CommandLine/Text/HelpText.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/CommandLine/Text/HelpText.cs b/src/CommandLine/Text/HelpText.cs index f0a3095c..b287a6e8 100644 --- a/src/CommandLine/Text/HelpText.cs +++ b/src/CommandLine/Text/HelpText.cs @@ -311,8 +311,7 @@ public static HelpText AutoBuild( Func onError, Func onExample, bool verbsIndex = false, - int maxDisplayWidth = DefaultMaximumLength, - Comparison comparison = null) + int maxDisplayWidth = DefaultMaximumLength) { var auto = new HelpText { @@ -320,8 +319,7 @@ public static HelpText AutoBuild( Copyright = CopyrightInfo.Empty, AdditionalNewLineAfterOption = true, AddDashesToOption = !verbsIndex, - MaximumDisplayWidth = maxDisplayWidth, - OptionComparison = comparison + MaximumDisplayWidth = maxDisplayWidth }; try