From c5ba0d7dcca299cb4b86ac2f8f26cf020ced1eb0 Mon Sep 17 00:00:00 2001 From: x789 <14997061+x789@users.noreply.github.com> Date: Mon, 17 Jun 2019 14:34:08 +0200 Subject: [PATCH] propagate parser-settings to HelpText This fixes issues #414 and #455 (value of AutoHelp and AutoVersion are ignored by HelpText) --- src/CommandLine/Parser.cs | 11 +- src/CommandLine/Text/HelpText.cs | 54 ++++++++- tests/CommandLine.Tests/Unit/ParserTests.cs | 112 ++++++++++++++++++ .../Unit/Text/HelpTextTests.cs | 55 +++++++-- 4 files changed, 211 insertions(+), 21 deletions(-) diff --git a/src/CommandLine/Parser.cs b/src/CommandLine/Parser.cs index 8f4bd049..8c0b7732 100644 --- a/src/CommandLine/Parser.cs +++ b/src/CommandLine/Parser.cs @@ -194,16 +194,15 @@ private static ParserResult MakeParserResult(ParserResult parserResult, { return DisplayHelp( parserResult, - settings.HelpWriter, - settings.MaximumDisplayWidth); + settings); } - private static ParserResult DisplayHelp(ParserResult parserResult, TextWriter helpWriter, int maxDisplayWidth) + private static ParserResult DisplayHelp(ParserResult parserResult, ParserSettings settings) { parserResult.WithNotParsed( errors => - Maybe.Merge(errors.ToMaybe(), helpWriter.ToMaybe()) - .Do((_, writer) => writer.Write(HelpText.AutoBuild(parserResult, maxDisplayWidth))) + Maybe.Merge(errors.ToMaybe(), settings.HelpWriter.ToMaybe()) + .Do((_, writer) => writer.Write(HelpText.AutoBuild(parserResult, settings))) ); return parserResult; @@ -229,4 +228,4 @@ private void Dispose(bool disposing) } } } -} \ No newline at end of file +} diff --git a/src/CommandLine/Text/HelpText.cs b/src/CommandLine/Text/HelpText.cs index cd11a475..ccf229b7 100644 --- a/src/CommandLine/Text/HelpText.cs +++ b/src/CommandLine/Text/HelpText.cs @@ -235,6 +235,29 @@ public static HelpText AutoBuild( Func onExample, bool verbsIndex = false, int maxDisplayWidth = DefaultMaximumLength) + { + var settings = new ParserSettings() { MaximumDisplayWidth = maxDisplayWidth }; + return HelpText.AutoBuild(parserResult, onError, onExample, settings, verbsIndex); + } + + /// + /// Creates a new instance of the class using common defaults. + /// + /// + /// An instance of class. + /// + /// The containing the instance that collected command line arguments parsed with class. + /// A delegate used to customize the text block of reporting parsing errors text block. + /// 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 parser settings + /// 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, + Func onExample, + ParserSettings settings, + bool verbsIndex = false) { var auto = new HelpText { @@ -242,7 +265,9 @@ public static HelpText AutoBuild( Copyright = CopyrightInfo.Empty, AdditionalNewLineAfterOption = true, AddDashesToOption = !verbsIndex, - MaximumDisplayWidth = maxDisplayWidth + MaximumDisplayWidth = settings.MaximumDisplayWidth, + AutoHelp = settings.AutoHelp, + AutoVersion = settings.AutoVersion }; try @@ -308,6 +333,23 @@ public static HelpText AutoBuild( /// This feature is meant to be invoked automatically by the parser, setting the HelpWriter property /// of . public static HelpText AutoBuild(ParserResult parserResult, int maxDisplayWidth = DefaultMaximumLength) + { + var settings = new ParserSettings() { MaximumDisplayWidth = maxDisplayWidth }; + return HelpText.AutoBuild(parserResult, settings); + } + + /// + /// Creates a new instance of the class, + /// automatically handling verbs or options scenario. + /// + /// The containing the instance that collected command line arguments parsed with class. + /// The parser settings. + /// + /// An instance of class. + /// + /// This feature is meant to be invoked automatically by the parser, setting the HelpWriter property + /// of . + public static HelpText AutoBuild(ParserResult parserResult, ParserSettings settings) { if (parserResult.Tag != ParserResultType.NotParsed) throw new ArgumentException("Excepting NotParsed type.", "parserResult"); @@ -315,16 +357,16 @@ public static HelpText AutoBuild(ParserResult parserResult, int maxDisplay var errors = ((NotParsed)parserResult).Errors; if (errors.Any(e => e.Tag == ErrorType.VersionRequestedError)) - return new HelpText(HeadingInfo.Default){MaximumDisplayWidth = maxDisplayWidth }.AddPreOptionsLine(Environment.NewLine); + return new HelpText(HeadingInfo.Default){MaximumDisplayWidth = settings.MaximumDisplayWidth, AutoHelp = settings.AutoHelp, AutoVersion = settings.AutoVersion }.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, current => DefaultParsingErrorsHandler(parserResult, current), e => e, settings); 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, current => DefaultParsingErrorsHandler(pr, current), e => e, settings) + : AutoBuild(parserResult, current => DefaultParsingErrorsHandler(parserResult, current), e => e, settings, true); } /// @@ -998,4 +1040,4 @@ private static string FormatDefaultValue(T value) : string.Empty; } } -} \ No newline at end of file +} diff --git a/tests/CommandLine.Tests/Unit/ParserTests.cs b/tests/CommandLine.Tests/Unit/ParserTests.cs index c183c47d..3e9e8fa1 100644 --- a/tests/CommandLine.Tests/Unit/ParserTests.cs +++ b/tests/CommandLine.Tests/Unit/ParserTests.cs @@ -860,5 +860,117 @@ public void Parse_options_with_shuffled_index_values() Assert.Equal("two", args.Arg2); }); } + + [Fact] + // Tests a fix for issue #455 + public void Help_screen_does_not_show_help_verb_if_AutoHelp_is_disabled() + { + var output = new StringWriter(); + var sut = new Parser(config => { config.AutoHelp = false; config.HelpWriter = output; }); + + sut.ParseArguments(new string[] { }); + + var helpText = output.ToString(); + Assert.DoesNotContain("help", helpText, StringComparison.InvariantCulture); + Assert.DoesNotContain("Display more information on a specific command", helpText, StringComparison.InvariantCulture); + } + + [Fact] + // Tests a fix for issue #455 + public void Help_screen_does_not_show_help_option_if_AutoHelp_is_disabled() + { + var output = new StringWriter(); + var sut = new Parser(config => { config.AutoHelp = false; config.HelpWriter = output; }); + + sut.ParseArguments(new string[] { }); + + var helpText = output.ToString(); + Assert.DoesNotContain("--help", helpText, StringComparison.InvariantCulture); + Assert.DoesNotContain("Display this help screen.", helpText, StringComparison.InvariantCulture); + } + + [Fact] + // Tests a fix for issue #455 + public void Help_screen_shows_help_verb_if_AutoHelp_is_enabled() + { + var output = new StringWriter(); + var sut = new Parser(config => { config.AutoHelp = true; config.HelpWriter = output; }); + + sut.ParseArguments(new string[] { }); + + var helpText = output.ToString(); + Assert.Contains("help", helpText, StringComparison.InvariantCulture); + Assert.Contains("Display more information on a specific command", helpText, StringComparison.InvariantCulture); + } + + [Fact] + // Tests a fix for issue #455 + public void Help_screen_shows_help_option_if_AutoHelp_is_enabled() + { + var output = new StringWriter(); + var sut = new Parser(config => { config.AutoHelp = true; config.HelpWriter = output; }); + + sut.ParseArguments(new string[] { }); + + var helpText = output.ToString(); + Assert.Contains("help", helpText, StringComparison.InvariantCulture); + Assert.Contains("Display this help screen.", helpText, StringComparison.InvariantCulture); + } + + [Fact] + // Tests a fix for issue #414 + public void Help_screen_does_not_show_version_verb_if_AutoVersion_is_disabled() + { + var output = new StringWriter(); + var sut = new Parser(config => { config.AutoVersion = false; config.HelpWriter = output; }); + + sut.ParseArguments(new string[] { }); + + var helpText = output.ToString(); + Assert.DoesNotContain("version", helpText, StringComparison.InvariantCulture); + Assert.DoesNotContain("Display version information.", helpText, StringComparison.InvariantCulture); + } + + [Fact] + // Tests a fix for issue #414 + public void Help_screen_does_not_show_version_option_if_AutoVersion_is_disabled() + { + var output = new StringWriter(); + var sut = new Parser(config => { config.AutoVersion = false; config.HelpWriter = output; }); + + sut.ParseArguments(new string[] { }); + + var helpText = output.ToString(); + Assert.DoesNotContain("--version", helpText, StringComparison.InvariantCulture); + Assert.DoesNotContain("Display version information.", helpText, StringComparison.InvariantCulture); + } + + [Fact] + // Tests a fix for issue #414 + public void Help_screen_shows_version_verb_if_AutoVersion_is_enabled() + { + var output = new StringWriter(); + var sut = new Parser(config => { config.AutoVersion = true; config.HelpWriter = output; }); + + sut.ParseArguments(new string[] { }); + + var helpText = output.ToString(); + Assert.Contains("version", helpText, StringComparison.InvariantCulture); + Assert.Contains("Display version information.", helpText, StringComparison.InvariantCulture); + } + + [Fact] + // Tests a fix for issue #414 + public void Help_screen_shows_version_option_if_AutoVersion_is_ensabled() + { + var output = new StringWriter(); + var sut = new Parser(config => { config.AutoVersion = true; config.HelpWriter = output; }); + + sut.ParseArguments(new string[] { }); + + var helpText = output.ToString(); + Assert.Contains("--version", helpText, StringComparison.InvariantCulture); + Assert.Contains("Display version information.", helpText, StringComparison.InvariantCulture); + } } } diff --git a/tests/CommandLine.Tests/Unit/Text/HelpTextTests.cs b/tests/CommandLine.Tests/Unit/Text/HelpTextTests.cs index 7c4d7590..d83ebcc6 100644 --- a/tests/CommandLine.Tests/Unit/Text/HelpTextTests.cs +++ b/tests/CommandLine.Tests/Unit/Text/HelpTextTests.cs @@ -318,9 +318,10 @@ public void Invoke_AutoBuild_for_Options_returns_appropriate_formatted_text() new BadFormatTokenError("badtoken"), new SequenceOutOfRangeError(new NameInfo("i", "")) }); + var settings = new ParserSettings(); // Exercize system - var helpText = HelpText.AutoBuild(fakeResult); + var helpText = HelpText.AutoBuild(fakeResult, settings); // Verify outcome var lines = helpText.ToString().ToNotEmptyLines().TrimStringArray(); @@ -353,9 +354,10 @@ public void Invoke_AutoBuild_for_Verbs_with_specific_verb_returns_appropriate_fo { new HelpVerbRequestedError("commit", typeof(Commit_Verb), true) }); + var settings = new ParserSettings(); // Exercize system - var helpText = HelpText.AutoBuild(fakeResult); + var helpText = HelpText.AutoBuild(fakeResult, settings); // Verify outcome var lines = helpText.ToString().ToNotEmptyLines().TrimStringArray(); @@ -386,9 +388,10 @@ public void Invoke_AutoBuild_for_Verbs_with_specific_verb_returns_appropriate_fo { new HelpVerbRequestedError("commit", typeof(Commit_Verb), true) }); + var settings = new ParserSettings() { MaximumDisplayWidth = 100 }; // Exercize system - var helpText = HelpText.AutoBuild(fakeResult, maxDisplayWidth: 100); + var helpText = HelpText.AutoBuild(fakeResult, settings); // Verify outcome var lines = helpText.ToString().ToNotEmptyLines().TrimStringArray(); @@ -418,9 +421,10 @@ public void Invoke_AutoBuild_for_Verbs_with_unknown_verb_returns_appropriate_for TypeInfo.Create(typeof(NullInstance), verbTypes), new Error[] { new HelpVerbRequestedError(null, null, false) }); + var settings = new ParserSettings(); // Exercize system - var helpText = HelpText.AutoBuild(fakeResult); + var helpText = HelpText.AutoBuild(fakeResult, settings); // Verify outcome var lines = helpText.ToString().ToNotEmptyLines().TrimStringArray(); @@ -504,9 +508,10 @@ public void Invoke_AutoBuild_for_Options_with_Usage_returns_appropriate_formatte { new BadFormatTokenError("badtoken") }); + var settings = new ParserSettings(); // Exercize system - var helpText = HelpText.AutoBuild(fakeResult); + var helpText = HelpText.AutoBuild(fakeResult, settings); // Verify outcome var text = helpText.ToString(); @@ -556,10 +561,11 @@ public void Default_set_to_sequence_should_be_properly_printed() new NotParsed( typeof(Options_With_Default_Set_To_Sequence).ToTypeInfo(), new Error[] { new BadFormatTokenError("badtoken") }); + var settings = new ParserSettings(); // Exercize system handlers.ChangeCulture(); - var helpText = HelpText.AutoBuild(fakeResult); + var helpText = HelpText.AutoBuild(fakeResult, settings); handlers.ResetCulture(); // Verify outcome @@ -577,6 +583,7 @@ public void Default_set_to_sequence_should_be_properly_printed() [Fact] public void AutoBuild_when_no_assembly_attributes() { + var settings = new ParserSettings(); string expectedCopyright = "Copyright (C) 1 author"; ReflectionHelper.SetAttributeOverride(new Attribute[0]); @@ -588,7 +595,7 @@ public void AutoBuild_when_no_assembly_attributes() { onErrorCalled = true; return ht; - }, ex => ex); + }, ex => ex, settings); onErrorCalled.Should().BeTrue(); actualResult.Copyright.Should().Be(expectedCopyright); @@ -597,6 +604,7 @@ public void AutoBuild_when_no_assembly_attributes() [Fact] public void AutoBuild_with_assembly_title_and_version_attributes_only() { + var settings = new ParserSettings(); string expectedTitle = "Title"; string expectedVersion = "1.2.3.4"; @@ -613,7 +621,7 @@ public void AutoBuild_with_assembly_title_and_version_attributes_only() { onErrorCalled = true; return ht; - }, ex => ex); + }, ex => ex, settings); onErrorCalled.Should().BeTrue(); actualResult.Heading.Should().Be(string.Format("{0} {1}", expectedTitle, expectedVersion)); @@ -623,6 +631,7 @@ public void AutoBuild_with_assembly_title_and_version_attributes_only() [Fact] public void AutoBuild_with_assembly_company_attribute_only() { + var settings = new ParserSettings(); string expectedCompany = "Company"; ReflectionHelper.SetAttributeOverride(new Attribute[] @@ -637,7 +646,7 @@ public void AutoBuild_with_assembly_company_attribute_only() { onErrorCalled = true; return ht; - }, ex => ex); + }, ex => ex, settings); onErrorCalled.Should().BeFalse(); // Other attributes have fallback logic actualResult.Copyright.Should().Be(string.Format("Copyright (C) {0} {1}", DateTime.Now.Year, expectedCompany)); @@ -653,5 +662,33 @@ public void Add_line_with_two_empty_spaces_at_the_end() Assert.Equal("T" + Environment.NewLine + "e" + Environment.NewLine + "s" + Environment.NewLine + "t", b.ToString()); } + + [Fact] + public void AutoBuild_without_settings_contains_help_and_version() + { + var parserResult = new NotParsed(TypeInfo.Create(typeof(NullInstance)), new[] { new BadFormatConversionError(new NameInfo("f", "foo")) }); + + var helpText = HelpText.AutoBuild(parserResult); + + var text = helpText.ToString(); + Assert.Contains("--help", helpText, StringComparison.InvariantCulture); + Assert.Contains("Display version information.", helpText, StringComparison.InvariantCulture); + Assert.Contains("--version", helpText, StringComparison.InvariantCulture); + Assert.Contains("Display this help screen.", helpText, StringComparison.InvariantCulture); + } + + [Fact] + public void AutoBuild_with_settings_does_not_contain_help_and_version() + { + var parserResult = new NotParsed(TypeInfo.Create(typeof(NullInstance)), new[] { new BadFormatConversionError(new NameInfo("f", "foo")) }); + var settings = new ParserSettings() { AutoHelp = false, AutoVersion = false }; + var helpText = HelpText.AutoBuild(parserResult, settings); + + var text = helpText.ToString(); + Assert.DoesNotContain("--help", helpText, StringComparison.InvariantCulture); + Assert.DoesNotContain("Display version information.", helpText, StringComparison.InvariantCulture); + Assert.DoesNotContain("--version", helpText, StringComparison.InvariantCulture); + Assert.DoesNotContain("Display this help screen.", helpText, StringComparison.InvariantCulture); + } } }