Guard the public API surface with Verify snapshots (leaner alternative to #530)#540
Draft
ChrisonSimtian wants to merge 2 commits into
Draft
Guard the public API surface with Verify snapshots (leaner alternative to #530)#540ChrisonSimtian wants to merge 2 commits into
ChrisonSimtian wants to merge 2 commits into
Conversation
The tooling generator now emits [System.CodeDom.Compiler.GeneratedCode] alongside the existing [ExcludeFromCodeCoverage] on every wrapper class, settings/data class, extension class and enumeration it produces. This gives a reflection-visible marker that a metadata-based public-API snapshot can filter on, so the ~60k generated tool symbols can be excluded without the file-level knowledge a Roslyn analyzer has. All 63 *.Generated.cs wrappers regenerated via `./build.sh GenerateTools`. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds tests/Fallout.PublicApi.Specs: one Verify snapshot of each consumer-facing assembly's public surface, produced by PublicApiGenerator. A surface change fails the matching case until its .verified.txt is re-accepted, so an accidental break fails CI and an intentional one lands as a reviewable snapshot diff. This is the leaner counterpart to the Roslyn PublicApiAnalyzers guard (Fallout-build#530): one test file plus snapshots under tests/, reusing the mandated xUnit + Verify stack, in place of per-assembly PublicAPI.*.txt in src/ with editorconfig/WarningsAsErrors plumbing. Covers the same 11 assemblies Fallout-build#530 opted in. Generated tool wrappers are excluded by their [GeneratedCode] marker. A metadata-based tool can only exclude whole types, so a class split across a generated and a hand-written partial (the 20 <Tool>Tasks classes) is dropped entirely — ~25 hand-written members that Fallout-build#530's file-level exclusion keeps. That residual gap is the precision ceiling of the approach and the main axis for the two PRs' comparison. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Collaborator
Author
|
@dennisdoomen thats another approach... |
Collaborator
Oh, that's quite a disappointment indeed. Although I'm not sure how the approach in FluentAssertions deals with that. |
Collaborator
|
Puh.. either one is a suprisingly "high" effort... For me: either one is fine... Edit: I don't get, though, why the tool wrappers do not count as "public API" here? Since this also ships to the consumer (and at worst break things - I remember times where "suddenly" tool extension were gone or renamed). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Alternative to #530 for public-API break detection — the leaner, Verify-snapshot approach (the path taken in the TvdbApi modernisation). Raised so the two can be compared side by side. Pick one — not for merge alongside #530. Non-breaking / dev-infra only.
Approach
tests/Fallout.PublicApi.Specs: one Verify snapshot of each consumer-facing assembly's public surface, produced byPublicApiGenerator. A surface change → snapshot mismatch → CI fails until the.verified.txtis re-accepted.PublicApiGenerator); everything else is the mandated xUnit + Verify stack already in the repo.vs #530 (Roslyn PublicApiAnalyzers)
PublicAPI.*.txtinsrc/(×11).verified.txtintests/.editorconfig+Directory.Build.props+WarningsAsErrorsPackageVersion+ one test file.txtdiff.verified.txtdiffGenerated tool wrappers
The ~60k generated tool symbols are excluded via a
[GeneratedCode]marker now stamped byFallout.Tooling.Generator(all 63*.Generated.csregenerated).PublicApiGeneratorreads compiled metadata, so it can only exclude whole types — #530 excludes by file (*.Generated.cs).<Tool>Tasksclasses are split partials (generated half + hand-written half merged into one type). The merged type carries[GeneratedCode], so it is dropped whole — ~25 hand-written members that #530 keeps go unguarded here. Member-level file precision is not reachable by a metadata-based tool. This is the cost of "leaner".Cost of the generated-code stamp
The
[GeneratedCode]attribute is the bulk of the diff: 63 regenerated wrappers (~1.2k lines of pure churn) + the 4 one-line generator edits. Without needing generated exclusion this approach would be ~150 lines; #530's file-level exclusion avoids touching the generator at all.Verified
dotnet buildgreen; specs 11/11 pass (baseline round-trips clean)..verified.txtdiff.AzureKeyVault*,MSBuildProject,DotNetRuntimeIdentifier, …) kept.[GeneratedCode]stamp round-trips throughGenerateTools(theVerifyGeneratedToolsgit-clean gate stays satisfied).Decision
Two viable guards for the same goal. #530 = file-precise, zero gap, more config + a heavier analyzer dep. This = leaner, reuses the existing test stack, but a ~25-member precision gap on split-partial tool tasks and a generator change to stamp
[GeneratedCode].