test(cli): port pnpm monorepo filter tests + wire --fail-if-no-match#457
test(cli): port pnpm monorepo filter tests + wire --fail-if-no-match#457
Conversation
Phase 3 batch 1 of the pnpm test import (5 tests from pnpm/test/monorepo/index.ts → test/pnpm_monorepo_index.bats): no-projects-matched warn-and-exit-0 (line 31, 3 sub-cases), topological run order under --filter=...<pkg> with intervening unrelated workspace packages (line 512), and ./packages/** directory glob (line 1662 sub-case 2). Aube-side fixes that landed alongside the ports: - wire the parsed-but-unread --fail-if-no-match global into EffectiveFilter; soften aube list's no-match path from hard-error to "No projects matched the filters in <root>" + exit 0 (suppressed under --parseable, hard-errors with --fail-if-no-match) - accept --depth=-1 as an alias for --depth=0 (pnpm's spelling for "no transitives") - parse ./packages/** as a synonym for ./packages — aube's path selector is "at or under" by design, no separate legacyDirFiltering gate - filtered list --parseable now leads each importer block with the package directory path; non-filtered --parseable keeps the legacy 3-field tab-separated dep records legacyDirFiltering added to the explicit-skip section in PNPM_TEST_IMPORT.md — aube's path-selector default is the more useful one. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Greptile SummaryThis PR ports 5 pnpm monorepo filter tests into Confidence Score: 4/5Safe to merge with minor caveats around the filtered --parseable format change and the /**-only path edge case. No P0/P1 issues found. Two P2 observations: run_filtered redundantly re-derives format that run already computed, and the /**-only absolute path collapses to an empty PathBuf via the new strip_suffix — a behaviour change from pre-PR though an extremely unlikely input. All other changes are well-tested and the previous review concerns have been correctly addressed. crates/aube/src/commands/list.rs and crates/aube-workspace/src/selector.rs Important Files Changed
Reviews (4): Last reviewed commit: "[autofix.ci] apply automated fixes" | Re-trigger Greptile |
…rkspace error Address greptile review on #457: - Pre-compute workspace_pkgs + selected once in `run()` and thread the result into `run_filtered`, eliminating the duplicate find_workspace_packages + select_workspace_packages walk on the match path. - Restore the "aube list: --filter requires a workspace root..." hard error when filter is set but no workspace config exists at or above the cwd. The previous patch silently downgraded that case to the soft "No projects matched" path. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…o-match error Address cursor bugbot review on #457: - The `raw.ends_with("/**")` arm in the path-selector branch was too broad — it silently promoted any `<name>/**` (e.g. `@scope/**`) from a NameGlob to a Path selector, breaking scoped-name globs. Drop that arm: `./packages/**` already enters via `starts_with("./")`, and the `strip_suffix("/**")` step still collapses it onto the existing "at or under" path semantics. Add a regression test asserting `@scope/**` parses as `NameGlob`. - The `--fail-if-no-match` error formatted only `filter.filters`, so passing only `--filter-prod` selectors produced `filter []`. Fold both lists into the message — and render them as a flat `["foo", "bar"]` list rather than dumping the EffectiveFilter struct. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ck filtered parseable shape Address review on #457: - Cursor (medium): the no-match warning was suppressed only when the `--parseable` shortcut was set, but `--format parseable` / `--format json` set `args.format` instead, so those routes still printed the human "No projects matched..." message and corrupted machine-parseable stdout. Hoist the format resolution above the no-match check and gate the warning on `format == Default`. Cleans the same gap for `--json` / `--format json` (the previous suppression only checked `args.parseable`). - Greptile (P1): filtered `aube list --parseable` now emits a leading package-directory line per importer (matches the help-text contract in `list.rs` and pnpm's shape). Lock the format with a bats regression so a future format change has to update the test. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 5888dcc. Configure here.
Benchmark changesPublic ratios: warm installs vs Bun 5x -> 14x; warm installs vs pnpm 6x -> 17x.
d0ebf03 vs 6769405 | aube/bun/pnpm | 3 scenarios | 3 runs | 500mbit/50ms | generated by Codex. |
Address cursor bugbot review on #457: mapping `--depth=-1` to `0` diverged from pnpm. In pnpm `--depth=-1` means "list project headers only, no deps", while `--depth=0` means "direct deps only". Aube's prior collapse silently leaked direct deps in `--parseable` output for projects that actually had deps. The previous bats test passed only because the fixture had zero-dep projects. Replace `pub depth: usize` with a `Depth` struct that carries both `include_direct: bool` and the transitive `max: usize`. Wire it through: - `--depth=-1` → `Depth { include_direct: false, max: 0 }` - `--depth=N` → `Depth { include_direct: true, max: N }` - `--depth=Inf` → `Depth { include_direct: true, max: usize::MAX }` `render_default_for_importer` / `render_parseable_for_importer` / `json_importer_value` early-return after the project header when `include_direct` is false. Strengthen the directory-filtering bats test with a real dep on `is-odd` so it would now fail under the old collapse, plus a sanity check that `--depth=0` still surfaces direct deps. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Summary
Phase 3 batch 1 of the pnpm test import — the first 5 filter-semantics
tests from
pnpm/test/monorepo/index.tstranslated into a newtest/pnpm_monorepo_index.bats, plus the small aube-side fixes the ports surfaced.Tests ported
monorepo/index.ts:31(3 sub-cases — default,--fail-if-no-match,--parseable)monorepo/index.ts:512--filter=...<pkg>topological run order with intervening unrelated workspace pkgsmonorepo/index.ts:1662(sub-case 2)--filter=./packages/**directory globAube-side fixes
--fail-if-no-match— the global flag was parsed atcrates/aube/src/main.rs:217but never read. Addedfail_if_no_match: booltoEffectiveFilterand softenedaube list's no-match path from a hard error to"No projects matched the filters in <root>"+ exit 0 (suppressed under--parseable; hard-errors only with--fail-if-no-match).--depth=-1accepted as an alias for--depth=0to match pnpm's "no transitives" spelling../packages/**parses as a synonym for./packages— aube's path selector is "at or under" by design, so the pnpm v9 exact-vs-recursive split (gated onlegacyDirFiltering) doesn't apply. Explicitly skipped perPNPM_TEST_IMPORT.md— aube's default is the more useful one.list --parseablenow leads each importer block with the package directory path so consumers can find each filtered project on its own line. Non-filtered--parseablekeeps the legacy 3-field tab-separated dep records (asserted bytest/list.bats:171).Documented divergences (not fixed here)
monorepo/index.ts:56("no projects found" onprepareEmpty()+list -r) — needs broaderproject_root()tolerance (workspace-yaml-only or no-manifest root). On the same fault line aslist/run/install/query/why— touch them together when this lands.monorepo/index.ts:1662sub-case 1 (./packagesmatches nothing) — pnpm v9 default is exact-directory match gated onlegacyDirFiltering=false; aube doesn't implementlegacyDirFilteringand treats./packagesas "at or under".Test plan
cargo build,cargo fmt,cargo clippy --all-targets -- -D warningscargo test --workspace --lib— all greenmise run test:bats test/pnpm_monorepo_index.bats— 5/5 passmise run test:bats test/filter.bats test/list.bats— 43/43 pass (regression check)🤖 Generated with Claude Code
Note
Medium Risk
Touches workspace selector parsing and
aube listoutput/exit-code behavior under filtering, which can affect CI scripts and machine parsers relying on prior semantics.Overview
Aligns workspace filtering behavior with pnpm for parity and CI use by threading the global
--fail-if-no-matchflag throughEffectiveFilterand updatingaube list --filterto warn+exit 0 on no matches by default (optionally hard-failing with--fail-if-no-match) while suppressing the warning for machine formats.Updates
aube list’s--depthhandling by introducing aDepthtype so--depth=-1can list project headers only (no deps) across default/JSON/parseable outputs, and adjusts filtered--parseableoutput to print each selected project directory before any dep records.Extends selector parsing so pnpm’s
./packages/**directory form is accepted as a path selector synonym (without reinterpreting name globs like@scope/**), and adds new bats coverage viatest/pnpm_monorepo_index.batsplus updates totest/PNPM_TEST_IMPORT.mdto track the ported pnpm monorepo filter tests.Reviewed by Cursor Bugbot for commit 10c6596. Bugbot is set up for automated code reviews on this repo. Configure here.