Skip to content

fix(filter_repos): match full repo paths and normalize trailing slashes#539

Draft
tony wants to merge 3 commits into
masterfrom
sync-edgecases
Draft

fix(filter_repos): match full repo paths and normalize trailing slashes#539
tony wants to merge 3 commits into
masterfrom
sync-edgecases

Conversation

@tony

@tony tony commented Apr 5, 2026

Copy link
Copy Markdown
Member

Summary

  • Fix filter_repos() so that passing a full repo path (e.g. /home/d/study/typescript/tanstack-router, as produced by shell glob expansion) correctly matches the configured repository — previously only the parent directory was matched against the pattern, so exact repo paths never resolved.
  • Fix workspace-root patterns with a trailing slash (e.g. ~/study/typescript/) silently returning no results due to the slash surviving into the fnmatch comparison against the normalized stored path.
  • Fix tilde and $HOME patterns (e.g. ~/study/typescript/tanstack-router) not matching stored absolute paths by expanding them via the existing expand_dir() before comparison.
  • Add two regression tests for the new matching modes: filtering by exact full repo path, and filtering by workspace root with a trailing slash.

Root cause

filter_repos() compared only pathlib.Path(r["path"]).parent against the pattern — designed for wildcard workspace patterns like *github_projects*. This broke when the shell expanded a glob such as ~/study/typescript/tanstack-* into a list of absolute repo paths before handing them to vcspull: discover found those repos in config via dict-key lookup, but sync could not.

Changes

src/vcspull/config.pyfilter_repos() path block:

  • Normalize the pattern through pathlib.Path to strip trailing slashes
  • Expand ~ / $HOME via expand_dir() when present, so tilde patterns match stored absolute paths
  • OR the existing parent-dir fnmatch with a new full-path fnmatch, making exact repo paths resolve without breaking any existing wildcard behavior

Design decisions

OR semantics, not replacement: matching against both r["path"].parent (existing) and r["path"] (new) is strictly additive — it can only produce more matches. All existing wildcard tests continue to pass unchanged.

Reuse expand_dir(): already defined in the same module with expandvars + expanduser semantics; no duplication needed.

Test plan

  • test_filter_dir_exact_repo_path — full absolute repo path resolves to the correct entry
  • test_filter_dir_workspace_root_trailing_slash — workspace root with trailing slash resolves all repos under it
  • test_filter_dir — existing wildcard pattern (*github_project*) still passes
  • 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

@tony tony force-pushed the sync-edgecases branch from 617c05e to be9b627 Compare July 5, 2026 12:47
@codecov

codecov Bot commented Jul 5, 2026

Copy link
Copy Markdown

Codecov Report

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

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #539      +/-   ##
==========================================
+ Coverage   83.30%   83.31%   +0.01%     
==========================================
  Files          32       32              
  Lines        4492     4496       +4     
  Branches      903      904       +1     
==========================================
+ Hits         3742     3746       +4     
  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 added 3 commits July 5, 2026 09:57
why: filter_repos() only compares r["path"].parent against the path pattern,
so full repo paths (e.g. from zsh glob expansion of tanstack-*) and workspace
roots with trailing slashes never match — discoverable via discover but not
via sync.
what:
- add test_filter_dir_exact_repo_path (xfail): full repo path like
  /home/me/myproject/github_projects/kaptan should filter to that repo
- add test_filter_dir_workspace_root_trailing_slash (xfail): workspace root
  with trailing slash should match all repos under it
why: vcspull sync ~/study/typescript/tanstack-* passes zsh-expanded absolute
paths like /home/d/study/typescript/tanstack-router; filter_repos only matched
against r["path"].parent (/home/d/study/typescript), so the full path never
matched. Tilde-prefixed paths and workspace roots with trailing slashes also
failed silently.
what:
- also match fnmatch against r["path"] (full repo path) in addition to parent
- expand ~ and $HOME in pattern before comparing against absolute stored paths
- normalize trailing slash via pathlib.Path so /foo/bar/ matches parent /foo/bar
…ing fixed

why: filter_repos now matches against both r["path"].parent and r["path"],
and normalizes trailing slashes, so the regression tests pass unconditionally.
what:
- remove @pytest.mark.xfail from test_filter_dir_exact_repo_path
- remove @pytest.mark.xfail from test_filter_dir_workspace_root_trailing_slash
- remove unused pytest import
@tony tony force-pushed the sync-edgecases branch from be9b627 to cfc5321 Compare July 5, 2026 15:00
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