fix(lockfile): parse bare user/repo as github shorthand#472
Conversation
Greptile SummaryThis PR adds bare Confidence Score: 5/5Safe to merge — all previously flagged P1s are addressed and no new issues found. Both loops in No files require special attention. Important Files Changed
Reviews (3): Last reviewed commit: "feat(cli): preserve git-spec deps throug..." | Re-trigger Greptile |
`parse_git_spec` now recognizes the bare `user/repo` form npm and pnpm auto-expand to `github:user/repo`. Placed last in the parser so explicit URL/scheme branches (`github:`, `gitlab:`, `bitbucket:`, scp, full URLs) shadow it. Refuses scoped npm names (`@scope/pkg`), file paths, and any form with extra slashes or non-`[A-Za-z0-9_.-]` characters in either segment, so it doesn't claim things that other branches already handled. End-to-end install of `kevva/is-negative` still needs `aube add` arg parsing and a hosted-git fixture for the bats suite — see `test/PNPM_TEST_IMPORT.md` for what remains. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
b9ac1ea to
9e2323e
Compare
|
Addressed the P1 ( Also expanded the PR scope while addressing the feedback. The parser change alone exposed a footgun: with bare End-to-end coverage lives in a new test/pnpm_update_slow.bats, gated behind Rebased onto current main (was on a stale base since #471 merged in the interim). Written with Claude. |
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 9e2323e. Configure here.
`aube update --latest` has two manifest-rewrite paths in sequence: the resolver_manifest clone (rewrites every direct dep to `"latest"` to drive re-resolution) and the package.json persist loop (writes the resolved range back). With bare `user/repo` GitHub shorthand now recognized by `parse_git_spec`, a manifest entry like `"is-negative": "kevva/is-negative"` would survive install but both rewrite paths would mishandle it: the resolver_manifest clone would route the resolver at the registry, and the package.json persist loop would silently swap the spec for a registry semver pin. Skip any specifier `parse_git_spec` matches in both loops, before the rewrite. Workspace specs already had this guard; git specs now do too. Adds `test/pnpm_update_slow.bats` with the network-test convention (`AUBE_NETWORK_TESTS=1` gate, mirrored on `_require_registry`) and one regression-guard port restoring `kevva/is-negative` alongside the registry deps from update.ts:143. Documents the convention in test/PNPM_TEST_IMPORT.md and updates the triage row. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
9e2323e to
1f7bbf3
Compare
|
Addressed Cursor Bugbot's high-severity finding: Added the same Verified: cargo build/test/clippy/fmt clean, Written with Claude. |
Benchmark changesPublic ratios: warm installs vs Bun 4x -> 8x; warm installs vs pnpm 9x -> 13x.
1f7bbf3 vs 7a231d6 | aube/bun/pnpm | 3 scenarios | 3 runs | 500mbit/50ms | generated by Codex. |
…ls (#476) ## Summary - Repeat `aube install` runs short-circuit through the warm path, which returns before the unreviewed-builds warning fires. Users were silently losing the nudge to run `aube approve-builds` between installs — exactly the failure mode `strictDepBuilds` exists to backstop. - Persist the unreviewed-build spec keys in `.aube-state` (new `unreviewed_builds: Vec<String>` on both `InstallState` and `FreshnessState`) and re-emit the same `tracing::warn!` line from both warm-path branches (`missing_lockfile_restore_eligible` and `warm_path_eligible`) when the set is non-empty. The allowBuilds review-placeholder write stays on the full pipeline, so warm installs nudge without re-seeding. - Ports `pnpm/test/install/lifecycleScripts.ts:245` ('warning is shown when an install with --no-frozen-lockfile reuses an existing node_modules with ignored build scripts'). Wording substituted to aube's canonical `ignored build scripts for N package(s)` per the existing divergence note. Background: triaged as `support` in #471 (`test/PNPM_TEST_IMPORT.md`). Companion to #472, which landed the bare-shorthand parser fix. ## Test plan - [x] `cargo build` - [x] `cargo test --workspace` — 362+239+169+... all green; the two new state round-trip tests (`unreviewed_builds_roundtrip_persists_into_fresh_state`, `unreviewed_builds_default_when_field_missing_in_state`) confirm legacy state files load via the serde default and the new field round-trips through the FreshnessState sidecar. - [x] `cargo clippy --all-targets -- -D warnings` - [x] `cargo fmt --check` - [x] `./test/bats/bin/bats test/lifecycle_scripts.bats` — 34/34 ok including the new `aube install re-emits ignored-build-scripts warning on repeat install` - [x] `./test/bats/bin/bats test/approve_builds.bats` — 10/10 ok (regression check on the existing warning emission path) 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Touches install warm-path short-circuit logic and the persisted `.aube-state` schema; regressions could cause incorrect warning behavior or state incompatibilities on upgrade, though the change is additive and guarded with serde defaults. > > **Overview** > Repeat `aube install` runs that short-circuit via the warm path (and the missing-lockfile-restore fast path) now **re-emit the ignored build scripts warning** by reading a persisted `unreviewed_builds` list from `.aube-state`. > > The install pipeline now computes the unreviewed-build set once, stores it in `InstallState`/`FreshnessState`, and centralizes warning formatting in `emit_unreviewed_builds_warning`; new unit tests cover round-tripping/defaulting of the new state field, and a new Bats test asserts the warning appears on a repeat no-op install. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit daf7bf0. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds three network-gated bats tests in pnpm_update_slow.bats mirroring pnpm/test/update.ts:143/170/197 with the dropped `kevva/is-negative` assertions restored end-to-end. Each test exercises the new `aube add <bare-shorthand>` path before the registry deps, so the github shorthand lands in package.json from the CLI rather than a manifest-declared dep + `aube install`. Updates PNPM_TEST_IMPORT.md to mark the github-shorthand resolution work done — parser branch (PR #472) + update --latest skip (PR #472) + CLI add support land the full end-to-end story for pnpm's update.ts:14 /143/170/197. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Extends parse_pkg_spec in aube/src/commands/add.rs to detect git specs via aube_lockfile::parse_git_spec and route them through a new non-packument branch: the verbatim spec is written to package.json and the resolver dispatches the git path on the next install. Recognized forms include bare GitHub shorthand (kevva/is-negative), github:/gitlab:/bitbucket: prefixes, and the full git+ssh / git+https URL family. The alias form (my-alias@kevva/is-negative) lands the user's alias as the manifest key. Manifest key derivation: when no alias is given, the repo segment of the clone URL is used (kevva/is-negative -> is-negative). Pass an alias when the package's package.json `name` differs from the repo segment. Restores the dropped kevva/is-negative assertions in the network-gated ports of update.ts:14, 143, 170, 197 in test/pnpm_update_slow.bats. PR #472 landed the parser branch and the update --latest skip-non-registry guard; this is the CLI-side counterpart so the four assertions can be exercised end-to-end. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Extends parse_pkg_spec in aube/src/commands/add.rs to detect git specs via aube_lockfile::parse_git_spec and route them through a new non-packument branch: the verbatim spec is written to package.json and the resolver dispatches the git path on the next install. Recognized forms include bare GitHub shorthand (kevva/is-negative), github:/gitlab:/bitbucket: prefixes, and the full git+ssh / git+https URL family. The alias form (my-alias@kevva/is-negative) lands the user's alias as the manifest key. Manifest key derivation: when no alias is given, the repo segment of the clone URL is used (kevva/is-negative -> is-negative). Pass an alias when the package's package.json `name` differs from the repo segment. Restores the dropped kevva/is-negative assertions in the network-gated ports of update.ts:14, 143, 170, 197 in test/pnpm_update_slow.bats. PR #472 landed the parser branch and the update --latest skip-non-registry guard; this is the CLI-side counterpart so the four assertions can be exercised end-to-end. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
## Summary
Ports three of the five test-only pnpm tests called out in the triage
brief, retriages the other two with empirical evidence:
| pnpm test | item | landed | file |
|---|---|---|---|
| `misc.ts:567` (git URL with hash containing slash) | 1 | yes |
`test/pnpm_install_misc_slow.bats` (network-gated, new file) |
| `hooks.ts:68` (readPackage returning undefined fails) | 2 | no —
divergence | already-skipped at `pnpm_install_hooks.bats:310`; triage
retriaged to won't-support |
| `hooks.ts:580` (readPackage during remove in workspace) | 3 | yes |
`test/pnpm_install_hooks.bats` |
| `lifecycleScripts.ts:108` (rollback-on-build-failure) | 4 | yes |
`test/lifecycle_scripts.bats` + new
`@pnpm.e2e/aube-test-failing-install` fixture |
| `lifecycleScripts.ts:179, 200` (verify-deps + preinstall sub-aube) | 5
| no — real bug | retriaged to support; needs aube fix before port |
### Items not ported (retriaged with evidence)
**Item 2 (`hooks.ts:68`)**: triage said aube errors with `readPackage
response missing pkg`. Empirically, the IPC shim at
`crates/aube/src/pnpmfile.rs:629` falls back to the original pkg via `if
(out && typeof out === 'object') result = out;` and writes back `{ id,
pkg: <original> }`. The Rust side at `pnpmfile.rs:809` sees `pkg`
present and continues with the original manifest — install succeeds
rather than fails. The existing skipped test at
`pnpm_install_hooks.bats:310` (added in a previous PR) already documents
this divergence correctly. Triage doc updated to move this to Tier 3
(won't-support / divergence).
**Item 5 (`lifecycleScripts.ts:179, 200`)**: triage said aube has the
parent-set recursion guard, but the only "parent-set" mechanism at
`run.rs:536` preserves `INIT_CWD`, not lifecycle context. Empirically:
- `verifyDepsBeforeRun=error` + `preinstall: aube run sayHello` → inner
`aube run` exits with `dependencies need install before run: install
state not found` (state isn't written until linking finishes).
- `verifyDepsBeforeRun=install` → inner `aube run` triggers
`ensure_installed` → `install::run`, which deadlocks on the project lock
the outer install holds (`Waiting for another aube process to finish in
this project...`, observed via 60s timeout).
Per the brief: "If porting surfaces a real recursion bug, STOP — don't
fight the bug." Aube fix needed: skip `ensure_installed` when
`npm_lifecycle_event` is set in the env (matches npm/pnpm's "no
verify-deps inside lifecycle scripts" contract). Tracked in the
retriaged entry in the triage doc.
### New offline fixture
`test/registry/storage/@pnpm.e2e/aube-test-failing-install/` (1.0.0,
`install: exit 1`) — minimal hand-built tarball + packument JSON,
mirrors the structure of the existing `@pnpm.e2e/install-script-example`
fixture. Used by the rollback test only.
### References
- Triage doc: `test/PNPM_TEST_IMPORT.md` (see PR #471 for triage
context).
- Network-test convention: PR #472 / `test/pnpm_update_slow.bats`.
## Test plan
- [x] `cargo build --workspace`
- [x] `cargo clippy --all-targets -- -D warnings` (zero warnings)
- [x] `cargo fmt --check` (clean — no Rust source changes)
- [x] `mise run test:bats test/pnpm_install_hooks.bats` — 21 passing (3
documented skips), including the new readPackage-during-remove test
- [x] `mise run test:bats test/lifecycle_scripts.bats` — 34 passing,
including the new rollback test
- [x] `AUBE_NETWORK_TESTS=1 ./test/bats/bin/bats
test/pnpm_install_misc_slow.bats` — passes (network required)
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Low Risk**
> Test-only changes add new bats coverage (including a network-gated
case) plus an offline fixture; no production Rust code paths are
modified, so risk is limited to CI/test stability and reliance on
external GitHub availability for the slow test.
>
> **Overview**
> Adds three new pnpm parity ports to the bats suite: a network-gated
`misc.ts:567` install-from-git regression test (new
`pnpm_install_misc_slow.bats`), a workspace `aube remove` path hook
regression test in `pnpm_install_hooks.bats`, and a lifecycle
rollback/retry contract test in `lifecycle_scripts.bats` backed by a new
always-failing offline fixture `@pnpm.e2e/aube-test-failing-install`.
>
> Updates `PNPM_TEST_IMPORT.md` to mark the newly-ported items as done
and to retriage two previously “test-only” gaps: `readPackage` returning
`undefined` is now documented as an intentional aube divergence, and the
`verify-deps-before-run` + lifecycle-subcommand case is reclassified as
a real aube bug requiring a fix before porting.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
6072789. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
## Summary - Extends `parse_pkg_spec` in [crates/aube/src/commands/add.rs](crates/aube/src/commands/add.rs) to detect git specs via `aube_lockfile::parse_git_spec` and route them through a new non-packument branch — verbatim spec written to `package.json`, resolver dispatches the git path on next install. Recognized forms: bare GitHub shorthand (`kevva/is-negative`), `github:`/`gitlab:`/`bitbucket:` prefixes, full `git+ssh` / `git+https` URLs, and the alias form (`my-alias@kevva/is-negative`). - Manifest-key derivation when no alias given: repo segment of the clone URL (e.g. `kevva/is-negative` → `is-negative`). 90% solution; pass an alias when the upstream `package.json` `name` differs from the repo segment. - Restores the dropped `kevva/is-negative` assertions in the network-gated ports of `update.ts:14, 143, 170, 197` in [test/pnpm_update_slow.bats](test/pnpm_update_slow.bats). PR #472 landed the parser branch and the `update --latest` skip-non-registry guard; this is the CLI-side counterpart so the four assertions can be exercised end-to-end. - Updates [test/PNPM_TEST_IMPORT.md](test/PNPM_TEST_IMPORT.md) to promote the update.ts:14/143/170/197 entry from "partially landed" to "landed". ## Test plan - [x] `cargo build --workspace` - [x] `cargo test --workspace` — 365+ workspace tests pass; 5 new unit tests cover bare GitHub shorthand, `github:` protocol, git URL with slash-bearing fragment, alias form, and scoped-name non-git negative case - [x] `cargo clippy --all-targets -- -D warnings` — no warnings - [x] `cargo fmt --check` - [x] `mise run test:bats test/pnpm_update.bats` — pre-existing 17/22 results unchanged (3 unrelated `<pkg>@latest` failures match `main` baseline) - [x] `mise run test:bats test/add.bats` — all 25 tests pass - [x] `mise run test:bats test/update.bats`, `test/catalogs.bats` — all pass - [x] `mise run test:bats test/pnpm_update_slow.bats` — 4 tests properly gated, skip without `AUBE_NETWORK_TESTS=1` - [ ] CI exercises the slow file with `AUBE_NETWORK_TESTS=1` 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes `aube add`’s dependency parsing and manifest-writing flow to bypass registry resolution for git specs; mistakes here could misclassify specs or skip packument fetching, affecting added dependencies. > > **Overview** > `aube add` now detects git dependency specifiers (bare `user/repo`, `github:`/`gitlab:`/`bitbucket:` prefixes, and full `git+...` URLs, including `alias@<git-spec>`), and routes them through a non-registry path. > > For git specs it **skips packument fetch + catalog logic**, derives a default manifest key from the repo URL when no alias is provided, and writes the user’s verbatim specifier into `package.json` so the resolver handles git resolution on install. > > Adds unit tests for git spec parsing/edge cases and expands the network-gated `pnpm_update_slow.bats` ports to cover `aube add kevva/is-negative` end-to-end; updates the pnpm test import tracking doc accordingly. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit a56d92b. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Summary
user/repoGitHub-shorthand recognition toparse_git_spec— npm/pnpm parity. Placed last after explicit URL/scheme branches so existing forms (github:user/repo,git+https://, scp, full URLs) shadow it.update.rsthat skips git-spec deps in theupdate --latestmanifest rewrite. Without this guard the parser change creates a footgun:"is-negative": "kevva/is-negative"would be silently rewritten to"^<some-version>"(a registry pin) and break install._require_networkskips unlessAUBE_NETWORK_TESTS=1is set, paired with a separatetest/*_slow.batsfile. First use: test/pnpm_update_slow.bats — one regression-guard port covering install + update --latest end-to-end withkevva/is-negativealongside the registry deps from update.ts:143.aube add <bare-shorthand>support, which is its own feature and is tracked as a follow-up intest/PNPM_TEST_IMPORT.md.Notes for the reviewer
is_bare_github_shorthandnow rejects owner starting with.so single-component relative paths (./repo,../repo) are correctly rejected. Test extended to cover both single- and multi-component forms.git checkoutteardown pattern aspnpm_update.batsto restore mutateddist-tagsstorage.Test plan
cargo build --workspace— greencargo test -p aube-lockfile— 239 lib tests pass (+8 new for parser branch)cargo clippy --all-targets -- -D warnings— no warningscargo fmt --check— cleanmise run test:bats test/pnpm_update.bats— 22/22 pass (offline, unchanged)AUBE_NETWORK_TESTS=1 mise run test:bats test/pnpm_update_slow.bats— not run locally (needs Verdaccio + github)Note
Medium Risk
Expands git-spec parsing and changes
update --latestmanifest-rewrite behavior; mistakes could misclassify paths/URLs as git or skip/incorrectly rewrite dependency specifiers, affecting installs.Overview
Git spec parsing now recognizes bare
user/repoas GitHub shorthand by expanding it tohttps://github.com/<user>/<repo>.git, with new validation to avoid colliding with relative paths, scoped package names, and other non-git forms.aube update --latestnow skips git-based dependencies when rewritingpackage.json, preventing git specs (including the new bare shorthand) from being converted into registrylatest/semver pins.Adds a network-gated bats regression test (
test/pnpm_update_slow.bats) and updates the pnpm test-porting doc to formalize_require_network/AUBE_NETWORK_TESTS=1for upstream-dependent tests.Reviewed by Cursor Bugbot for commit 1f7bbf3. Bugbot is set up for automated code reviews on this repo. Configure here.