Skip to content

Snapshot bump lockfile output and publish stale-lockfile errors (#81) - #119

Open
leynos wants to merge 5 commits into
mainfrom
issue-81-snapshot-lockfile-messages
Open

Snapshot bump lockfile output and publish stale-lockfile errors (#81)#119
leynos wants to merge 5 commits into
mainfrom
issue-81-snapshot-lockfile-messages

Conversation

@leynos

@leynos leynos commented Jun 10, 2026

Copy link
Copy Markdown
Owner

Summary

Closes #81

PR #75 introduced text-based CLI output for lockfile operations that was verified only by substring matching. New tests/unit/test_lockfile_message_snapshots.py adds syrupy snapshot coverage for all four cases:

  • Bump result message with a root Cargo.lock ((lockfile) suffix)
  • Bump result message including a nested tests/ui_lints/Cargo.lock
  • PublishPreflightError message for a single stale lockfile (with repair command)
  • PublishPreflightError message for multiple stale lockfiles

Snapshots use a fixed /ws workspace root so they stay deterministic.

Testing

  • make check-fmt, make lint, make typecheck, and make test (559 passed) all green.
  • coderabbit review --agent: 0 findings.

🤖 Generated with Claude Code

Summary by Sourcery

Add snapshot-based tests to lock in CLI output for lockfile bump and stale lockfile publish preflight messages.

Tests:

  • Add syrupy snapshot tests covering bump result messages with root and nested Cargo.lock files.
  • Add snapshot tests for publish preflight stale lockfile error messages for single and multiple lockfiles.

References

@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Summary

Add Syrupy snapshot coverage for lockfile-related CLI output.

  • Cover root and nested Cargo.lock messages from bump.run.
  • Cover single and multiple stale-lockfile errors from publish.run.
  • Verify repair commands and the (lockfile) suffix.
  • Add a fixture to enable real publish preflight checks.
  • Use /ws as the fixed workspace root for deterministic snapshots.

All 559 tests, formatting, linting, and type checks pass.

Walkthrough

Add Syrupy snapshot tests for bump lockfile messages and publish stale-lockfile errors. Cover root and nested lockfiles, plus single and multiple stale-lockfile cases.

Changes

Lockfile message snapshot coverage

Layer / File(s) Summary
Bump message snapshots
tests/unit/test_lockfile_message_snapshots.py, tests/unit/__snapshots__/test_lockfile_message_snapshots.ambr
Add parametrised snapshots for root and nested Cargo.lock paths, including workspace-relative formatting and the (lockfile) suffix.
Stale-lockfile error snapshots
tests/unit/test_lockfile_message_snapshots.py, tests/unit/conftest.py, tests/unit/__snapshots__/test_lockfile_message_snapshots.ambr
Restore publish preflight checks and snapshot stale-lockfile errors with repair commands for single and multiple lockfiles.

Possibly related PRs

  • leynos/lading#135: Refactors lockfile repository paths covered by these bump and stale-lockfile snapshots.
  • leynos/lading#160: Changes lockfile regeneration and publish preflight paths covered by these snapshots.
  • leynos/lading#164: Changes the publish preflight execution path and its test fixture setup.

Suggested labels: Issue

Poem

Lockfile paths align,
Stale errors show repair commands,
Snapshots guard each line,
Root and nested cases pass,
Four messages stay precise.

🚥 Pre-merge checks | ✅ 19 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Architectural Complexity And Maintainability ❓ Inconclusive Investigation in progress; no verdict has been established. Inspect the changed fixtures and command boundaries before deciding whether the added test structure increases architectural complexity.
✅ Passed checks (19 passed)
Check name Status Explanation
Title check ✅ Passed Keep the title; it accurately describes the snapshot tests and includes the linked issue reference (#81).
Description check ✅ Passed Keep the description; it clearly documents the lockfile snapshot coverage and test results.
Linked Issues check ✅ Passed Keep the changes; they cover all four snapshot scenarios required by issue #81.
Out of Scope Changes check ✅ Passed Keep the changes; all modified files support the requested lockfile message snapshot tests.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Testing (Overall) ✅ Passed Parametrised tests call public bump.run and publish.run, and compare complete root/nested and single/multiple messages to deterministic snapshots; adjacent tests cover repository and freshness beha...
User-Facing Documentation ✅ Passed Pass this check: the PR changes only tests and fixtures, while docs/users-guide.md already documents bump suffixes and stale-lockfile repair commands.
Developer Documentation ✅ Passed The branch adds only unit tests, snapshots, and a pytest fixture; it changes no production API, architecture, tooling, or build requirement, and existing lockfile documentation remains current.
Module-Level Documentation ✅ Passed Verify both changed Python modules: each starts with a clear module docstring describing purpose, test utility, and relationships to related components.
Testing (Unit And Behavioural) ✅ Passed Accept the coverage: parametrised tests drive public bump.run and publish.run paths, snapshot root/nested and single/multiple cases, and assert the stale-lockfile error path.
Testing (Property / Proof) ✅ Passed Treat this as PASS: the PR adds four finite snapshot scenarios and fixture wiring only; it introduces no new range-based invariant or proof assumption requiring property or proof testing.
Testing (Compile-Time / Ui) ✅ Passed Pass: Syrupy tests exercise public bump.run and publish.run paths for four focused cases, with fixed /ws paths and explicit lockfile suffix and repair-command expectations.
Unit Architecture ✅ Passed Keep the change: the patch only updates tests, fixtures, and snapshots; command tests use injected runners and narrow lockfile seams, with no production query or side-effect boundary changed.
Domain Architecture ✅ Passed The PR changes only tests and pytest fixtures; it adds no domain or production logic and uses the existing lockfile repository boundary in test doubles.
Observability ✅ Passed The PR changes only unit tests, snapshots, and a test fixture; it introduces no operational behaviour or production failure mode requiring logs, metrics, tracing, or alerts.
Security And Privacy ✅ Passed Accept: the PR adds only synthetic unit tests and snapshots; scans found no secrets or sensitive data, and no new external command, credential, environment, or permission handling.
Performance And Resource Use ✅ Passed Pass: the PR changes only three test artefacts; it uses four fixed cases, one manifest write, and mocked lockfile/command I/O, so it adds no production resource cost.
Concurrency And State ✅ Passed The PR adds only tests and pytest fixtures. Module patching is function-scoped via monkeypatch, restored after each test, and CI uses process isolation rather than threaded parallel tests.
Rust Compiler Lint Integrity ✅ Passed The PR changes only Python test files, fixtures, and a snapshot; it adds no Rust files or Rust lint suppressions, so this Rust-specific check is not applicable.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch issue-81-snapshot-lockfile-messages

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

@sourcery-ai

sourcery-ai Bot commented Jun 10, 2026

Copy link
Copy Markdown

Reviewer's Guide

Adds deterministic syrupy snapshot tests to validate CLI lockfile-related output formats for bump and publish preflight operations, covering root vs nested Cargo.lock handling and single vs multiple stale lockfile errors.

File-Level Changes

Change Details Files
Add syrupy snapshot coverage for lockfile-related CLI output from bump and publish preflight commands.
  • Introduce a dedicated test module that constructs BumpChanges with a fixed /ws workspace root and exercises bump._format_result_message for configurations with root-only and root+nested Cargo.lock files.
  • Add snapshot tests validating _build_stale_lockfile_message output for single and multiple stale lockfiles, including per-file repair commands and formatting.
  • Configure snapshots via a new .ambr snapshot file to lock in the exact multiline text output for all four scenarios.
tests/unit/test_lockfile_message_snapshots.py
tests/unit/__snapshots__/test_lockfile_message_snapshots.ambr

Assessment against linked issues

Issue Objective Addressed Explanation
#81 Add syrupy snapshot test for bump result message with a root Cargo.lock (lockfile suffix).
#81 Add syrupy snapshot test for bump result message with a nested tests/ui_lints/Cargo.lock.
#81 Add syrupy snapshot tests for PublishPreflightError messages for stale lockfiles: one test for a single stale lockfile and one test for multiple stale lockfiles.

Possibly linked issues


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

@leynos
leynos marked this pull request as ready for review July 27, 2026 21:57
@coderabbitai coderabbitai Bot added the Issue label Jul 27, 2026
sourcery-ai[bot]

This comment was marked as resolved.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/unit/test_lockfile_message_snapshots.py`:
- Line 40: Update every snapshot assertion comparing snapshot with
_result_message(changes) in the lockfile message tests to include a concise,
case-specific assertion message identifying whether the scenario is root,
nested, single-lockfile, or multiple-lockfile. Apply this consistently to all
four assertions while preserving their existing comparisons.
- Around line 33-70: The four repeated snapshot tests should be consolidated
into parametrized pytest cases, grouped in a focused test class where
appropriate. Parameterize the bump-message scenarios with stable IDs such as
root and nested, and the stale-lockfile scenarios with single and multiple;
preserve each existing input setup, snapshot assertion, and test behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 1a96614f-053d-4344-834b-3367bd58a6d9

📥 Commits

Reviewing files that changed from the base of the PR and between a07962b and 61e62bd.

📒 Files selected for processing (2)
  • tests/unit/__snapshots__/test_lockfile_message_snapshots.ambr
  • tests/unit/test_lockfile_message_snapshots.py
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • leynos/cmd-mox (auto-detected)
  • leynos/cuprum (auto-detected)
  • leynos/shared-actions (auto-detected)

Comment thread tests/unit/test_lockfile_message_snapshots.py Outdated
Comment thread tests/unit/test_lockfile_message_snapshots.py Outdated
codescene-access[bot]

This comment was marked as outdated.

codescene-access[bot]

This comment was marked as outdated.

codescene-access[bot]

This comment was marked as outdated.

leynos and others added 4 commits August 1, 2026 12:08
PR #75 introduced text-based CLI output for lockfile operations that
was verified only by substring matching: the (lockfile) suffix in
lading bump result messages and the multi-line stale-lockfile error
raised by lading publish.

Add syrupy snapshot coverage for all four cases: a bump message with a
root Cargo.lock, a bump message including a nested
tests/ui_lints/Cargo.lock, and the PublishPreflightError text for one
and for multiple stale lockfiles including their repair commands.

Closes #81
Group the bump and stale-lockfile message scenarios into focused
parametrized tests. Give every snapshot comparison a case-specific
failure message while preserving the existing output contracts.
Exercise the public `bump.run` and `publish.run` boundaries when
snapshotting lockfile output. Keep external lockfile operations
controlled without coupling the assertions to private formatters.
Restore real publish preflight through its relocated module and stub the
new lockfile inspection adapter boundary. Refresh stale-lockfile snapshots
to retain main's expanded repair guidance after the rebase.
@lodyai
lodyai Bot force-pushed the issue-81-snapshot-lockfile-messages branch from 2dcf73c to d58a544 Compare August 1, 2026 10:19
codescene-access[bot]

This comment was marked as outdated.

@codescene-access codescene-access Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

No quality gates enabled for this code.

@pandalump

Copy link
Copy Markdown
Collaborator

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@leynos

leynos commented Aug 14, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai Have the following now been resolved?

  • The tests rely on private helpers (bump._format_result_message, _build_stale_lockfile_message), which may change frequently; consider routing through the public CLI interface or adding a thin public wrapper to reduce brittleness.
  • The stale lockfile tests are very similar; you could use a parametrized test (single vs multiple lockfiles) to reduce duplication while keeping snapshot coverage intact.

@leynos

leynos commented Aug 14, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai Please suggest a fix for this issue and supply a prompt for an AI coding agent to enable it to apply the fix. Include the file and symbol names indicated in the issue at the head of your response.

Excess Number of Function Arguments

tests/unit/test_lockfile_message_snapshots.py: TestBumpLockfileMessages.test_message

What lead to degradation?

TestBumpLockfileMessages.test_message has 5 arguments, max arguments = 4

Why does this problem occur?

Functions with many arguments indicate either a) low cohesion where the function has too many responsibilities, or b) a missing abstraction that encapsulates those arguments.
The threshold for the Python language is 4 function arguments.

How to fix it?

Start by investigating the responsibilities of the function. Make sure it doesn't do too many things, in which case it should be split into smaller and more cohesive functions. Consider the refactoring INTRODUCE PARAMETER OBJECT to encapsulate arguments that refer to the same logical concept.

Helpful refactoring examples

This code health issue has been solved before in this project. Here are some examples for inspiration:

undefined

# conftest.py (114b752)
 def publish_fixtures(
-    tmp_path: Path,
-    make_crate: typ.Callable[[Path, str, _CrateSpec | None], WorkspaceCrate],
-    make_workspace: typ.Callable[[Path, WorkspaceCrate], WorkspaceGraph],
-    make_config: typ.Callable[..., config_module.LadingConfig],
-    make_dependency: typ.Callable[[str], WorkspaceDependency],
-    publish_options: publish.PublishOptions,
+    request: pytest.FixtureRequest, publish_options: publish.PublishOptions
 ) -> PublishFixtures:
     """Return the composite publish fixtures used across unit suites."""
+    tmp_path: Path = request.getfixturevalue("tmp_path")
+    make_crate = request.getfixturevalue("make_crate")
+    make_workspace = request.getfixturevalue("make_workspace")
+    make_config = request.getfixturevalue("make_config")
+    make_dependency = request.getfixturevalue("make_dependency")
     return PublishFixtures(

@coderabbitai

This comment was marked as resolved.

@coderabbitai

coderabbitai Bot commented Aug 14, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

ast-grep outline tests/unit/test_lockfile_message_snapshots.py --items all
ast-grep outline tests/unit/conftest.py --items all --match 'enable_publish_preflight|disable_publish_preflight'

printf '\n--- private-helper references and public command calls ---\n'
rg -n -C 4 '(_format_result_message|_build_stale_lockfile_message|\bbump\.run\s*\(|\bpublish\.run\s*\()' \
  tests/unit/test_lockfile_message_snapshots.py

printf '\n--- stale-lockfile test implementation ---\n'
rg -n -A 100 -B 12 'class\s+TestStaleLockfileMessages|def\s+test_message\s*\(' \
  tests/unit/test_lockfile_message_snapshots.py

Length of output: 6579


@leynos Yes. Both items are resolved.

  • tests/unit/test_lockfile_message_snapshots.py now calls the public command boundaries: bump.run(...) at Line 79 and publish.run(...) at Line 149. The file has no references to bump._format_result_message or _build_stale_lockfile_message.
  • TestStaleLockfileMessages.test_message now uses one parametrized test. It covers both single and multiple stale-lockfile cases at Lines 96-113. The shared test retains separate snapshot assertions and case-specific failure messages.

You are interacting with an AI system.

@leynos

leynos commented Aug 14, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai Please suggest a fix for this issue and supply a prompt for an AI coding agent to enable it to apply the fix. Include the file and symbol names indicated in the issue at the head of your response.

Excess Number of Function Arguments

tests/unit/test_lockfile_message_snapshots.py: TestStaleLockfileMessages.test_message
tests/unit/test_lockfile_message_snapshots.py: TestBumpLockfileMessages.test_message

What lead to degradation?

TestStaleLockfileMessages.test_message has 5 arguments, max arguments = 4
TestBumpLockfileMessages.test_message has 5 arguments, max arguments = 4

Why does this problem occur?

Functions with many arguments indicate either a) low cohesion where the function has too many responsibilities, or b) a missing abstraction that encapsulates those arguments.
The threshold for the Python language is 4 function arguments.

How to fix it?

Start by investigating the responsibilities of the function. Make sure it doesn't do too many things, in which case it should be split into smaller and more cohesive functions. Consider the refactoring INTRODUCE PARAMETER OBJECT to encapsulate arguments that refer to the same logical concept.

Helpful refactoring examples

This code health issue has been solved before in this project. Here are some examples for inspiration:

undefined

# conftest.py (114b752)
 def publish_fixtures(
-    tmp_path: Path,
-    make_crate: typ.Callable[[Path, str, _CrateSpec | None], WorkspaceCrate],
-    make_workspace: typ.Callable[[Path, WorkspaceCrate], WorkspaceGraph],
-    make_config: typ.Callable[..., config_module.LadingConfig],
-    make_dependency: typ.Callable[[str], WorkspaceDependency],
-    publish_options: publish.PublishOptions,
+    request: pytest.FixtureRequest, publish_options: publish.PublishOptions
 ) -> PublishFixtures:
     """Return the composite publish fixtures used across unit suites."""
+    tmp_path: Path = request.getfixturevalue("tmp_path")
+    make_crate = request.getfixturevalue("make_crate")
+    make_workspace = request.getfixturevalue("make_workspace")
+    make_config = request.getfixturevalue("make_config")
+    make_dependency = request.getfixturevalue("make_dependency")
     return PublishFixtures(

@coderabbitai

This comment was marked as resolved.

Use the parametrized test IDs as the sole case labels so the test methods
do not carry unused scenario arguments.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add syrupy snapshot tests for bump lockfile messages and publish stale-lockfile errors

2 participants