From bb38fa965b7916e21784c3a78c6cc33da3dc5267 Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Sat, 4 Apr 2026 20:17:05 -0700 Subject: [PATCH 1/5] feat: prepare v5.1.0 release with keyed DI support Add release notes, changelog entry, version bump, and a sample project demonstrating keyed dependency injection via [FromKeyedServices]. Co-Authored-By: Claude Opus 4.6 (1M context) --- CHANGELOG.md | 7 +++ Directory.Build.props | 2 +- docs/samples/Directory.Build.targets | 2 +- .../keyed/KeyedServices.csproj | 13 ++++ .../dependency-injection/keyed/Program.cs | 59 +++++++++++++++++++ docs/samples/samples.sln | 15 +++++ src/CommandLineUtils/releasenotes.props | 6 ++ 7 files changed, 102 insertions(+), 2 deletions(-) create mode 100644 docs/samples/dependency-injection/keyed/KeyedServices.csproj create mode 100644 docs/samples/dependency-injection/keyed/Program.cs diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c428df7..9f5c6319 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [Unreleased changes](https://github.com/natemcmaster/CommandLineUtils/compare/v5.0.1...main) + +### Features +* [@Chris-Wolfgang]: Add support for keyed dependency injection via `[FromKeyedServices]` attribute ([#560]) + +[#560]: https://github.com/natemcmaster/CommandLineUtils/pull/560 + ## [v5.0.1](https://github.com/natemcmaster/CommandLineUtils/compare/v5.0.0...v5.0.1) ### Features diff --git a/Directory.Build.props b/Directory.Build.props index aa9c9601..a6482787 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -43,7 +43,7 @@ - 5.0.1 + 5.1.0 beta true $(GITHUB_RUN_NUMBER) diff --git a/docs/samples/Directory.Build.targets b/docs/samples/Directory.Build.targets index 70c60c59..5650d4c0 100644 --- a/docs/samples/Directory.Build.targets +++ b/docs/samples/Directory.Build.targets @@ -2,7 +2,7 @@ - + diff --git a/docs/samples/dependency-injection/keyed/KeyedServices.csproj b/docs/samples/dependency-injection/keyed/KeyedServices.csproj new file mode 100644 index 00000000..35e1ef97 --- /dev/null +++ b/docs/samples/dependency-injection/keyed/KeyedServices.csproj @@ -0,0 +1,13 @@ + + + + Exe + net8.0 + + + + + + + + diff --git a/docs/samples/dependency-injection/keyed/Program.cs b/docs/samples/dependency-injection/keyed/Program.cs new file mode 100644 index 00000000..6f2fc96e --- /dev/null +++ b/docs/samples/dependency-injection/keyed/Program.cs @@ -0,0 +1,59 @@ +// Copyright (c) Nate McMaster. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using McMaster.Extensions.CommandLineUtils; +using Microsoft.Extensions.DependencyInjection; + +namespace KeyedServices +{ + [Command(Name = "keyed-di", Description = "Keyed Dependency Injection sample project")] + [HelpOption] + class Program + { + public static int Main(string[] args) + { + var services = new ServiceCollection() + .AddKeyedSingleton("formal") + .AddKeyedSingleton("casual") + .AddSingleton(PhysicalConsole.Singleton) + .BuildServiceProvider(); + + var app = new CommandLineApplication(); + app.Conventions.UseDefaultConventions() + .UseConstructorInjection(services); + return app.Execute(args); + } + + [Option(Description = "The subject to greet")] + public string Subject { get; set; } = "world"; + + [Option(Description = "Use casual greeting")] + public bool Casual { get; set; } + + private int OnExecute( + [FromKeyedServices("formal")] IGreeter formalGreeter, + [FromKeyedServices("casual")] IGreeter casualGreeter, + IConsole console) + { + var greeter = Casual ? casualGreeter : formalGreeter; + console.WriteLine(greeter.Greet(Subject)); + return 0; + } + } + + interface IGreeter + { + string Greet(string subject); + } + + class FormalGreeter : IGreeter + { + public string Greet(string subject) => $"Good day, {subject}. How do you do?"; + } + + class CasualGreeter : IGreeter + { + public string Greet(string subject) => $"Hey {subject}!"; + } +} diff --git a/docs/samples/samples.sln b/docs/samples/samples.sln index a8438486..60aedb76 100644 --- a/docs/samples/samples.sln +++ b/docs/samples/samples.sln @@ -65,6 +65,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HelloWorld", "helloworld\He EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HelloWorldAttributes", "helloworld-attributes\HelloWorldAttributes.csproj", "{81F83C18-B60C-4A3F-8896-4B280A8F06D6}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KeyedServices", "dependency-injection\keyed\KeyedServices.csproj", "{30674755-09B2-41DC-8AAD-31AC4541E562}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -375,6 +377,18 @@ Global {81F83C18-B60C-4A3F-8896-4B280A8F06D6}.Release|x64.Build.0 = Release|Any CPU {81F83C18-B60C-4A3F-8896-4B280A8F06D6}.Release|x86.ActiveCfg = Release|Any CPU {81F83C18-B60C-4A3F-8896-4B280A8F06D6}.Release|x86.Build.0 = Release|Any CPU + {30674755-09B2-41DC-8AAD-31AC4541E562}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {30674755-09B2-41DC-8AAD-31AC4541E562}.Debug|Any CPU.Build.0 = Debug|Any CPU + {30674755-09B2-41DC-8AAD-31AC4541E562}.Debug|x64.ActiveCfg = Debug|Any CPU + {30674755-09B2-41DC-8AAD-31AC4541E562}.Debug|x64.Build.0 = Debug|Any CPU + {30674755-09B2-41DC-8AAD-31AC4541E562}.Debug|x86.ActiveCfg = Debug|Any CPU + {30674755-09B2-41DC-8AAD-31AC4541E562}.Debug|x86.Build.0 = Debug|Any CPU + {30674755-09B2-41DC-8AAD-31AC4541E562}.Release|Any CPU.ActiveCfg = Release|Any CPU + {30674755-09B2-41DC-8AAD-31AC4541E562}.Release|Any CPU.Build.0 = Release|Any CPU + {30674755-09B2-41DC-8AAD-31AC4541E562}.Release|x64.ActiveCfg = Release|Any CPU + {30674755-09B2-41DC-8AAD-31AC4541E562}.Release|x64.Build.0 = Release|Any CPU + {30674755-09B2-41DC-8AAD-31AC4541E562}.Release|x86.ActiveCfg = Release|Any CPU + {30674755-09B2-41DC-8AAD-31AC4541E562}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -394,6 +408,7 @@ Global {1EE15348-5FF4-4988-AEA4-3E267ED4C288} = {75E74B42-039E-4661-B39C-160363B6884A} {A4F3D30A-4124-49B0-A888-F81CE682F491} = {13EC390A-3D6F-4A7E-A02C-D3CBA197FA40} {B38FF032-9AFB-481F-A432-DFA7A5100C3A} = {13EC390A-3D6F-4A7E-A02C-D3CBA197FA40} + {30674755-09B2-41DC-8AAD-31AC4541E562} = {E03982B3-80F2-4D55-9501-378EACE93E5B} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {43B81702-C1EF-43B6-B57D-C630AD1F555D} diff --git a/src/CommandLineUtils/releasenotes.props b/src/CommandLineUtils/releasenotes.props index b857d9fc..ae607adb 100644 --- a/src/CommandLineUtils/releasenotes.props +++ b/src/CommandLineUtils/releasenotes.props @@ -1,5 +1,11 @@ + +Changes since 5.0: + +Features: +* @Chris-Wolfgang: Add support for keyed dependency injection via [FromKeyedServices] attribute (#560) + Changes since 4.1: From dd9bd8caef7c01f73a1f6d45b44236e262f4036f Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Sat, 4 Apr 2026 20:25:20 -0700 Subject: [PATCH 2/5] chore: use SDK built-in format, not global-tool for formatting --- .config/dotnet-tools.json | 8 +------- build.ps1 | 6 +++--- docs/samples/dependency-injection/custom/Program.cs | 5 ++++- docs/samples/dependency-injection/generic-host/Program.cs | 5 ++++- docs/samples/dependency-injection/standard/Program.cs | 5 ++++- docs/samples/generic-host/AttributeApi/Program.cs | 5 ++++- docs/samples/generic-host/BuilderApi/Program.cs | 5 ++++- docs/samples/helloworld-async/Program.cs | 5 ++++- docs/samples/helloworld-attributes/Program.cs | 5 ++++- docs/samples/helloworld/Program.cs | 3 +++ docs/samples/interactive-prompts/Program.cs | 8 ++++---- docs/samples/pager/Program.cs | 5 ++++- docs/samples/passthru-args/attributes/Program.cs | 3 +++ docs/samples/passthru-args/builder-api/Program.cs | 3 +++ docs/samples/response-file-parsing/attributes/Program.cs | 5 ++++- docs/samples/response-file-parsing/builder-api/Program.cs | 5 ++++- src/CommandLineUtils/CommandLineApplication.cs | 1 - .../Conventions/ExecuteMethodConvention.cs | 2 -- .../Conventions/ParentPropertyConvention.cs | 1 - .../Conventions/SubcommandPropertyConvention.cs | 1 - .../SourceGeneration/Handlers/IModelFactory.cs | 2 -- .../SourceGeneration/ArgumentMetadataTests.cs | 1 - .../CommandLineApplicationWithModelTests.cs | 1 - .../SourceGeneration/MetadataProviderTests.cs | 1 - .../SourceGeneration/OptionMetadataTests.cs | 1 - .../SourceGeneration/ReflectionExecuteHandlerTests.cs | 1 - .../SourceGeneration/ReflectionValidateHandlerTests.cs | 1 - .../SourceGeneration/SpecialPropertiesMetadataTests.cs | 1 - .../SourceGeneration/SubcommandMetadataTests.cs | 1 - .../SourceGeneration/TypedWrapperTests.cs | 2 -- 30 files changed, 57 insertions(+), 41 deletions(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index d503d041..72bd4edd 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -2,12 +2,6 @@ "version": 1, "isRoot": true, "tools": { - "dotnet-format": { - "version": "5.1.250801", - "commands": [ - "dotnet-format" - ] - }, "docfx": { "version": "2.78.5", "commands": [ @@ -15,4 +9,4 @@ ] } } -} \ No newline at end of file +} diff --git a/build.ps1 b/build.ps1 index a0b26fc9..0f37d9df 100755 --- a/build.ps1 +++ b/build.ps1 @@ -24,11 +24,11 @@ exec dotnet tool restore [string[]] $formatArgs=@() if ($ci) { - $formatArgs += '--check' + $formatArgs += '--verify-no-changes' } -exec dotnet tool run dotnet-format -- -v detailed @formatArgs "$PSScriptRoot/CommandLineUtils.sln" -exec dotnet tool run dotnet-format -- -v detailed @formatArgs "$PSScriptRoot/docs/samples/samples.sln" +exec dotnet format -- @formatArgs "$PSScriptRoot/CommandLineUtils.sln" +exec dotnet format -- @formatArgs "$PSScriptRoot/docs/samples/samples.sln" exec dotnet build --configuration $Configuration '-warnaserror:CS1591' exec dotnet pack --no-build --configuration $Configuration -o $artifacts exec dotnet build --configuration $Configuration "$PSScriptRoot/docs/samples/samples.sln" diff --git a/docs/samples/dependency-injection/custom/Program.cs b/docs/samples/dependency-injection/custom/Program.cs index 5b2abde7..12025279 100644 --- a/docs/samples/dependency-injection/custom/Program.cs +++ b/docs/samples/dependency-injection/custom/Program.cs @@ -1,4 +1,7 @@ -using System; +// Copyright (c) Nate McMaster. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; using McMaster.Extensions.CommandLineUtils; using Microsoft.Extensions.DependencyInjection; diff --git a/docs/samples/dependency-injection/generic-host/Program.cs b/docs/samples/dependency-injection/generic-host/Program.cs index ba194167..d744d773 100644 --- a/docs/samples/dependency-injection/generic-host/Program.cs +++ b/docs/samples/dependency-injection/generic-host/Program.cs @@ -1,4 +1,7 @@ -using System; +// Copyright (c) Nate McMaster. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; using System.Threading; using System.Threading.Tasks; using McMaster.Extensions.CommandLineUtils; diff --git a/docs/samples/dependency-injection/standard/Program.cs b/docs/samples/dependency-injection/standard/Program.cs index c90a8d1e..725d4074 100644 --- a/docs/samples/dependency-injection/standard/Program.cs +++ b/docs/samples/dependency-injection/standard/Program.cs @@ -1,4 +1,7 @@ -using System; +// Copyright (c) Nate McMaster. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; using System.Threading.Tasks; using McMaster.Extensions.CommandLineUtils; diff --git a/docs/samples/generic-host/AttributeApi/Program.cs b/docs/samples/generic-host/AttributeApi/Program.cs index fee1def9..84baff6b 100644 --- a/docs/samples/generic-host/AttributeApi/Program.cs +++ b/docs/samples/generic-host/AttributeApi/Program.cs @@ -1,4 +1,7 @@ -using System; +// Copyright (c) Nate McMaster. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; using System.Threading.Tasks; using McMaster.Extensions.CommandLineUtils; using Microsoft.Extensions.Hosting; diff --git a/docs/samples/generic-host/BuilderApi/Program.cs b/docs/samples/generic-host/BuilderApi/Program.cs index 3efd199f..788eff56 100644 --- a/docs/samples/generic-host/BuilderApi/Program.cs +++ b/docs/samples/generic-host/BuilderApi/Program.cs @@ -1,4 +1,7 @@ -using System; +// Copyright (c) Nate McMaster. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; using System.Threading.Tasks; using McMaster.Extensions.CommandLineUtils; using Microsoft.Extensions.DependencyInjection; diff --git a/docs/samples/helloworld-async/Program.cs b/docs/samples/helloworld-async/Program.cs index 099cbd37..f6cd09a5 100644 --- a/docs/samples/helloworld-async/Program.cs +++ b/docs/samples/helloworld-async/Program.cs @@ -1,4 +1,7 @@ -using System; +// Copyright (c) Nate McMaster. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; using System.Threading.Tasks; using McMaster.Extensions.CommandLineUtils; diff --git a/docs/samples/helloworld-attributes/Program.cs b/docs/samples/helloworld-attributes/Program.cs index ddafdb34..baa222f7 100644 --- a/docs/samples/helloworld-attributes/Program.cs +++ b/docs/samples/helloworld-attributes/Program.cs @@ -1,4 +1,7 @@ -using System; +// Copyright (c) Nate McMaster. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; using McMaster.Extensions.CommandLineUtils; public class Program diff --git a/docs/samples/helloworld/Program.cs b/docs/samples/helloworld/Program.cs index 6a0e80d9..0504a022 100644 --- a/docs/samples/helloworld/Program.cs +++ b/docs/samples/helloworld/Program.cs @@ -1,3 +1,6 @@ +// Copyright (c) Nate McMaster. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + using System; using McMaster.Extensions.CommandLineUtils; diff --git a/docs/samples/interactive-prompts/Program.cs b/docs/samples/interactive-prompts/Program.cs index 39424313..e9ab35bf 100644 --- a/docs/samples/interactive-prompts/Program.cs +++ b/docs/samples/interactive-prompts/Program.cs @@ -19,7 +19,7 @@ static void Main(string[] args) promptColor: ConsoleColor.White, promptBgColor: ConsoleColor.DarkGreen); - Console.WriteLine($"Hello, there { name ?? "anonymous console user"}."); + Console.WriteLine($"Hello, there {name ?? "anonymous console user"}."); var age = Prompt.GetInt("How old are you?", promptColor: ConsoleColor.White, @@ -32,13 +32,13 @@ static void Main(string[] args) Console.Write($"Your password contains {password.Length} characters. "); switch (password.Length) { - case int _ when (password.Length < 2): + case int _ when password.Length < 2: Console.WriteLine("Your password is so short you might as well not have one."); break; - case int _ when (password.Length < 4): + case int _ when password.Length < 4: Console.WriteLine("Your password is too short. You should pick a better one"); break; - case int _ when (password.Length < 10): + case int _ when password.Length < 10: Console.WriteLine("Your password is too okay, I guess."); break; default: diff --git a/docs/samples/pager/Program.cs b/docs/samples/pager/Program.cs index cbcd4e44..8c40dc09 100644 --- a/docs/samples/pager/Program.cs +++ b/docs/samples/pager/Program.cs @@ -1,4 +1,7 @@ -using System; +// Copyright (c) Nate McMaster. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; using McMaster.Extensions.CommandLineUtils; class Program diff --git a/docs/samples/passthru-args/attributes/Program.cs b/docs/samples/passthru-args/attributes/Program.cs index 41726fd4..5433afb8 100644 --- a/docs/samples/passthru-args/attributes/Program.cs +++ b/docs/samples/passthru-args/attributes/Program.cs @@ -1,3 +1,6 @@ +// Copyright (c) Nate McMaster. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + using System; using System.Diagnostics; using System.Linq; diff --git a/docs/samples/passthru-args/builder-api/Program.cs b/docs/samples/passthru-args/builder-api/Program.cs index 9ae023ff..99ec19a3 100644 --- a/docs/samples/passthru-args/builder-api/Program.cs +++ b/docs/samples/passthru-args/builder-api/Program.cs @@ -1,3 +1,6 @@ +// Copyright (c) Nate McMaster. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + using System; using System.Diagnostics; using System.Linq; diff --git a/docs/samples/response-file-parsing/attributes/Program.cs b/docs/samples/response-file-parsing/attributes/Program.cs index d1052503..bb465450 100644 --- a/docs/samples/response-file-parsing/attributes/Program.cs +++ b/docs/samples/response-file-parsing/attributes/Program.cs @@ -1,4 +1,7 @@ -using System; +// Copyright (c) Nate McMaster. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; using McMaster.Extensions.CommandLineUtils; namespace ResponseFileParsing diff --git a/docs/samples/response-file-parsing/builder-api/Program.cs b/docs/samples/response-file-parsing/builder-api/Program.cs index d08855ed..c97b87e8 100644 --- a/docs/samples/response-file-parsing/builder-api/Program.cs +++ b/docs/samples/response-file-parsing/builder-api/Program.cs @@ -1,4 +1,7 @@ -using System; +// Copyright (c) Nate McMaster. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; using McMaster.Extensions.CommandLineUtils; namespace ResponseFileParsing diff --git a/src/CommandLineUtils/CommandLineApplication.cs b/src/CommandLineUtils/CommandLineApplication.cs index 9a9e5bd7..5aa4cea3 100644 --- a/src/CommandLineUtils/CommandLineApplication.cs +++ b/src/CommandLineUtils/CommandLineApplication.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; using System.IO; using System.Linq; using System.Reflection; diff --git a/src/CommandLineUtils/Conventions/ExecuteMethodConvention.cs b/src/CommandLineUtils/Conventions/ExecuteMethodConvention.cs index d3254e14..0be24b54 100644 --- a/src/CommandLineUtils/Conventions/ExecuteMethodConvention.cs +++ b/src/CommandLineUtils/Conventions/ExecuteMethodConvention.cs @@ -2,8 +2,6 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using System.Threading; -using System.Threading.Tasks; namespace McMaster.Extensions.CommandLineUtils.Conventions { diff --git a/src/CommandLineUtils/Conventions/ParentPropertyConvention.cs b/src/CommandLineUtils/Conventions/ParentPropertyConvention.cs index e28f2dd6..9fca9018 100644 --- a/src/CommandLineUtils/Conventions/ParentPropertyConvention.cs +++ b/src/CommandLineUtils/Conventions/ParentPropertyConvention.cs @@ -1,7 +1,6 @@ // Copyright (c) Nate McMaster. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; using System.Reflection; using McMaster.Extensions.CommandLineUtils.Abstractions; diff --git a/src/CommandLineUtils/Conventions/SubcommandPropertyConvention.cs b/src/CommandLineUtils/Conventions/SubcommandPropertyConvention.cs index 5e7c67d0..99c2b430 100644 --- a/src/CommandLineUtils/Conventions/SubcommandPropertyConvention.cs +++ b/src/CommandLineUtils/Conventions/SubcommandPropertyConvention.cs @@ -1,7 +1,6 @@ // Copyright (c) Nate McMaster. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; using System.Reflection; using McMaster.Extensions.CommandLineUtils.Abstractions; diff --git a/src/CommandLineUtils/SourceGeneration/Handlers/IModelFactory.cs b/src/CommandLineUtils/SourceGeneration/Handlers/IModelFactory.cs index 6d312eba..561c72bc 100644 --- a/src/CommandLineUtils/SourceGeneration/Handlers/IModelFactory.cs +++ b/src/CommandLineUtils/SourceGeneration/Handlers/IModelFactory.cs @@ -1,8 +1,6 @@ // Copyright (c) Nate McMaster. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; - namespace McMaster.Extensions.CommandLineUtils.SourceGeneration { /// diff --git a/test/CommandLineUtils.Tests/SourceGeneration/ArgumentMetadataTests.cs b/test/CommandLineUtils.Tests/SourceGeneration/ArgumentMetadataTests.cs index f7d0eecf..0d787c5e 100644 --- a/test/CommandLineUtils.Tests/SourceGeneration/ArgumentMetadataTests.cs +++ b/test/CommandLineUtils.Tests/SourceGeneration/ArgumentMetadataTests.cs @@ -1,7 +1,6 @@ // Copyright (c) Nate McMaster. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using McMaster.Extensions.CommandLineUtils.SourceGeneration; diff --git a/test/CommandLineUtils.Tests/SourceGeneration/CommandLineApplicationWithModelTests.cs b/test/CommandLineUtils.Tests/SourceGeneration/CommandLineApplicationWithModelTests.cs index 9644c44c..d75a6678 100644 --- a/test/CommandLineUtils.Tests/SourceGeneration/CommandLineApplicationWithModelTests.cs +++ b/test/CommandLineUtils.Tests/SourceGeneration/CommandLineApplicationWithModelTests.cs @@ -1,7 +1,6 @@ // Copyright (c) Nate McMaster. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; using McMaster.Extensions.CommandLineUtils.Abstractions; using McMaster.Extensions.CommandLineUtils.SourceGeneration; using Xunit; diff --git a/test/CommandLineUtils.Tests/SourceGeneration/MetadataProviderTests.cs b/test/CommandLineUtils.Tests/SourceGeneration/MetadataProviderTests.cs index fdfcdc46..a8db2a03 100644 --- a/test/CommandLineUtils.Tests/SourceGeneration/MetadataProviderTests.cs +++ b/test/CommandLineUtils.Tests/SourceGeneration/MetadataProviderTests.cs @@ -1,7 +1,6 @@ // Copyright (c) Nate McMaster. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; using System.Linq; using McMaster.Extensions.CommandLineUtils.SourceGeneration; using Xunit; diff --git a/test/CommandLineUtils.Tests/SourceGeneration/OptionMetadataTests.cs b/test/CommandLineUtils.Tests/SourceGeneration/OptionMetadataTests.cs index 63a99b9f..bb91f77d 100644 --- a/test/CommandLineUtils.Tests/SourceGeneration/OptionMetadataTests.cs +++ b/test/CommandLineUtils.Tests/SourceGeneration/OptionMetadataTests.cs @@ -1,7 +1,6 @@ // Copyright (c) Nate McMaster. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using McMaster.Extensions.CommandLineUtils.SourceGeneration; diff --git a/test/CommandLineUtils.Tests/SourceGeneration/ReflectionExecuteHandlerTests.cs b/test/CommandLineUtils.Tests/SourceGeneration/ReflectionExecuteHandlerTests.cs index a08541da..23206163 100644 --- a/test/CommandLineUtils.Tests/SourceGeneration/ReflectionExecuteHandlerTests.cs +++ b/test/CommandLineUtils.Tests/SourceGeneration/ReflectionExecuteHandlerTests.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using System.Reflection; using System.Threading; using System.Threading.Tasks; using McMaster.Extensions.CommandLineUtils.SourceGeneration; diff --git a/test/CommandLineUtils.Tests/SourceGeneration/ReflectionValidateHandlerTests.cs b/test/CommandLineUtils.Tests/SourceGeneration/ReflectionValidateHandlerTests.cs index c60c69f1..fcf9a3a1 100644 --- a/test/CommandLineUtils.Tests/SourceGeneration/ReflectionValidateHandlerTests.cs +++ b/test/CommandLineUtils.Tests/SourceGeneration/ReflectionValidateHandlerTests.cs @@ -4,7 +4,6 @@ using System; using System.ComponentModel.DataAnnotations; using System.IO; -using System.Reflection; using McMaster.Extensions.CommandLineUtils.Abstractions; using McMaster.Extensions.CommandLineUtils.Internal; using McMaster.Extensions.CommandLineUtils.SourceGeneration; diff --git a/test/CommandLineUtils.Tests/SourceGeneration/SpecialPropertiesMetadataTests.cs b/test/CommandLineUtils.Tests/SourceGeneration/SpecialPropertiesMetadataTests.cs index f4b2a071..a3b9eb93 100644 --- a/test/CommandLineUtils.Tests/SourceGeneration/SpecialPropertiesMetadataTests.cs +++ b/test/CommandLineUtils.Tests/SourceGeneration/SpecialPropertiesMetadataTests.cs @@ -1,7 +1,6 @@ // Copyright (c) Nate McMaster. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; using System.Linq; using McMaster.Extensions.CommandLineUtils.SourceGeneration; using Xunit; diff --git a/test/CommandLineUtils.Tests/SourceGeneration/SubcommandMetadataTests.cs b/test/CommandLineUtils.Tests/SourceGeneration/SubcommandMetadataTests.cs index fee39c17..e1ea348f 100644 --- a/test/CommandLineUtils.Tests/SourceGeneration/SubcommandMetadataTests.cs +++ b/test/CommandLineUtils.Tests/SourceGeneration/SubcommandMetadataTests.cs @@ -1,7 +1,6 @@ // Copyright (c) Nate McMaster. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; using McMaster.Extensions.CommandLineUtils.SourceGeneration; using Xunit; diff --git a/test/CommandLineUtils.Tests/SourceGeneration/TypedWrapperTests.cs b/test/CommandLineUtils.Tests/SourceGeneration/TypedWrapperTests.cs index 7dba49a9..2f96704b 100644 --- a/test/CommandLineUtils.Tests/SourceGeneration/TypedWrapperTests.cs +++ b/test/CommandLineUtils.Tests/SourceGeneration/TypedWrapperTests.cs @@ -1,8 +1,6 @@ // Copyright (c) Nate McMaster. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; -using System.Collections.Generic; using McMaster.Extensions.CommandLineUtils.SourceGeneration; using Xunit; From 56e3739e017cf35f3aed1763405a81a3119a7e00 Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Sat, 4 Apr 2026 20:36:55 -0700 Subject: [PATCH 3/5] chore: add linter for removing unnecessary using statements --- .editorconfig | 3 +++ Directory.Build.props | 4 ++++ docs/samples/dependency-injection/custom/Program.cs | 1 - docs/samples/dependency-injection/generic-host/Program.cs | 2 -- docs/samples/dependency-injection/keyed/Program.cs | 1 - docs/samples/dependency-injection/standard/Program.cs | 1 - docs/samples/pager/Program.cs | 1 - docs/samples/response-file-parsing/attributes/Program.cs | 1 - docs/samples/response-file-parsing/builder-api/Program.cs | 1 - docs/samples/validation/attributes/Program.cs | 1 - .../CommandMetadataGenerator.cs | 1 - .../Conventions/SubcommandAttributeConvention.cs | 5 ----- src/CommandLineUtils/Internal/DictionaryExtensions.cs | 8 ++++---- .../SourceGeneration/ActivatorModelFactory.cs | 5 ----- .../SourceGeneration/DefaultMetadataResolver.cs | 5 ----- .../SourceGeneration/ReflectionExecuteHandler.cs | 5 ----- .../SourceGeneration/ReflectionMetadataProvider.cs | 5 ----- .../SourceGeneration/ReflectionValidateHandler.cs | 5 ----- .../SourceGeneration/ReflectionValidationErrorHandler.cs | 5 ----- .../ExecuteMethodConventionTests.cs | 1 - test/Directory.Build.props | 3 +++ 21 files changed, 14 insertions(+), 50 deletions(-) diff --git a/.editorconfig b/.editorconfig index 7160019d..13901627 100644 --- a/.editorconfig +++ b/.editorconfig @@ -48,6 +48,9 @@ csharp_style_expression_bodied_indexers = true csharp_style_expression_bodied_accessors = true csharp_style_throw_expression = true +# Remove unnecessary usings +dotnet_diagnostic.IDE0005.severity = warning + # Default severity for analyzer diagnostics with category 'Style' (escalated to build warnings) # dotnet_analyzer_diagnostic.category-Style.severity = suggestion diff --git a/Directory.Build.props b/Directory.Build.props index a6482787..6f1eca18 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -60,6 +60,10 @@ + + true + + diff --git a/docs/samples/dependency-injection/custom/Program.cs b/docs/samples/dependency-injection/custom/Program.cs index 12025279..4537ebcd 100644 --- a/docs/samples/dependency-injection/custom/Program.cs +++ b/docs/samples/dependency-injection/custom/Program.cs @@ -1,7 +1,6 @@ // Copyright (c) Nate McMaster. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; using McMaster.Extensions.CommandLineUtils; using Microsoft.Extensions.DependencyInjection; diff --git a/docs/samples/dependency-injection/generic-host/Program.cs b/docs/samples/dependency-injection/generic-host/Program.cs index d744d773..fda080be 100644 --- a/docs/samples/dependency-injection/generic-host/Program.cs +++ b/docs/samples/dependency-injection/generic-host/Program.cs @@ -2,10 +2,8 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using System.Threading; using System.Threading.Tasks; using McMaster.Extensions.CommandLineUtils; -using McMaster.Extensions.Hosting.CommandLine; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; diff --git a/docs/samples/dependency-injection/keyed/Program.cs b/docs/samples/dependency-injection/keyed/Program.cs index 6f2fc96e..61e97480 100644 --- a/docs/samples/dependency-injection/keyed/Program.cs +++ b/docs/samples/dependency-injection/keyed/Program.cs @@ -1,7 +1,6 @@ // Copyright (c) Nate McMaster. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; using McMaster.Extensions.CommandLineUtils; using Microsoft.Extensions.DependencyInjection; diff --git a/docs/samples/dependency-injection/standard/Program.cs b/docs/samples/dependency-injection/standard/Program.cs index 725d4074..5ea1ab2b 100644 --- a/docs/samples/dependency-injection/standard/Program.cs +++ b/docs/samples/dependency-injection/standard/Program.cs @@ -1,7 +1,6 @@ // Copyright (c) Nate McMaster. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; using System.Threading.Tasks; using McMaster.Extensions.CommandLineUtils; diff --git a/docs/samples/pager/Program.cs b/docs/samples/pager/Program.cs index 8c40dc09..97a4abdd 100644 --- a/docs/samples/pager/Program.cs +++ b/docs/samples/pager/Program.cs @@ -1,7 +1,6 @@ // Copyright (c) Nate McMaster. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; using McMaster.Extensions.CommandLineUtils; class Program diff --git a/docs/samples/response-file-parsing/attributes/Program.cs b/docs/samples/response-file-parsing/attributes/Program.cs index bb465450..bfef221e 100644 --- a/docs/samples/response-file-parsing/attributes/Program.cs +++ b/docs/samples/response-file-parsing/attributes/Program.cs @@ -1,7 +1,6 @@ // Copyright (c) Nate McMaster. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; using McMaster.Extensions.CommandLineUtils; namespace ResponseFileParsing diff --git a/docs/samples/response-file-parsing/builder-api/Program.cs b/docs/samples/response-file-parsing/builder-api/Program.cs index c97b87e8..2f18b5cb 100644 --- a/docs/samples/response-file-parsing/builder-api/Program.cs +++ b/docs/samples/response-file-parsing/builder-api/Program.cs @@ -1,7 +1,6 @@ // Copyright (c) Nate McMaster. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System; using McMaster.Extensions.CommandLineUtils; namespace ResponseFileParsing diff --git a/docs/samples/validation/attributes/Program.cs b/docs/samples/validation/attributes/Program.cs index a70af9f2..5afab299 100644 --- a/docs/samples/validation/attributes/Program.cs +++ b/docs/samples/validation/attributes/Program.cs @@ -3,7 +3,6 @@ using System; using System.ComponentModel.DataAnnotations; -using System.Linq; using McMaster.Extensions.CommandLineUtils; // This is required since .NET 8 introduced a new type System.ComponentModel.DataAnnotations.AllowedValuesAttribute // which conflicts with the attribute in this library (added long before .NET 8.) diff --git a/src/CommandLineUtils.Generators/CommandMetadataGenerator.cs b/src/CommandLineUtils.Generators/CommandMetadataGenerator.cs index b40f8966..1809b1d4 100644 --- a/src/CommandLineUtils.Generators/CommandMetadataGenerator.cs +++ b/src/CommandLineUtils.Generators/CommandMetadataGenerator.cs @@ -8,7 +8,6 @@ using System.Text; using System.Threading; using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Text; diff --git a/src/CommandLineUtils/Conventions/SubcommandAttributeConvention.cs b/src/CommandLineUtils/Conventions/SubcommandAttributeConvention.cs index 4c2e5839..db527017 100644 --- a/src/CommandLineUtils/Conventions/SubcommandAttributeConvention.cs +++ b/src/CommandLineUtils/Conventions/SubcommandAttributeConvention.cs @@ -58,12 +58,7 @@ private static string GetSubcommandName(Type subcommandType, ICommandMetadataPro private void AddSubcommandFromMetadata( ConventionContext context, -#if NET6_0_OR_GREATER [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] -#elif NET472_OR_GREATER -#else -#error Target framework misconfiguration -#endif Type subcommandType, ICommandMetadataProvider provider, string name) diff --git a/src/CommandLineUtils/Internal/DictionaryExtensions.cs b/src/CommandLineUtils/Internal/DictionaryExtensions.cs index 5918f826..65da25c5 100644 --- a/src/CommandLineUtils/Internal/DictionaryExtensions.cs +++ b/src/CommandLineUtils/Internal/DictionaryExtensions.cs @@ -1,14 +1,14 @@ // Copyright (c) Nate McMaster. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +#if NET6_0_OR_GREATER +#elif NET472_OR_GREATER using System.Collections.Generic; namespace McMaster.Extensions.CommandLineUtils { internal static class DictionaryExtensions { -#if NET6_0_OR_GREATER -#elif NET472_OR_GREATER public static bool TryAdd(this IDictionary dictionary, TKey key, TValue value) { if (dictionary.ContainsKey(key)) @@ -18,8 +18,8 @@ public static bool TryAdd(this IDictionary dictionar dictionary.Add(key, value); return true; } + } +} #else #error Target framework misconfiguration #endif - } -} diff --git a/src/CommandLineUtils/SourceGeneration/ActivatorModelFactory.cs b/src/CommandLineUtils/SourceGeneration/ActivatorModelFactory.cs index b9967031..2ec3c8d9 100644 --- a/src/CommandLineUtils/SourceGeneration/ActivatorModelFactory.cs +++ b/src/CommandLineUtils/SourceGeneration/ActivatorModelFactory.cs @@ -11,12 +11,7 @@ namespace McMaster.Extensions.CommandLineUtils.SourceGeneration /// /// Model factory that uses Activator.CreateInstance or DI with constructor injection. /// -#if NET6_0_OR_GREATER [RequiresUnreferencedCode("Uses Activator.CreateInstance or DI with constructor injection")] -#elif NET472_OR_GREATER -#else -#error Target framework misconfiguration -#endif internal sealed class ActivatorModelFactory : IModelFactory { private readonly Type _modelType; diff --git a/src/CommandLineUtils/SourceGeneration/DefaultMetadataResolver.cs b/src/CommandLineUtils/SourceGeneration/DefaultMetadataResolver.cs index 1e6f95d9..1b1fcedb 100644 --- a/src/CommandLineUtils/SourceGeneration/DefaultMetadataResolver.cs +++ b/src/CommandLineUtils/SourceGeneration/DefaultMetadataResolver.cs @@ -30,12 +30,7 @@ private DefaultMetadataResolver() /// For full AOT compatibility, ensure the CommandLineUtils.Generators package is referenced /// and the source generator runs during compilation. /// -#if NET6_0_OR_GREATER [RequiresUnreferencedCode("Falls back to reflection when no generated metadata is available. Use the source generator for AOT compatibility.")] -#elif NET472_OR_GREATER -#else -#error Target framework misconfiguration -#endif public ICommandMetadataProvider GetProvider(Type modelType) { // Check for generated metadata first (AOT-safe path) diff --git a/src/CommandLineUtils/SourceGeneration/ReflectionExecuteHandler.cs b/src/CommandLineUtils/SourceGeneration/ReflectionExecuteHandler.cs index f3e26c38..7ed1237c 100644 --- a/src/CommandLineUtils/SourceGeneration/ReflectionExecuteHandler.cs +++ b/src/CommandLineUtils/SourceGeneration/ReflectionExecuteHandler.cs @@ -12,12 +12,7 @@ namespace McMaster.Extensions.CommandLineUtils.SourceGeneration /// /// Execute handler that uses reflection to invoke OnExecute/OnExecuteAsync. /// -#if NET6_0_OR_GREATER [RequiresUnreferencedCode("Uses reflection to invoke method")] -#elif NET472_OR_GREATER -#else -#error Target framework misconfiguration -#endif internal sealed class ReflectionExecuteHandler : IExecuteHandler { private readonly MethodInfo _method; diff --git a/src/CommandLineUtils/SourceGeneration/ReflectionMetadataProvider.cs b/src/CommandLineUtils/SourceGeneration/ReflectionMetadataProvider.cs index 3659f241..e5b26f7d 100644 --- a/src/CommandLineUtils/SourceGeneration/ReflectionMetadataProvider.cs +++ b/src/CommandLineUtils/SourceGeneration/ReflectionMetadataProvider.cs @@ -15,12 +15,7 @@ namespace McMaster.Extensions.CommandLineUtils.SourceGeneration /// Provides command metadata by analyzing a type using reflection. /// This is the fallback when generated metadata is not available. /// -#if NET6_0_OR_GREATER [RequiresUnreferencedCode("Uses reflection to analyze the model type")] -#elif NET472_OR_GREATER -#else -#error Target framework misconfiguration -#endif internal sealed class ReflectionMetadataProvider : ICommandMetadataProvider { private const BindingFlags MethodLookup = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public; diff --git a/src/CommandLineUtils/SourceGeneration/ReflectionValidateHandler.cs b/src/CommandLineUtils/SourceGeneration/ReflectionValidateHandler.cs index 3ead1679..bb473e9f 100644 --- a/src/CommandLineUtils/SourceGeneration/ReflectionValidateHandler.cs +++ b/src/CommandLineUtils/SourceGeneration/ReflectionValidateHandler.cs @@ -12,12 +12,7 @@ namespace McMaster.Extensions.CommandLineUtils.SourceGeneration /// /// Validate handler that uses reflection to invoke OnValidate. /// -#if NET6_0_OR_GREATER [RequiresUnreferencedCode("Uses reflection to invoke method")] -#elif NET472_OR_GREATER -#else -#error Target framework misconfiguration -#endif internal sealed class ReflectionValidateHandler : IValidateHandler { private readonly MethodInfo _method; diff --git a/src/CommandLineUtils/SourceGeneration/ReflectionValidationErrorHandler.cs b/src/CommandLineUtils/SourceGeneration/ReflectionValidationErrorHandler.cs index 68dbf57f..0619433f 100644 --- a/src/CommandLineUtils/SourceGeneration/ReflectionValidationErrorHandler.cs +++ b/src/CommandLineUtils/SourceGeneration/ReflectionValidationErrorHandler.cs @@ -11,12 +11,7 @@ namespace McMaster.Extensions.CommandLineUtils.SourceGeneration /// /// Validation error handler that uses reflection to invoke OnValidationError. /// -#if NET6_0_OR_GREATER [RequiresUnreferencedCode("Uses reflection to invoke method")] -#elif NET472_OR_GREATER -#else -#error Target framework misconfiguration -#endif internal sealed class ReflectionValidationErrorHandler : IValidationErrorHandler { private readonly MethodInfo _method; diff --git a/test/CommandLineUtils.Tests/ExecuteMethodConventionTests.cs b/test/CommandLineUtils.Tests/ExecuteMethodConventionTests.cs index 56902c21..40793715 100644 --- a/test/CommandLineUtils.Tests/ExecuteMethodConventionTests.cs +++ b/test/CommandLineUtils.Tests/ExecuteMethodConventionTests.cs @@ -4,7 +4,6 @@ using System; using System.Threading; using System.Threading.Tasks; -using McMaster.Extensions.CommandLineUtils; using Microsoft.Extensions.DependencyInjection; using Moq; using Xunit; diff --git a/test/Directory.Build.props b/test/Directory.Build.props index ab31da95..138a4376 100644 --- a/test/Directory.Build.props +++ b/test/Directory.Build.props @@ -3,5 +3,8 @@ $(DefaultItemExcludes);TestResults\** $(MSBuildThisFileDirectory)\.runsettings + + true + $(NoWarn);CS1591 From ea8c62fe2bec68c17be2f857cd7249fd175924ad Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Sat, 4 Apr 2026 20:42:33 -0700 Subject: [PATCH 4/5] chore: upgrade dependencies --- .../dependency-injection/custom/CustomServices.csproj | 2 +- .../generic-host/GenericHostDI.csproj | 4 ++-- .../dependency-injection/keyed/KeyedServices.csproj | 2 +- .../samples/generic-host/AttributeApi/AttributeApi.csproj | 2 +- docs/samples/generic-host/BuilderApi/BuilderApi.csproj | 2 +- .../McMaster.Extensions.CommandLineUtils.csproj | 2 +- .../McMaster.Extensions.Hosting.CommandLine.csproj | 6 +++--- .../McMaster.Extensions.CommandLineUtils.Tests.csproj | 8 ++++---- .../McMaster.Extensions.Hosting.CommandLine.Tests.csproj | 8 ++++---- 9 files changed, 18 insertions(+), 18 deletions(-) diff --git a/docs/samples/dependency-injection/custom/CustomServices.csproj b/docs/samples/dependency-injection/custom/CustomServices.csproj index 716e65c4..f82de1fd 100644 --- a/docs/samples/dependency-injection/custom/CustomServices.csproj +++ b/docs/samples/dependency-injection/custom/CustomServices.csproj @@ -7,7 +7,7 @@ - + diff --git a/docs/samples/dependency-injection/generic-host/GenericHostDI.csproj b/docs/samples/dependency-injection/generic-host/GenericHostDI.csproj index b8f92381..771d842d 100644 --- a/docs/samples/dependency-injection/generic-host/GenericHostDI.csproj +++ b/docs/samples/dependency-injection/generic-host/GenericHostDI.csproj @@ -6,8 +6,8 @@ - - + + diff --git a/docs/samples/dependency-injection/keyed/KeyedServices.csproj b/docs/samples/dependency-injection/keyed/KeyedServices.csproj index 35e1ef97..2e90c51b 100644 --- a/docs/samples/dependency-injection/keyed/KeyedServices.csproj +++ b/docs/samples/dependency-injection/keyed/KeyedServices.csproj @@ -7,7 +7,7 @@ - + diff --git a/docs/samples/generic-host/AttributeApi/AttributeApi.csproj b/docs/samples/generic-host/AttributeApi/AttributeApi.csproj index 425b4a3a..23d3f3d2 100644 --- a/docs/samples/generic-host/AttributeApi/AttributeApi.csproj +++ b/docs/samples/generic-host/AttributeApi/AttributeApi.csproj @@ -6,7 +6,7 @@ - + diff --git a/docs/samples/generic-host/BuilderApi/BuilderApi.csproj b/docs/samples/generic-host/BuilderApi/BuilderApi.csproj index 425b4a3a..23d3f3d2 100644 --- a/docs/samples/generic-host/BuilderApi/BuilderApi.csproj +++ b/docs/samples/generic-host/BuilderApi/BuilderApi.csproj @@ -6,7 +6,7 @@ - + diff --git a/src/CommandLineUtils/McMaster.Extensions.CommandLineUtils.csproj b/src/CommandLineUtils/McMaster.Extensions.CommandLineUtils.csproj index 45fd2c8a..63f34efd 100644 --- a/src/CommandLineUtils/McMaster.Extensions.CommandLineUtils.csproj +++ b/src/CommandLineUtils/McMaster.Extensions.CommandLineUtils.csproj @@ -26,7 +26,7 @@ McMaster.Extensions.CommandLineUtils.ArgumentEscaper - + diff --git a/src/Hosting.CommandLine/McMaster.Extensions.Hosting.CommandLine.csproj b/src/Hosting.CommandLine/McMaster.Extensions.Hosting.CommandLine.csproj index 242c9617..04e943c7 100644 --- a/src/Hosting.CommandLine/McMaster.Extensions.Hosting.CommandLine.csproj +++ b/src/Hosting.CommandLine/McMaster.Extensions.Hosting.CommandLine.csproj @@ -9,9 +9,9 @@ - - - + + + diff --git a/test/CommandLineUtils.Tests/McMaster.Extensions.CommandLineUtils.Tests.csproj b/test/CommandLineUtils.Tests/McMaster.Extensions.CommandLineUtils.Tests.csproj index 7d5a5661..1893b139 100644 --- a/test/CommandLineUtils.Tests/McMaster.Extensions.CommandLineUtils.Tests.csproj +++ b/test/CommandLineUtils.Tests/McMaster.Extensions.CommandLineUtils.Tests.csproj @@ -10,14 +10,14 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - + + + 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 542f95ee..6d469475 100644 --- a/test/Hosting.CommandLine.Tests/McMaster.Extensions.Hosting.CommandLine.Tests.csproj +++ b/test/Hosting.CommandLine.Tests/McMaster.Extensions.Hosting.CommandLine.Tests.csproj @@ -10,13 +10,13 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - + + + From 13814e43a6cb2aee89a1f70dda9809210c745ca1 Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Sat, 4 Apr 2026 20:48:54 -0700 Subject: [PATCH 5/5] chore: allow Claude Code reviews on fork PRs Use pull_request_target for auto-reviews so the workflow runs in the base repo context with access to secrets, while safely checking out only the base branch. Remove fork restrictions from the interactive workflow since those events already run in the base repo context. Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/claude-code-review.yml | 4 +--- .github/workflows/claude.yml | 4 ---- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml index c7091153..2d8adda3 100644 --- a/.github/workflows/claude-code-review.yml +++ b/.github/workflows/claude-code-review.yml @@ -1,13 +1,11 @@ name: Claude Code Review on: - pull_request: + pull_request_target: types: [opened, synchronize] jobs: claude-review: - # Only run on PRs from branches in the same repository, not from forks - if: github.event.pull_request.head.repo.full_name == github.repository runs-on: ubuntu-latest permissions: contents: read diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml index 38de20ab..85deb7b6 100644 --- a/.github/workflows/claude.yml +++ b/.github/workflows/claude.yml @@ -18,10 +18,6 @@ jobs: (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) || (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) || (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude'))) - ) && ( - github.event_name == 'issues' || - github.event_name == 'issue_comment' || - github.event.pull_request.head.repo.full_name == github.repository ) runs-on: ubuntu-latest permissions: