Skip to content

feat(backend): skip remote discovery for exact versions in more backends - #11070

Merged
jdx merged 2 commits into
mainfrom
feat/resolve-exact-version-backends
Jul 17, 2026
Merged

jdx merged 2 commits into
mainfrom
feat/resolve-exact-version-backends

Conversation

@jdx

@jdx jdx commented Jul 16, 2026 •

Copy link
Copy Markdown
Owner

Summary

Extends the resolve_exact_version fast path introduced for cargo in #11013 to the npm, go, gem, pipx, and dotnet backends.

When a version request parses as full semver (versions::SemVer), resolution now skips fetching the remote version list entirely and defers authoritative validation to the underlying installer, which fails cleanly when the version doesn't exist upstream:

Backend Installer validation
npm npm/bun/pnpm/aube install pkg@version
go go install mod@vX.Y.Z (validates against the module proxy; v-prefixed requests are normalized to match listed versions)
gem gem install --version
pipx pipx install pkg==version / uv tool install
dotnet dotnet tool install --version

This mostly benefits flows the lockfile short-circuit doesn't cover: exact pins in mise.toml without a lockfile, first-time mise install tool@x.y.z, and mise x tool@x.y.z.

What still uses remote discovery

  • Fuzzy/prefix/channel requests (latest, 3, 3.1, ^1.2.3, next)
  • Non-semver version schemes, so prefix promotion keeps working where those schemes exist: RubyGems 4-part versions (5.0.0.1) and dotted prereleases (1.2.3.rc1), PEP 440 (1.2.3.post1, 1.2.3rc1, 1.2.3.4), legacy 4-part NuGet versions
  • Git-sourced pipx tools (pipx:owner/repo, pipx:git+...) — versions there are repo tags, mirroring the cargo git_url escape hatch

Behavior tradeoff (same as #11013)

An exact 3-part pin that does not exist upstream now fails at install time with the installer's error, instead of being silently promoted to a separator-suffixed variant (1.2.3 → 1.2.3.4 / 1.2.3-rc1) during resolution. Explicit exact pins also stay outside release-age filtering, per the existing comment in tool_version.rs.

Verification

  • 11 new unit tests mirroring the cargo ones (exact resolves, fuzzy/non-semver/git fall through) — all pass
  • Traced end-to-end with a debug build: mise install --dry-run npm:cowsay@1.6.0 resolves with zero remote calls (no npm view), while the fuzzy control npm:cowsay@1.6 still fetches the version list and resolves to 1.6.0

This PR was generated by an AI coding assistant.

🤖 Generated with Claude Code


Note

Medium Risk
Changes version resolution behavior for exact pins across five install backends; wrong semver classification could skip needed remote discovery or change failure mode from resolution promotion to install-time errors.

Overview
Extends the resolve_exact_version fast path (from cargo) to npm, go, gem, pipx, and dotnet. When a pin parses as full semver via versions::SemVer, mise skips remote version-list fetches and treats the string as exact; missing versions surface at install time from the package manager instead of during resolution.

Backend-specific rules: go strips a leading v before semver checks; pipx only applies the fast path for PyPI tools (git-sourced tools still use remote discovery); gem, dotnet, and pipx leave non-semver schemes (RubyGems 4-part/dotted prereleases, NuGet 4-part, PEP 440) on the remote-discovery path so prefix promotion keeps working.

Tradeoff: exact semver pins that do not exist upstream no longer get silently promoted to separator-suffixed variants during resolution—they fail with the installer’s error instead.

Adds unit tests on each backend mirroring cargo (exact semver resolves, fuzzy/non-semver/git fall through).

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

Summary by CodeRabbit

  • New Features

    • Improved version resolution for .NET, RubyGems, Go, npm, and pipx packages.
    • Exact semantic versions, including supported prerelease versions and Go’s v prefix, can now resolve directly.
    • Non-semantic, partial, range-based, legacy, and Git-based version references continue through remote discovery for more accurate results.
  • Tests

    • Added coverage for exact, fuzzy, legacy, prerelease, and unsupported version formats across supported package ecosystems.

Extend the resolve_exact_version fast path introduced for cargo in #11013
to the npm, go, gem, pipx, and dotnet backends. When a request parses as
full semver, resolution skips fetching the remote version list entirely
and defers authoritative validation to the underlying installer
(npm/bun/pnpm/aube install pkg@v, go install mod@vX.Y.Z,
gem install --version, pipx install pkg==v / uv tool install,
dotnet tool install --version), which all fail when the version does not
exist upstream.

Non-semver version schemes (RubyGems 4-part versions, PEP 440 post/rc
releases, legacy 4-part NuGet versions) and git-sourced pipx tools still
fall through to normal remote discovery, so prefix resolution like
1.2.3 -> 1.2.3.4 keeps working where those schemes exist.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Entire-Checkpoint: d3b92f548c1c
@coderabbitai

coderabbitai Bot commented Jul 16, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Central YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: e294f17b-d961-4378-9935-60da5b6a8445

📥 Commits

Reviewing files that changed from the base of the PR and between 33440d6 and c6fd9d2.

📒 Files selected for processing (5)
  • src/backend/dotnet.rs
  • src/backend/gem.rs
  • src/backend/go.rs
  • src/backend/npm.rs
  • src/backend/pipx.rs

📝 Walkthrough

Walkthrough

Five package backends now resolve exact SemVer inputs locally, while non-SemVer, fuzzy, range, legacy, and Git-based inputs return None for remote discovery. Async Tokio tests cover accepted and rejected version formats.

Changes

Exact version resolution

Layer / File(s) Summary
Standard backend SemVer resolution
src/backend/dotnet.rs, src/backend/gem.rs, src/backend/go.rs, src/backend/npm.rs
Dotnet, Gem, Go, and NPM validate exact versions as SemVer, with Go normalizing a leading v; tests cover valid, fuzzy, range, and legacy inputs.
PIPX target-specific resolution
src/backend/pipx.rs
PIPX resolves SemVer versions locally for PyPI targets and returns None for non-SemVer values and Git-based specifications, with corresponding async tests.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Suggested reviewers: risu729

Poem

A rabbit hops through versions bright,
SemVer stars resolve just right.
Fuzzy tags take the distant trail,
Git winds tug a remote sail.
Tests thump softly: green and neat!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: expanding exact-version fast paths to more backends and skipping remote discovery.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Jul 16, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR extends the resolve_exact_version fast path (previously only on cargo) to the npm, go, gem, pipx, and dotnet backends. When a version string parses as full semver, mise now skips fetching the remote version list entirely and defers authoritative validation to the underlying installer; non-semver, fuzzy, and git-sourced version requests continue through normal remote discovery.

  • Each backend correctly gates on versions::SemVer::new(version) to catch only strict 3-part versions; backend-specific non-semver schemes (NuGet 4-part, RubyGems dotted prerelease, PEP 440 extras) all fall through as intended, verified by the new unit tests.
  • The go backend strips a leading v before the semver check and returns the bare version, matching how listed versions are stored; install_version_ already re-adds the v prefix before invoking go install, so there is no mismatch.
  • The pipx backend deliberately calls get_registry_url() in the fast path to surface misconfigured index URLs at resolve time, consistent with what remote discovery does.

Confidence Score: 5/5

Safe to merge — the change is a narrowly-scoped fast path that only activates for full three-part semver strings; all other version patterns (fuzzy, prerelease scheme variants, git-sourced) continue through the existing remote-discovery code path.

Each backend's semver gate is correct and independently unit-tested. The go v-prefix normalization is consistent with how install_version_ later re-adds the prefix. The pipx git-source escape hatch is well-covered by tests. No correctness gap was found across all five backends.

No files require special attention; all five backends follow the same pattern and the unit tests are comprehensive.

Important Files Changed

Filename Overview
src/backend/dotnet.rs Adds resolve_exact_version fast path: full semver bypasses remote discovery; 4-part NuGet versions fall through correctly. Tests cover exact, fuzzy, and legacy formats.
src/backend/gem.rs Adds resolve_exact_version fast path: 4-part (5.0.0.1) and dotted-prerelease (1.2.3.rc1) RubyGems versions correctly fall through; strict 3-part semver is treated as exact.
src/backend/go.rs Adds resolve_exact_version fast path with v-prefix stripping; returned version without v matches how listed versions are stored and install_version_ re-adds the prefix before invoking go install.
src/backend/npm.rs Adds resolve_exact_version fast path: strict semver (including prerelease like 1.1.0-beta.1) is treated as exact; dist-tags and range expressions fall through to remote discovery.
src/backend/pipx.rs Adds resolve_exact_version fast path: git-sourced tools always fall through; PyPI tools validate registry URL config eagerly (intentional parity with remote-discovery behaviour) then skip fetch for strict semver versions.

Reviews (2): Last reviewed commit: "fix(backend): validate pipx registry url..." | Re-trigger Greptile

@github-actions

github-actions Bot commented Jul 16, 2026 •

Copy link
Copy Markdown
Contributor

Hyperfine Performance

mise x -- echo

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.7.7 x -- echo 20.9 ± 1.1 18.6 26.5 1.01 ± 0.10
mise x -- echo 20.6 ± 1.8 18.3 46.9 1.00

mise env

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.7.7 env 20.5 ± 1.1 18.4 25.0 1.10 ± 0.08
mise env 18.7 ± 0.9 17.1 23.6 1.00

mise hook-env

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.7.7 hook-env 21.0 ± 1.0 19.0 24.7 1.07 ± 0.07
mise hook-env 19.6 ± 1.0 17.8 23.8 1.00

mise ls

Command Mean [ms] Min [ms] Max [ms] Relative
mise-2026.7.7 ls 18.5 ± 1.0 16.7 23.1 1.06 ± 0.08
mise ls 17.5 ± 1.0 15.4 22.0 1.00

xtasks/test/perf

Command mise-2026.7.7 mise Variance
install (cached) 168ms 171ms -1%
ls (cached) 64ms 59ms +8%
bin-paths (cached) 63ms 61ms +3%
task-ls (cached) 128ms 128ms +0%

The exact-version fast path skipped resolve-time registry URL validation,
so a malformed pipx.registry_url only surfaced as an installer network
error instead of the intended configuration error
(test_pipx_custom_registry).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

An error occurred during the review process. Please try again later.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@jdx
jdx merged commit cdc5dd3 into main Jul 17, 2026
39 of 50 checks passed
@jdx
jdx deleted the feat/resolve-exact-version-backends branch July 17, 2026 03:35
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