Skip to content

feat(cli): support git specs in aube add#483

Merged
jdx merged 3 commits intomainfrom
feat/cli-add-git-spec
May 3, 2026
Merged

feat(cli): support git specs in aube add#483
jdx merged 3 commits intomainfrom
feat/cli-add-git-spec

Conversation

@jdx
Copy link
Copy Markdown
Contributor

@jdx jdx commented May 2, 2026

Summary

  • Extends parse_pkg_spec in 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-negativeis-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. PR fix(lockfile): parse bare user/repo as github shorthand #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 to promote the update.ts:14/143/170/197 entry from "partially landed" to "landed".

Test plan

  • cargo build --workspace
  • 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
  • cargo clippy --all-targets -- -D warnings — no warnings
  • cargo fmt --check
  • mise run test:bats test/pnpm_update.bats — pre-existing 17/22 results unchanged (3 unrelated <pkg>@latest failures match main baseline)
  • mise run test:bats test/add.bats — all 25 tests pass
  • mise run test:bats test/update.bats, test/catalogs.bats — all pass
  • 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


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.

Reviewed by Cursor Bugbot for commit a56d92b. Bugbot is set up for automated code reviews on this repo. Configure here.

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented May 2, 2026

Greptile Summary

Extends parse_pkg_spec to detect git dependency specs (bare user/repo shorthands, github:/gitlab:/bitbucket: prefixes, git+ssh/git+https URLs, and alias@<git-spec> forms), routing them through a new non-packument branch that writes the verbatim spec into package.json for resolver dispatch. The new apply_git_spec_to_manifest function correctly mirrors the duplicate-section scrub of the workspace and registry paths, and the alias-vs-name derivation logic is properly guarded — repo_name_from_clone_url is only consulted when no alias is supplied. Three new network-gated bats tests restore the kevva/is-negative assertions for update.ts:14/170/197, and PNPM_TEST_IMPORT.md is updated to reflect the landed status.

Confidence Score: 5/5

Safe to merge — changes are well-scoped, correctly guard all edge cases, and are covered by both unit tests and network-gated integration tests.

No P0 or P1 findings. The alias-before-URL-derivation ordering is correct, the de-dupe scrub mirrors the workspace and registry paths exactly, and split_git_alias correctly handles protocol prefixes, scoped names, and trailing-slash URLs. All five new unit tests and three new bats tests pass per the test plan.

No files require special attention.

Important Files Changed

Filename Overview
crates/aube/src/commands/add.rs Adds git-spec parsing branch to parse_pkg_spec, split_git_alias helper, parse_git_pkg_spec, repo_name_from_clone_url, and apply_git_spec_to_manifest — all correctly mirror the workspace-spec pattern with proper alias handling and de-dupe scrub.
test/pnpm_update_slow.bats Adds three network-gated bats tests (update.ts:14/170/197) that use aube add with the new bare GitHub shorthand, and adds @pnpm.e2e/foo to the teardown restore list required by the update.ts:197 port.
test/PNPM_TEST_IMPORT.md Promotes update.ts:14/143/170/197 from "partially landed" to "landed" and splits the updateRewritesSpecifier item into a separate pending entry.

Reviews (5): Last reviewed commit: "fix(test): restore @pnpm.e2e/foo fixture..." | Re-trigger Greptile

Comment thread crates/aube/src/commands/add.rs Outdated
Comment thread crates/aube/src/commands/add.rs Outdated
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 2, 2026

Benchmark changes

Public ratios: warm installs vs Bun 7x -> 10x; warm installs vs pnpm 11x -> 12x.

Benchmark aube bun pnpm
Fresh install (warm cache) 332ms -> 226ms (-32%) 2242ms -> 2357ms (+5%) 3500ms -> 2656ms (-24%)
CI install (warm cache, GVS disabled) 930ms -> 1210ms (+30%) 1447ms -> 2290ms (+58%) 2475ms -> 2404ms (-3%)
CI install (cold cache, GVS disabled) 4364ms -> 4175ms (-4%) 4083ms -> 5012ms (+23%) 5380ms -> 5517ms (+3%)

a56d92b vs c910bd8 | aube/bun/pnpm | 3 scenarios | 3 runs | 500mbit/50ms | generated by Codex.

@jdx
Copy link
Copy Markdown
Contributor Author

jdx commented May 2, 2026

Addressed Greptile P1 / Cursor low-severity: parse_git_pkg_spec was calling repo_name_from_clone_url unconditionally, so a pathless URL with an alias (e.g. my-alias@git+https://example.com/) would hard-fail with "pass an alias" even though the alias was already given. Reordered so the URL derivation only fires when alias is None.

Added a unit test for the alias-with-pathless-URL case.

Validation: cargo test --bin aube parse_pkg_spec 20/20, clippy/fmt clean.

Written with Claude.

Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit e863be8. Configure here.

Comment thread test/pnpm_update_slow.bats
jdx added a commit that referenced this pull request May 2, 2026
The new "named update leaves shorthand alone" test calls
`add_dist_tag '@pnpm.e2e/foo'` which mutates
`test/registry/storage/@pnpm.e2e/foo/package.json` via jq, but the
teardown's `git checkout` list didn't include that file. Subsequent
runs would inherit the mutated dist-tag.

Addresses Cursor review on PR #483.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@jdx
Copy link
Copy Markdown
Contributor Author

jdx commented May 2, 2026

Added @pnpm.e2e/foo/package.json to the teardown checkout list. Written with Claude.

jdx added a commit that referenced this pull request May 2, 2026
`parse_git_pkg_spec` was calling `repo_name_from_clone_url` even when
the user passed an alias, so a pathless URL like
`my-alias@git+https://example.com/` would hard-fail with "pass an
alias" — even though one was already passed. Reorder so the URL
derivation only fires when alias is None.

Adds a unit test asserting the alias-with-pathless-URL form succeeds.

Addresses Greptile P1 + Cursor low-severity on PR #483.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
jdx added a commit that referenced this pull request May 2, 2026
The new "named update leaves shorthand alone" test calls
`add_dist_tag '@pnpm.e2e/foo'` which mutates
`test/registry/storage/@pnpm.e2e/foo/package.json` via jq, but the
teardown's `git checkout` list didn't include that file. Subsequent
runs would inherit the mutated dist-tag.

Addresses Cursor review on PR #483.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@jdx jdx force-pushed the feat/cli-add-git-spec branch from 277a541 to 6c6f787 Compare May 2, 2026 22:06
jdx and others added 3 commits May 2, 2026 17:41
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>
`parse_git_pkg_spec` was calling `repo_name_from_clone_url` even when
the user passed an alias, so a pathless URL like
`my-alias@git+https://example.com/` would hard-fail with "pass an
alias" — even though one was already passed. Reorder so the URL
derivation only fires when alias is None.

Adds a unit test asserting the alias-with-pathless-URL form succeeds.

Addresses Greptile P1 + Cursor low-severity on PR #483.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The new "named update leaves shorthand alone" test calls
`add_dist_tag '@pnpm.e2e/foo'` which mutates
`test/registry/storage/@pnpm.e2e/foo/package.json` via jq, but the
teardown's `git checkout` list didn't include that file. Subsequent
runs would inherit the mutated dist-tag.

Addresses Cursor review on PR #483.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@jdx jdx force-pushed the feat/cli-add-git-spec branch from 6c6f787 to a56d92b Compare May 2, 2026 22:43
@jdx jdx merged commit 5f05906 into main May 3, 2026
18 checks passed
@jdx jdx deleted the feat/cli-add-git-spec branch May 3, 2026 00:22
jdx added a commit that referenced this pull request May 3, 2026
Adds a non-packument branch in `parse_pkg_spec` for `file:` and
`link:` local-path specs (mirroring the workspace-spec fork). The
verbatim spec is written to `package.json` and the resolver's
existing local branch dispatches the install — `aube add file:./pkg`
no longer 404s on the registry packument fetch.

Manifest key is derived from the path basename when no alias is
given (`file:./packages/foo` -> `foo`, `file:./bundle.tgz` ->
`bundle`). Pass an alias when the upstream `package.json` `name`
differs: `aube add my-pkg@file:./packages/foo`.

Sibling to PR #483 (git specs). Closes the local-path-spec followup
that #483's review surfaced.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
jdx added a commit that referenced this pull request May 3, 2026
## Summary

- Adds a non-packument branch in
[parse_pkg_spec](crates/aube/src/commands/add.rs:175) for `file:` /
`link:` local-path specs (`file:./pkg`, `link:../sibling`,
`file:./bundle.tgz`). Sits alongside the workspace-spec fork; mirrors
the structural shape of #483 (git specs).
- Manifest-key derivation: alias when given (`my-alias@file:./pkg`),
otherwise the basename of the path (with `.tgz` / `.tar.gz` stripped).
Verbatim spec is written into `package.json` and the resolver's existing
local branch
([is_non_registry_specifier](crates/aube-resolver/src/local_source.rs:185))
dispatches the install on next pass.
- Skips packument fetch and catalog logic for local specs (catalogs are
for registry deps). `aube add file:./pkg` no longer 404s on the
registry.

Sibling to PR #483 (git specs). Closes the local-path-spec followup that
#483's review surfaced. The new branch is parallel to the git-spec
branch in `parse_pkg_spec` — when #483 lands the two branches sit
side-by-side without nesting.

## Test plan

- [x] `cargo build --workspace`
- [x] `cargo test --workspace` — 9 new unit tests in
`commands::add::tests` cover `file:` / `link:` relative + absolute,
tarball-basename derivation, alias forms, scoped/git non-collisions, and
the bare `file:` + alias edge case
- [x] `cargo clippy --all-targets -- -D warnings` — clean
- [x] `cargo fmt --check`
- [x] `mise run test:bats test/add.bats` — 28 tests pass (3 new offline
tests for `file:` / `link:` / aliased `file:`)
- [x] `mise run test:bats test/local_deps.bats` — regression check, 10
tests pass
- [x] `mise run test:bats test/pnpm_install_misc.bats` — regression
check, 30 tests pass

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Extends `aube add` parsing/routing to treat `file:`/`link:` (and
scoped/aliased variants) as non-registry deps, which could impact how
ambiguous specs are classified and when registry packument fetches are
skipped.
> 
> **Overview**
> `aube add` now supports `file:` and `link:` local-path dependencies by
routing them through the same *non-registry* flow as git specs: skip
packument fetch/catalog logic and write the verbatim spec into
`package.json` for the resolver to handle.
> 
> This introduces local-spec parsing with basename-based manifest key
derivation (including stripping `.tgz`/`.tar.gz`/`.tar`), supports alias
and `@scope/alias@<spec>` forms for both git and local specs, updates
the packument-fetch skip guards accordingly, and adds unit + bats
coverage for the new behaviors.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
aba32ba. 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>
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