From ddc351b0d7382b3627704915b04216b75cc0f842 Mon Sep 17 00:00:00 2001 From: Stuart Meeks Date: Wed, 26 Aug 2026 14:05:35 +0800 Subject: [PATCH] docs: fix the consumer sample, list Providers.GitHub, document version pairing Three follow-ups now that the providers are being re-cut alongside 2.0.0. The consumer sample does not compile, and my first review pass missed it. It declared `public override async Task ExecuteAsync(CommandContext context)`, but Spectre.Console.Cli 0.55's AsyncCommand takes `(CommandContext, CancellationToken)` and the member is protected: CS0534: does not implement inherited abstract member AsyncCommand.ExecuteAsync(CommandContext, CancellationToken) CS0507: cannot change access modifiers when overriding Corrected to protected override with the token parameter, matching this repo's own commands, and compiled against 0.55.0 rather than eyeballed. This is the sample showing how to use a token from a command handler, so it is among the most-copied code in the file. Providers.GitHub was added to the packages table last pass but not to the install block; both now list it. Version pairing is documented because it is what will actually bite on this release: the providers cap at the major boundary, so 2.x needs 2.x. Stated with the reason -- the cap converts what would be a runtime MissingMethodException, since the providers call ICredentialManager, into a resolution error at restore. Co-Authored-By: Claude Opus 5 --- CHANGELOG.md | 12 ++++++++++++ README.md | 17 ++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f115fb..11463b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +- **A third broken README snippet, missed by the first review pass.** The consumer sample — + the one showing how to use a token from a command handler, so among the most-copied code in + the file — does not compile against the Spectre.Console.Cli version this package depends on: + `AsyncCommand.ExecuteAsync` is `protected` and takes `(CommandContext, CancellationToken)`, + not a `public` `(CommandContext)`. Corrected and compiled. The install block also gained the + `Providers.GitHub` package, which the previous pass added to the table but not there, and a + version-pairing table was added: the providers cap at the major boundary, so `2.x` needs + `2.x`, and the cap exists to turn what would be a runtime `MissingMethodException` into a + restore-time resolution error. + +### Fixed + - **README review ahead of 2.0.0: two broken snippets and nine stale or missing claims.** Both broken examples were verified by running them, and both replacements verified the same way. The DPAPI section registered the manager by type diff --git a/README.md b/README.md index 852b55d..25d6bbe 100644 --- a/README.md +++ b/README.md @@ -38,10 +38,25 @@ Pair it with one or more provider packages (or write your own — see [Extending dotnet add package NextIteration.SpectreConsole.Auth.Providers.Adobe dotnet add package NextIteration.SpectreConsole.Auth.Providers.Airtable dotnet add package NextIteration.SpectreConsole.Auth.Providers.SoftwareOne +dotnet add package NextIteration.SpectreConsole.Auth.Providers.GitHub ``` Targets `net8.0` and `net10.0`. +**Pair matching major versions.** Each provider package depends on this one through a +major-capped range, so `2.x` providers require `2.x` of this package and NuGet will refuse to +mix them: + +| This package | Provider packages | +|---|---| +| `2.x` | `2.x` | +| `1.x` | `1.0.1`+ | + +That refusal is deliberate and worth understanding. `ICredentialManager` changed shape in +2.0.0, and the providers call into it — so a `1.x` provider assembly running against `2.x` of +this package would fail at *runtime* with `MissingMethodException`. The version cap turns that +into a resolution error you read at restore time instead. + --- ## Quick start @@ -91,7 +106,7 @@ And from inside any of your command handlers: ```csharp public sealed class SyncCommand(AdobeAuthenticationService auth) : AsyncCommand { - public override async Task ExecuteAsync(CommandContext context) + protected override async Task ExecuteAsync(CommandContext context, CancellationToken cancellationToken) { var token = await auth.AuthenticateAsync(); // use token.GetAuthorizationHeader() on outgoing requests