Skip to content

fix: v2 panel batch — doc pins, actionable deprecations, release idempotency, load-order + dual-install guards - #222

Merged
pftg merged 1 commit into
masterfrom
fix/v2-panel-batch
Aug 22, 2026
Merged

fix: v2 panel batch — doc pins, actionable deprecations, release idempotency, load-order + dual-install guards#222
pftg merged 1 commit into
masterfrom
fix/v2-panel-batch

Conversation

@pftg

@pftg pftg commented Aug 22, 2026

Copy link
Copy Markdown
Collaborator

Six small items from the as-shipped v2 architecture panel, each with its own evidence.

1. Doc version pins (README.md, docs/UPGRADING.md)

All 2.0.0.alpha1 pin examples updated to 2.0.0.beta1, with "(or the latest 2.0.0 prerelease)" where it reads naturally.
Evidence: grep -rn alpha1 README.md docs/ → no matches (CHANGELOG untouched by design).

2. Actionable deprecation warnings (lib/snap_diff/deprecation.rb)

The warning now appends (called from <file:line>) — the first caller frame outside the gem's lib dir (same filtering idea as BacktraceFilter). Warn-once semantics unchanged.
Evidence (TDD): new test "warning names the caller's file and line" was red first (Expected /called from .../ to match "...instead.\n"), green after the implementation. End-to-end probe through the legacy shim path:

$ ruby -Ilib -e 'require "snap_diff"; Capybara::Screenshot::Diff::ImageCompare'
[snap_diff deprecation] `Capybara::Screenshot::Diff::ImageCompare` is deprecated (constant); use `SnapDiff::Comparison` instead. (called from -e:1)

(gem-internal legacy_shims frames correctly skipped).

3. Stale "dormant" comment (lib/snap_diff/deprecation.rb)

Header rewritten: the module is the live warn-once engine for the legacy-namespace shims (snap_diff/legacy_shims routes every const_missing hit through it), not dormant machinery.

4. release.yml tag idempotency

"Create tag" now fetches the tag ref (checkout doesn't fetch tags), skips when the tag already exists at HEAD, and fails loudly — never retags — when it exists at a different commit.
Evidence: shell simulation of all three cases: fresh run → tagged; re-run → skip: exists at HEAD; moved HEAD → FAIL LOUD: exists at <sha>, HEAD <sha> with exit 1.

5. Load-order guard (test/unit/snap_diff_test.rb)

New subprocess probe: under bare require "snap_diff", lib/capybara_screenshot_diff.rb must be absent from $LOADED_FEATURES. This turns the #208 acyclic-require-graph fix (the deadlock/partial-initialization bug class) from discipline into an executable contract — a panel probe previously reintroduced the cycle and the suite stayed green.
Gate evidence: temporarily adding require "capybara_screenshot_diff" to lib/snap_diff/config.rb → guard red (umbrella loaded via: .../lib/capybara_screenshot_diff.rb); revert → green.

6. Dual-install conflict guard (lib/snap_diff.rb)

Both gem names ship identical files; with both activated, requires resolve silently from whichever activated first and version skew is undetectable. The shared entry now raises SnapDiff::DualInstallError (naming both gems, instructing to remove one) when Gem.loaded_specs contains both capybara-screenshot-diff and snap_diff-capybara. Single-gem installs, local dev from source (neither spec loaded), and the test suite are unaffected.
Evidence (TDD): tests red first (NameError: uninitialized constant SnapDiff::DualInstallError), green after; pass-cases cover each single gem and the empty (source-checkout) case.

Test evidence

  • Baseline (origin/master 393bacb): rake test:unit → 488 runs, 1417 assertions, 0 failures
  • After: rake test:unit492 runs, 1427 assertions, 0 failures, 0 errors
  • Full rake test525 runs, 1472 assertions, 0 failures, 0 errors, 6 skips (pre-existing driver skips)
  • standardrb on all touched Ruby files: no offenses

🤖 Generated with Claude Code

Summary by Sourcery

Harden the v2 prerelease transition with safer release tagging, clearer deprecations, installation conflict detection, load-order safeguards, and current documentation.

Bug Fixes:

  • Add actionable caller file and line information to legacy deprecation warnings while preserving warn-once behavior.
  • Prevent incompatible dual activation of the capybara-screenshot-diff and snap_diff-capybara gems with a clear error.
  • Make release tag creation safe to rerun without retagging existing releases.

Enhancements:

  • Enforce that the lean snap_diff entry point does not load the umbrella integration file, protecting the acyclic load-order contract.
  • Update v2 prerelease references and upgrade guidance from alpha1 to beta1.
  • Clarify the deprecation engine documentation to reflect its active legacy-shim role.

CI:

  • Add tests covering deprecation attribution, load-order protection, and dual-install handling.

Documentation:

  • Update README and upgrade documentation to reference the beta1 prerelease or the latest 2.0 prerelease.

Tests:

  • Expand unit coverage for caller attribution, dual-install detection, and bare-require load behavior.

Summary by CodeRabbit

  • Bug Fixes

    • Prevented conflicts when both supported gem variants are loaded, with a clear error message.
    • Improved deprecation warnings by identifying the calling file and line number.
    • Made release tag creation safer by avoiding duplicate or unintended retagging.
  • Documentation

    • Updated installation and upgrade guidance from the 2.0 alpha release to the 2.0 beta release.
    • Clarified that the latest 2.0.0 prerelease can be used.

…potency, load-order + dual-install guards

Six small items from the as-shipped v2 architecture panel:

1. Docs: pin examples updated 2.0.0.alpha1 -> 2.0.0.beta1 (or latest
   2.0.0 prerelease) in README and docs/UPGRADING.md.
2. Deprecation warnings now name the first caller frame outside the
   gem's lib dir ("called from file:line"); warn-once semantics
   unchanged.
3. Deprecation module header rewritten: it is the live warn-once engine
   for the legacy namespace shims, not dormant machinery.
4. release.yml Create tag step is idempotent: skips when the tag exists
   at HEAD, fails loudly (never retags) when it exists elsewhere.
5. New subprocess guard: bare require "snap_diff" must never load the
   umbrella capybara_screenshot_diff.rb — pins the #208 acyclic require
   graph as an executable contract.
6. Dual-install guard in lib/snap_diff.rb: raises DualInstallError when
   both capybara-screenshot-diff and snap_diff-capybara gems are
   activated (identical files, silent version skew otherwise).
@sourcery-ai

sourcery-ai Bot commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

Updates docs for the 2.0 beta prerelease, makes deprecation warnings more actionable, strengthens load-order and dual-install safeguards in the core SnapDiff entrypoint, and makes the GitHub release tagging workflow idempotent and safer to rerun.

Sequence diagram for actionable legacy deprecation warnings

sequenceDiagram
    participant UserCode
    participant LegacyShims
    participant Deprecation
    participant Kernel

    UserCode->>LegacyShims: const_missing
    LegacyShims->>Deprecation: warn(subject, replacement, category)
    Deprecation->>Deprecation: caller_locations(1)
    Deprecation->>Deprecation: origin_for(locations)
    Deprecation->>Kernel: warn(message with file:line)
    Kernel-->>UserCode: deprecation warning
Loading

Flow diagram for safe idempotent release tagging

flowchart TD
    A[Create tag] --> B[Fetch remote tag ref]
    B --> C{Tag exists?}
    C -->|No| D[git tag -a and git push]
    C -->|Yes| E{Tag points to HEAD?}
    E -->|Yes| F[Skip tag creation]
    E -->|No| G[Fail workflow; refuse to retag]
Loading

File-Level Changes

Change Details Files
Make GitHub Actions release tag creation idempotent and safe to rerun without retagging.
  • Wrap tag name in TAG variable and fetch existing remote tag refs before creation.
  • Detect when tag already exists at HEAD and skip creation with a log message.
  • Detect when tag exists at a different commit, emit a GitHub error annotation, and exit with status 1.
  • Only configure git user and create/push tag when it does not yet exist.
.github/workflows/release.yml
Update user-facing docs to reference the 2.0.0 beta prerelease and mention latest prerelease where relevant.
  • Change Gemfile pin examples from 2.0.0.alpha1 to 2.0.0.beta1.
  • Add explanatory text that users can use the latest 2.0.0 prerelease in README and upgrading guide.
  • Update upgrade checklist to reference the beta pin and latest prerelease option.
README.md
docs/UPGRADING.md
Enhance deprecation warning infrastructure to attribute the call site file and line while clarifying its active role.
  • Rewrite Deprecation module header comment to describe its role in legacy-namespace shims.
  • Introduce GEM_LIB_DIR constant to identify gem-internal library paths.
  • Change warning emission to pass caller_locations into message construction.
  • Implement origin_for to pick the first caller frame outside the gem lib dir and append a "called from file:line" suffix when present.
  • Add unit test ensuring warnings include the caller file and line, treating the test file as user code.
lib/snap_diff/deprecation.rb
test/unit/snap_diff_deprecation_test.rb
Add runtime guard and tests to prevent reintroducing cyclic requires between snap_diff and capybara_screenshot_diff.
  • Introduce a subprocess test that requires "snap_diff" and asserts capybara_screenshot_diff.rb is absent from $LOADED_FEATURES.
  • Abort with a clear message if the umbrella file is found, making the acyclic require contract executable.
test/unit/snap_diff_test.rb
Introduce a dual-install conflict guard at the SnapDiff entrypoint to prevent silently divergent versions when both gem names are installed.
  • Define SnapDiff::DualInstallError and assert_single_gem! helper that inspects Gem.loaded_specs.
  • Raise a detailed error when both capybara-screenshot-diff and snap_diff-capybara specs are present, instructing users to remove one.
  • Invoke SnapDiff.assert_single_gem! at file load so the guard runs on require "snap_diff".
  • Add tests covering the error case with both gems and pass cases for single-gem installs and source-only development.
lib/snap_diff.rb
test/unit/snap_diff_test.rb

Possibly linked issues

  • #ADR-004: The PR directly supports ADR-004's v2 namespace migration with actionable deprecations, compatibility guards, and load-order validation.

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai

coderabbitai Bot commented Aug 22, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b039e3b8-e05b-4ee3-aecd-0ab24aaf5d83

📥 Commits

Reviewing files that changed from the base of the PR and between 393bacb and cc660fd.

📒 Files selected for processing (7)
  • .github/workflows/release.yml
  • README.md
  • docs/UPGRADING.md
  • lib/snap_diff.rb
  • lib/snap_diff/deprecation.rb
  • test/unit/snap_diff_deprecation_test.rb
  • test/unit/snap_diff_test.rb

📝 Walkthrough

Walkthrough

The PR adds a dual-gem loading guard, caller locations to deprecation warnings, idempotent release tag creation, and updated 2.0 prerelease documentation.

Changes

Runtime safeguards

Layer / File(s) Summary
Single-gem loading guard
lib/snap_diff.rb, test/unit/snap_diff_test.rb
SnapDiff raises SnapDiff::DualInstallError when both supported gem names are loaded. Tests cover bare loading, dual activation, single-gem activation, and source-tree usage.
Deprecation caller reporting
lib/snap_diff/deprecation.rb, test/unit/snap_diff_deprecation_test.rb
Deprecation warnings append the first caller outside the gem library as file:line. Tests verify the caller location.

Release and documentation

Layer / File(s) Summary
Release tag and prerelease updates
.github/workflows/release.yml, README.md, docs/UPGRADING.md
The release workflow skips matching existing tags and fails on mismatched tags. Documentation updates 2.0 examples from alpha1 to beta1 or the latest prerelease.

Estimated code review effort: 3 (Moderate) | ~20 minutes

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/v2-panel-batch

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@pftg
pftg merged commit 40bbf96 into master Aug 22, 2026
5 of 6 checks passed
@pftg
pftg deleted the fix/v2-panel-batch branch August 22, 2026 21:36

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've reviewed your changes and they look great!

Sourcery assessment

Needs a human reviewer. A faulty release decision can create or accept the wrong version tag and proceed with publishing, leaving an externally visible release artifact that reverting the workflow does not remove. The dual-install guard can also turn application startup into a failure for environments with both gem specs activated, though that part is reversible by reverting.


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant