Skip to content

feat(sync[dry-run]): auto-show all matched repos when filtering explicitly#540

Draft
tony wants to merge 3 commits into
sync-edgecasesfrom
sync-implicit-show-unchanged
Draft

feat(sync[dry-run]): auto-show all matched repos when filtering explicitly#540
tony wants to merge 3 commits into
sync-edgecasesfrom
sync-implicit-show-unchanged

Conversation

@tony

@tony tony commented Apr 5, 2026

Copy link
Copy Markdown
Member

Summary

  • Fix a confusing DX gap: vcspull sync tanstack-* --dry-run matched 5 repos but only displayed the 1 needing action — the 4 unchanged repos were hidden unless --show-unchanged was passed, even though the user had already scoped the command to specific repos.
  • Add has_explicit_patterns to PlanRenderOptions: computed as not sync_all and bool(repo_patterns) in sync(), propagated to both the human and JSON/NDJSON render paths.
  • Improve tip message: suppress the --show-unchanged hint when unchanged rows are already visible due to explicit filtering; show a shorter "run without --dry-run to apply" tip instead.
  • Add xfail field and request.applymarker support to DryRunPlanFixture / test_sync_dry_run_plan_human for per-fixture conditional xfail without stopping test execution.

Design decisions

OR semantics at the call site: show_unchanged or has_explicit_patterns is passed to _filter_entries_for_display() rather than changing the function's own signature — the helper stays minimal and doesn't need to know about the concept of "explicit patterns".

--all unaffected: has_explicit_patterns is only True when repo_patterns is non-empty and sync_all is False. Bulk --all dry-runs retain the hide-unchanged default.

request.applymarker over pytest.xfail(): imperative pytest.xfail() short-circuits execution and can never become XPASS. request.applymarker applies the marker but still runs the test body, so the fixture transitions XFAIL → XPASS → PASS cleanly across the three-commit workflow.

Before / After

Before:

Progress: 5/5 +:0 ~:1 ✓:4 ⚠:0 ✗:0
Plan: 0 to clone (+), 1 to update (~), 4 unchanged (✓), 0 blocked (⚠), 0 errors (✗)

~/study/typescript/
  ~ tanstack-router  ~/study/typescript/tanstack-router  remote state unknown; use --fetch
Tip: run without --dry-run to apply. Use --show-unchanged to include ✓ rows.

After:

Progress: 5/5 +:0 ~:1 ✓:4 ⚠:0 ✗:0
Plan: 0 to clone (+), 1 to update (~), 4 unchanged (✓), 0 blocked (⚠), 0 errors (✗)

~/study/typescript/
  ~ tanstack-router  ~/study/typescript/tanstack-router  remote state unknown; use --fetch
  ✓ tanstack-devtools  ~/study/typescript/tanstack-devtools
  ✓ tanstack-store     ~/study/typescript/tanstack-store
  ✓ tanstack-table     ~/study/typescript/tanstack-table
  ✓ tanstack-virtual   ~/study/typescript/tanstack-virtual
Tip: run without --dry-run to apply.

Test plan

  • unchanged-implicit-filter--dry-run with explicit name pattern and pre-synced repo shows row without --show-unchanged
  • unchanged-show — existing --show-unchanged flag still works
  • uv run ruff check . --fix --show-fixes — no lint errors
  • uv run ruff format . — no formatting changes
  • uv run mypy — no type errors
  • uv run py.test --reruns 0 — full suite passes

@codecov

codecov Bot commented Apr 5, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 83.32%. Comparing base (cfc5321) to head (6417c6f).

Additional details and impacted files
@@               Coverage Diff               @@
##           sync-edgecases     #540   +/-   ##
===============================================
  Coverage           83.31%   83.32%           
===============================================
  Files                  32       32           
  Lines                4496     4498    +2     
  Branches              904      904           
===============================================
+ Hits                 3746     3748    +2     
  Misses                499      499           
  Partials              251      251           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@tony tony force-pushed the sync-edgecases branch from 617c05e to be9b627 Compare July 5, 2026 12:47
@tony tony force-pushed the sync-implicit-show-unchanged branch from d22bd28 to 213a30d Compare July 5, 2026 12:48
@tony tony force-pushed the sync-edgecases branch from be9b627 to cfc5321 Compare July 5, 2026 15:00
tony added 3 commits July 5, 2026 10:01
…atterns

why: when filtering to specific repos, the user expects all matched repos to
appear — needing --show-unchanged to see the 4 unchanged out of 5 matched is
unintuitive. Regression test documents the desired behavior before the fix.
what:
- add xfail field to DryRunPlanFixture (defaults False, zero churn on existing fixtures)
- add pytest.xfail() guard in test_sync_dry_run_plan_human when xfail=True
- add unchanged-implicit-filter fixture: --dry-run with explicit name pattern,
  pre-synced repo, expects ✓ row without --show-unchanged flag
…itly

why: vcspull sync tanstack-* shows 5 matched repos but only the 1 needing
action — the user has already scoped the command to specific repos and
shouldn't need --show-unchanged to confirm the filter worked.
what:
- add has_explicit_patterns field to PlanRenderOptions
- set it true in sync() when repo_patterns passed without --all
- fold it into the show_unchanged OR at both _filter_entries_for_display
  call sites (human and JSON/NDJSON paths)
- add PLAN_TIP_MESSAGE_FILTERED: suppress --show-unchanged hint when
  unchanged rows are already visible due to explicit filtering
- wire request.applymarker into test_sync_dry_run_plan_human to support
  per-fixture xfail without stopping test execution
…ed fixed

why: unchanged-implicit-filter now passes unconditionally.
what:
- remove xfail=True from unchanged-implicit-filter fixture
@tony tony force-pushed the sync-implicit-show-unchanged branch from 213a30d to 6417c6f Compare July 5, 2026 15:01
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