diff --git a/src/CommandLine/Infrastructure/ReflectionHelper.cs b/src/CommandLine/Infrastructure/ReflectionHelper.cs index 47fe70ea..11089d26 100644 --- a/src/CommandLine/Infrastructure/ReflectionHelper.cs +++ b/src/CommandLine/Infrastructure/ReflectionHelper.cs @@ -16,6 +16,14 @@ static class ReflectionHelper /// [ThreadStatic] private static IDictionary _overrides; + private static Assembly _programAssembly; + + public static Assembly ProgramAssembly + { + get => _programAssembly ?? GetExecutingOrEntryAssembly(); + set => _programAssembly = value; + } + /// /// Assembly attribute overrides for testing. /// @@ -51,12 +59,10 @@ public static Maybe GetAttribute() Maybe.Nothing(); } - var assembly = GetExecutingOrEntryAssembly(); - #if NET40 - var attributes = assembly.GetCustomAttributes(typeof(TAttribute), false); + var attributes = ProgramAssembly.GetCustomAttributes(typeof(TAttribute), false); #else - var attributes = assembly.GetCustomAttributes().ToArray(); + var attributes = ProgramAssembly.GetCustomAttributes().ToArray(); #endif return attributes.Length > 0 @@ -66,14 +72,12 @@ public static Maybe GetAttribute() public static string GetAssemblyName() { - var assembly = GetExecutingOrEntryAssembly(); - return assembly.GetName().Name; + return ProgramAssembly.GetName().Name; } public static string GetAssemblyVersion() { - var assembly = GetExecutingOrEntryAssembly(); - return assembly.GetName().Version.ToStringInvariant(); + return ProgramAssembly.GetName().Version.ToStringInvariant(); } public static bool IsFSharpOptionType(Type type) diff --git a/src/CommandLine/Text/HelpText.cs b/src/CommandLine/Text/HelpText.cs index e9ce218d..a6a93690 100644 --- a/src/CommandLine/Text/HelpText.cs +++ b/src/CommandLine/Text/HelpText.cs @@ -305,6 +305,17 @@ public SentenceBuilder SentenceBuilder get { return sentenceBuilder; } } + /// + /// Gets or sets the that will be used to look for meta data (assembly attributes) to auto build the help. + /// By default the entry assembly is automatically selected, but this may not match what is really expected, in particular when + /// running unit tests. + /// + public static Assembly AutoBuildMetadataAssembly + { + get => ReflectionHelper.ProgramAssembly; + set => ReflectionHelper.ProgramAssembly = value; + } + /// /// Creates a new instance of the class using common defaults. /// diff --git a/tests/CommandLine.Tests/Unit/Text/HelpTextTests.cs b/tests/CommandLine.Tests/Unit/Text/HelpTextTests.cs index 9811f7be..948e5546 100644 --- a/tests/CommandLine.Tests/Unit/Text/HelpTextTests.cs +++ b/tests/CommandLine.Tests/Unit/Text/HelpTextTests.cs @@ -22,6 +22,7 @@ public class HelpTextTests : IDisposable public void Dispose() { ReflectionHelper.SetAttributeOverride(null); + HelpText.AutoBuildMetadataAssembly = null; } [Fact] @@ -716,6 +717,21 @@ public void AutoBuild_with_assembly_company_attribute_only() actualResult.Copyright.Should().Be(string.Format("Copyright (C) {0} {1}", DateTime.Now.Year, expectedCompany)); } + [Fact] + public void AutoBuild_with_AutoBuildMetadataAssembly_defined() + { + HelpText.AutoBuildMetadataAssembly = typeof(HelpText).Assembly; + string expectedHeading = "CommandLine 0.0.0"; + string expectedCopyright = "Copyright (c) 2005 - 2020 Giacomo Stelluti Scala & Contributors"; + + ParserResult fakeResult = new NotParsed( + TypeInfo.Create(typeof(Simple_Options)), new Error[0]); + HelpText actualResult = HelpText.AutoBuild(fakeResult, ht => ht, ex => ex); + + actualResult.Heading.Should().Be(expectedHeading); + actualResult.Copyright.Should().Be(expectedCopyright); + } + [Fact] public void Add_line_with_two_empty_spaces_at_the_end() {