From 39cd77b8e9d88040cab7a3551ba74dd747f393f7 Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Sat, 27 Dec 2025 10:53:10 -0800 Subject: [PATCH 1/3] fix: Correct bugs in multiple value enum option help text (#553) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes several issues introduced in f1a8455: 1. ReflectionHelper.IsEnumerableType - The implementation had bugs: - type.IsAssignableTo(typeof(IEnumerable<>)) doesn't work for open generics - type.GenericTypeArguments[1] was wrong (arrays have element at index 0) Rewrote to properly handle arrays and generic types. 2. DefaultHelpTextGenerator.ExtractNamesFromEnum - Used wrong variable name (wrappedType2 instead of wrappedEnumerableType). 3. ValueParserProvider.GetParserImpl - Added array type support so app.Option() works with MultipleValue options. 4. Test expectation - Fixed expected help text format for MultipleValue options (--enumOpt5 not --enumOpt5[:]). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .../Abstractions/ValueParserProvider.cs | 10 ++++++++++ .../HelpText/DefaultHelpTextGenerator.cs | 2 +- .../Internal/ReflectionHelper.cs | 17 +++++++++++++---- .../DefaultHelpTextGeneratorTests.cs | 2 +- 4 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/CommandLineUtils/Abstractions/ValueParserProvider.cs b/src/CommandLineUtils/Abstractions/ValueParserProvider.cs index d7b694df..89d730a7 100644 --- a/src/CommandLineUtils/Abstractions/ValueParserProvider.cs +++ b/src/CommandLineUtils/Abstractions/ValueParserProvider.cs @@ -133,6 +133,16 @@ public IValueParser GetParser(Type type) #pragma warning restore CS8600 // Converting null literal or possible null value to non-nullable type. } + // For array and collection types, return a parser for the element type + if (type.IsArray) + { + var elementType = type.GetElementType(); + if (elementType != null) + { + return GetParser(elementType); + } + } + return null; } diff --git a/src/CommandLineUtils/HelpText/DefaultHelpTextGenerator.cs b/src/CommandLineUtils/HelpText/DefaultHelpTextGenerator.cs index c64381b3..75aa0088 100644 --- a/src/CommandLineUtils/HelpText/DefaultHelpTextGenerator.cs +++ b/src/CommandLineUtils/HelpText/DefaultHelpTextGenerator.cs @@ -428,7 +428,7 @@ private string[] ExtractNamesFromEnum(Type? type) if (ReflectionHelper.IsEnumerableType(type, out var wrappedEnumerableType)) { - return ExtractNamesFromEnum(wrappedType2); + return ExtractNamesFromEnum(wrappedEnumerableType); } if (type.IsEnum) diff --git a/src/CommandLineUtils/Internal/ReflectionHelper.cs b/src/CommandLineUtils/Internal/ReflectionHelper.cs index e022390a..4d7e1c65 100644 --- a/src/CommandLineUtils/Internal/ReflectionHelper.cs +++ b/src/CommandLineUtils/Internal/ReflectionHelper.cs @@ -160,11 +160,20 @@ public static bool IsSpecialTupleType(Type type, [NotNullWhen(true)] out Type? w public static bool IsEnumerableType(Type type, [NotNullWhen(true)] out Type? wrappedType) { - var result = type.IsGenericType && - type.IsAssignableTo(typeof(IEnumerable<>)); - wrappedType = result ? type.GenericTypeArguments[1] : null; + if (type.IsArray) + { + wrappedType = type.GetElementType()!; + return true; + } - return result; + if (type.IsGenericType) + { + wrappedType = type.GenericTypeArguments[0]; + return true; + } + + wrappedType = null; + return false; } private static IEnumerable GetAllMembers(Type type) diff --git a/test/CommandLineUtils.Tests/DefaultHelpTextGeneratorTests.cs b/test/CommandLineUtils.Tests/DefaultHelpTextGeneratorTests.cs index 2f49639b..7f46adf4 100644 --- a/test/CommandLineUtils.Tests/DefaultHelpTextGeneratorTests.cs +++ b/test/CommandLineUtils.Tests/DefaultHelpTextGeneratorTests.cs @@ -165,7 +165,7 @@ SomeNullableEnumArgument nullable enum arg desc. Allowed values are: None, Normal, Extreme. --enumOpt4[:] nullable enum option desc. Allowed values are: None, Normal, Extreme. - --enumOpt5[:] multiple enum option desc. + --enumOpt5 multiple enum option desc. Allowed values are: None, Normal, Extreme. ", From 36234d73d232b3e40f3656942c3b981d2f5c2f26 Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Sat, 27 Dec 2025 10:58:19 -0800 Subject: [PATCH 2/3] fix: update .NET settings in CI builds --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 68bb5704..5274e7a8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -38,8 +38,8 @@ jobs: uses: actions/setup-dotnet@v4 with: dotnet-version: | - 6.0.x 8.0.x + 9.0.x - name: Run build script id: build_script run: ./build.ps1 -ci From e04f253fc538b436bd383bcc496a5785090f11fd Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Sat, 27 Dec 2025 11:09:21 -0800 Subject: [PATCH 3/3] fix: add missing test SDK package and update analyzer references MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Hosting.CommandLine.Tests project was missing the Microsoft.NET.Test.Sdk package, causing test host failures with Castle.Core dependency resolution errors. Also moved package references from Directory.Build.targets into individual project files and updated analyzer versions. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .../McMaster.Extensions.CommandLineUtils.csproj | 8 +++++++- src/Directory.Build.targets | 12 ------------ .../McMaster.Extensions.Hosting.CommandLine.csproj | 8 +++++--- ...aster.Extensions.Hosting.CommandLine.Tests.csproj | 1 + 4 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/CommandLineUtils/McMaster.Extensions.CommandLineUtils.csproj b/src/CommandLineUtils/McMaster.Extensions.CommandLineUtils.csproj index bc7c3eea..adce0298 100644 --- a/src/CommandLineUtils/McMaster.Extensions.CommandLineUtils.csproj +++ b/src/CommandLineUtils/McMaster.Extensions.CommandLineUtils.csproj @@ -26,7 +26,13 @@ McMaster.Extensions.CommandLineUtils.ArgumentEscaper - + + + + + + + diff --git a/src/Directory.Build.targets b/src/Directory.Build.targets index ea33f241..2c27293d 100644 --- a/src/Directory.Build.targets +++ b/src/Directory.Build.targets @@ -1,17 +1,5 @@ - - - - - - - - - - - - diff --git a/src/Hosting.CommandLine/McMaster.Extensions.Hosting.CommandLine.csproj b/src/Hosting.CommandLine/McMaster.Extensions.Hosting.CommandLine.csproj index 08a5b766..5887084a 100644 --- a/src/Hosting.CommandLine/McMaster.Extensions.Hosting.CommandLine.csproj +++ b/src/Hosting.CommandLine/McMaster.Extensions.Hosting.CommandLine.csproj @@ -11,14 +11,16 @@ + + - + + - + - diff --git a/test/Hosting.CommandLine.Tests/McMaster.Extensions.Hosting.CommandLine.Tests.csproj b/test/Hosting.CommandLine.Tests/McMaster.Extensions.Hosting.CommandLine.Tests.csproj index ed83c547..6756990b 100644 --- a/test/Hosting.CommandLine.Tests/McMaster.Extensions.Hosting.CommandLine.Tests.csproj +++ b/test/Hosting.CommandLine.Tests/McMaster.Extensions.Hosting.CommandLine.Tests.csproj @@ -15,6 +15,7 @@ +