Skip to content

fix(backend): use runtime paths for backend bin dirs#9606

Merged
jdx merged 8 commits into
jdx:mainfrom
risu729:fix-runtime-bin-paths
May 11, 2026
Merged

fix(backend): use runtime paths for backend bin dirs#9606
jdx merged 8 commits into
jdx:mainfrom
risu729:fix-runtime-bin-paths

Conversation

@risu729

@risu729 risu729 commented May 5, 2026

Copy link
Copy Markdown
Contributor

Summary

  • map backend-discovered bin paths from concrete install dirs onto ToolVersion::runtime_path()
  • align aqua, GitHub/GitLab/Forgejo, HTTP, S3, UBI, vfox, conda, and Windows npm bin-paths with runtime symlink labels for fuzzy versions
  • centralize the .mise-bins directory name behind MISE_BINS_DIR
  • add regression coverage for GitHub, HTTP, and aqua runtime-path bin-paths

Why this matters

mise keeps a concrete install dir for the resolved version and, for fuzzy requests, a runtime path for the requested label. For example, latest might resolve to 1.0.0, and 1.46 might resolve to 1.46.0. The runtime path is the stable symlink users expect on PATH.

Before this PR, several backend bin-paths implementations could report bins from the concrete install path instead of the runtime path:

  • GitHub alias example: tiny = { version = "latest", bin_path = "hello-world-1.0.0/bin" } resolved to 1.0.0, but mise bin-paths tiny used the concrete .../installs/tiny/1.0.0/.../bin path instead of .../installs/tiny/latest/.../bin.
  • HTTP example: http:hello-upgrade-latest resolved latest to 2.0.0, but bin-paths could expose the concrete resolved install/cache path rather than .../installs/http-hello-upgrade-latest/latest/.../bin.
  • Aqua prefix example: aqua:casey/just with version 1.46 resolves to 1.46.0; with symlink_bins = true, bin-paths should use .../installs/aqua-casey-just/1.46/.mise-bins, not the concrete 1.46.0 directory.

runtime_path_for_install_path is needed for backend-discovered absolute paths: it strips the concrete install prefix and reattaches the same relative subpath under tv.runtime_path(). Explicit relative bin_path values can join runtime_path() directly; the helper covers paths found by scanning extracted archives while leaving unrelated paths unchanged.

Tests

  • cargo fmt --all -- --check
  • git diff --check
  • cargo test test_runtime_path_for_install_path_remaps_install_subpath
  • mise run test:e2e e2e/backend/test_github_alias_versions e2e/backend/test_http_upgrade e2e/backend/test_aqua_symlink_bins
  • after AI-review follow-up: mise run test:e2e e2e/backend/test_http_upgrade e2e/backend/test_aqua_symlink_bins (the preceding rerun passed test_github_alias_versions, then hit a transient test_http_upgrade server-port setup race before assertions)
  • after const/re-review follow-up: cargo fmt --all -- --check, git diff --check, cargo test test_runtime_path_for_install_path_remaps_install_subpath, mise run test:e2e e2e/backend/test_github_alias_versions e2e/backend/test_http_upgrade e2e/backend/test_aqua_symlink_bins

Project item: https://github.com/users/risu729/projects/3/views/1?pane=issue&itemId=182730541

This PR was generated by an AI coding assistant.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a mechanism to remap tool installation paths to runtime paths, ensuring that commands like mise bin-paths return paths relative to symlinks like 'latest' rather than physical version directories. It adds a runtime_path_for_install_path helper and updates the Aqua, GitHub, and HTTP backends, supported by new E2E tests. Feedback recommends simplifying the helper function by removing an unnecessary check and directly using tv.runtime_path() in backend implementations where the subpath is already known, rather than relying on the remapping helper.

Comment thread src/backend/mod.rs
Comment thread src/backend/github.rs Outdated
Comment thread src/backend/http.rs Outdated
Comment thread src/backend/http.rs Outdated
Comment thread src/backend/http.rs Outdated
@greptile-apps

greptile-apps Bot commented May 5, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes several backends (aqua, github/gitlab/forgejo, http, s3, ubi, vfox, conda, Windows npm) that could expose the concrete resolved-version install path instead of the fuzzy-label runtime symlink path when bin-paths or PATH entries are queried for tools installed with labels like latest or 1.46.

  • Centralises the .mise-bins directory name behind a MISE_BINS_DIR constant and introduces a runtime_path_for_install_path helper that strips the concrete install prefix from a backend-discovered path and reattaches the same relative subpath under tv.runtime_path(), falling back unchanged for paths outside the install dir.
  • Updates every affected backend's list_bin_paths to join explicit bin_path values and discovered archive subpaths onto tv.runtime_path() rather than tv.install_path(), and replaces the rebuild call in rebuild_shims_and_runtime_symlinks with rebuild_for_toolset so that project-local backends not in the global backend::list() also have their symlinks refreshed.
  • Adds a unit test covering both the remap and the no-symlink fallback paths, plus e2e regression tests for the GitHub alias, HTTP fuzzy-latest, and aqua symlink-bins scenarios.

Confidence Score: 5/5

Safe to merge — the fallback in runtime_path_for_install_path (return path unchanged when no runtime symlink exists) prevents any regression for exact-version pinned tools.

The helper is straightforward and both code paths are covered by new unit tests. rebuild_for_toolset is a strict superset of the previous rebuild call, so no previously-rebuilt symlinks are skipped. Each backend change follows the same pattern uniformly, and e2e tests lock in the expected runtime-path shape.

No files require special attention.

Important Files Changed

Filename Overview
src/backend/mod.rs Adds MISE_BINS_DIR constant, the runtime_path_for_install_path helper, and two unit tests covering the remap and the no-symlink fallback; helper logic is correct.
src/runtime_symlinks.rs Adds rebuild_for_toolset which is a strict superset of rebuild — starts from the full backend::list() then includes any toolset-only backends; safe change.
src/backend/github.rs Applies runtime_path_for_install_path to discovered bin paths and uses tv.runtime_path() for the .mise-bins fast path; MISE_BINS_DIR constant adoption is consistent.
src/backend/http.rs Explicit bin_path and bin/ checks now join onto tv.runtime_path() directly; subdirectory scan paths are remapped via runtime_path_for_install_path.
src/backend/aqua.rs Switches .mise-bins check to use MISE_BINS_DIR constant and uses runtime_path for archive-scanned paths; create_symlink_bin_dir constant adoption is correct.
src/backend/conda.rs Both the .mise-bins fast path and the Windows/Unix fallback bin paths are remapped via runtime_path_for_install_path; refactoring to avoid early returns is clean.
src/backend/s3.rs All three bin-path discovery paths (explicit, bin/, subdirectory scan) remapped via runtime_path_for_install_path; empty-path fallback switches to tv.runtime_path().
src/backend/ubi.rs Relative bin_path and bin/ cases remapped via runtime_path_for_install_path; extract_all and empty fallbacks switch to tv.runtime_path().
src/backend/vfox.rs PATH entries from the vfox plugin are remapped via runtime_path_for_install_path; fallback uses tv.runtime_path().
src/backend/npm.rs Windows-only list_bin_paths applies runtime_path_for_install_path to each discovered path; #[cfg(windows)] import guard is correct.
src/config/mod.rs Switches rebuild call to rebuild_for_toolset which is a strict superset, ensuring project-local backends also get their symlinks rebuilt.
e2e/backend/test_aqua_symlink_bins Adds a fuzzy-version (1.46) test block that asserts bin-paths and which resolve through the runtime symlink rather than the concrete 1.46.0 directory.
e2e/backend/test_github_alias_versions Adds assertions for both the runtime-symlink (unlocked) and the locked concrete-path bin-paths results for the tiny alias tool.
e2e/backend/test_http_upgrade Adds a fuzzy latest HTTP tool and asserts that bin-paths uses the latest runtime symlink path, not the concrete resolved cache path.

Reviews (15): Last reviewed commit: "fix(backend): respect locked runtime pat..." | Re-trigger Greptile

@risu729

risu729 commented May 5, 2026

Copy link
Copy Markdown
Contributor Author

CI completed. The current failures look unrelated to this PR's runtime bin-path changes:

  • e2e-0: shell/test_xonsh failed while installing aqua:astral-sh/uv@latest because GitHub artifact attestation verification failed (expected 'astral-sh/uv/.github/workflows/release.yml', found certificate: None, provenance: None).
  • e2e-3: cli/test_activate_multiple_xonsh failed with the same uv attestation verification error; sync/test_sync_python_uv is also in the failing shard.
  • e2e-4: cli/test_deactivate_xonsh failed with the same uv attestation verification error.
  • benchmark: failed because mise x -- echo measured 18% slower than the mise-2026.5.0 baseline. The other benchmarked commands were within threshold, and this command does not exercise the aqua/github/http runtime bin-path mapping changed here.
  • test-ci: aggregate failure from the failed jobs above.

The relevant build/lint/unit checks passed, as did the other Linux e2e shards and Windows e2e. I am leaving these CI failures as unrelated.

This comment was generated by an AI coding assistant.

@risu729

This comment was marked as outdated.

@risu729

This comment was marked as outdated.

@risu729

This comment was marked as outdated.

@risu729

This comment was marked as outdated.

@risu729 risu729 force-pushed the fix-runtime-bin-paths branch from 668bd46 to cde081a Compare May 7, 2026 02:21
Comment thread src/backend/mod.rs Outdated
@risu729 risu729 force-pushed the fix-runtime-bin-paths branch from cde081a to 4467751 Compare May 7, 2026 02:32
@risu729 risu729 marked this pull request as ready for review May 7, 2026 09:53
@risu729 risu729 marked this pull request as draft May 7, 2026 09:54
@risu729 risu729 marked this pull request as ready for review May 8, 2026 14:40
@risu729 risu729 force-pushed the fix-runtime-bin-paths branch from 2f02fcb to 736a937 Compare May 11, 2026 16:48
@risu729 risu729 force-pushed the fix-runtime-bin-paths branch from 736a937 to 4158542 Compare May 11, 2026 16:49
@jdx jdx merged commit 291693f into jdx:main May 11, 2026
33 checks passed
@risu729 risu729 deleted the fix-runtime-bin-paths branch May 11, 2026 17:49
mise-en-dev added a commit that referenced this pull request May 13, 2026
### 🐛 Bug Fixes

- **(backend)** use runtime paths for backend bin dirs by @risu729 in
[#9606](#9606)
- **(ci)** preserve vendor/aqua-registry/ in PPA publish workflow by
@jdx in [#9782](#9782)
- **(ci)** set UTF-8 locale in e2e Docker image by @jdx in
[#9820](#9820)
- **(ci)** pass UTF-8 locale through to e2e tests by @jdx in
[#9823](#9823)
- **(conda)** dedup repodata by archive identifier instead of URL by
@jdx in [#9831](#9831)
- **(github)** use default shell for credential command by @risu729 in
[#9664](#9664)
- **(settings)** distinguish unset known settings from unknown ones by
@jdx in [#9818](#9818)
- **(upgrade)** remove completed progress jobs to prevent duplicate
output by @jdx in [#9779](#9779)
- **(vfox)** resolve GitHub token lazily inside Lua plugins by @jdx in
[#9816](#9816)

### 🚜 Refactor

- **(config)** separate core and backend tool options by @risu729 in
[#9753](#9753)
- **(schema)** reuse env directive property schemas by @risu729 in
[#9651](#9651)

### 📚 Documentation

- **(aliases)** fix Aliased Versions example and drop stale asdf callout
by @jdx in [#9830](#9830)

### ⚡ Performance

- **(aqua)** use phf for baked registry lookups by @risu729 in
[#9763](#9763)
- **(task)** cache per-file content hashes for
source_freshness_hash_contents by @jdx in
[#9819](#9819)

### 🧪 Testing

- **(e2e)** pin aube to known-good version in npm package_manager test
by @jdx in [#9794](#9794)

### 📦 Registry

- replace unsupported exe options by @risu729 in
[#9587](#9587)
- update pi by @garysassano in
[#9792](#9792)

### Chore

- **(ci)** use non-large runners for release builds by @jdx in
[#9786](#9786)
- **(ci)** compare registry PRs from fork point by @risu729 in
[#9643](#9643)
- **(ci)** make build-copr.sh the single source of truth for COPR
chroots by @jdx in [#9788](#9788)
- **(ci)** use crates.io trusted publishing in release-plz by @jdx in
[#9793](#9793)
- **(ci)** remove autofix.ci workflow by @jdx in
[#9801](#9801)
- **(ci)** restore -large runner for Linux release builds by @jdx in
[#9815](#9815)
- **(ci)** add zizmor workflow for github actions security analysis by
@jdx in [#9804](#9804)
- **(ci)** assert mise run render produces no diff by @jdx in
[#9803](#9803)
- **(copr)** publish EL9 builds via centos-stream+epel-next-9 chroot by
@jdx in [#9787](#9787)

### Ci

- remove pull_request_target workflow by @jdx in
[#9799](#9799)
- remove caching from publishing workflows by @jdx in
[#9800](#9800)

### Security

- reject shell metacharacters in version strings and CI inputs by @jdx
in [#9814](#9814)

## 📦 Aqua Registry Updates

### New Packages (11)

- [`Code-Hex/Neo-cowsay`](https://github.com/Code-Hex/Neo-cowsay)
-
[`SonarSource/sonarqube-cli`](https://github.com/SonarSource/sonarqube-cli)
- [`earendil-works/pi`](https://github.com/earendil-works/pi)
- [`hylo-lang/hylo-new`](https://github.com/hylo-lang/hylo-new)
- [`jfernandez/bpftop`](https://github.com/jfernandez/bpftop)
- [`modem-dev/hunk`](https://github.com/modem-dev/hunk)
- [`npm/cli`](https://github.com/npm/cli)
- [`racket/racket/minimal`](https://github.com/racket/racket)
- [`slackapi/slack-cli`](https://github.com/slackapi/slack-cli)
- [`vectordotdev/vector`](https://github.com/vectordotdev/vector)
- [`wasilibs/go-yamllint`](https://github.com/wasilibs/go-yamllint)

### Updated Packages (10)

- [`DataDog/pup`](https://github.com/DataDog/pup)
- [`aquasecurity/trivy`](https://github.com/aquasecurity/trivy)
- [`astral-sh/uv`](https://github.com/astral-sh/uv)
- [`caarlos0/svu`](https://github.com/caarlos0/svu)
-
[`cargo-bins/cargo-binstall`](https://github.com/cargo-bins/cargo-binstall)
- [`foundry-rs/foundry`](https://github.com/foundry-rs/foundry)
- [`gastownhall/beads`](https://github.com/gastownhall/beads)
-
[`gruntwork-io/terragrunt`](https://github.com/gruntwork-io/terragrunt)
- [`pnpm/pnpm`](https://github.com/pnpm/pnpm)
- [`santosr2/TerraTidy`](https://github.com/santosr2/TerraTidy)
3PeatVR pushed a commit to 3PeatVR/mise that referenced this pull request May 14, 2026
### 🐛 Bug Fixes

- **(backend)** use runtime paths for backend bin dirs by @risu729 in
[jdx#9606](jdx#9606)
- **(ci)** preserve vendor/aqua-registry/ in PPA publish workflow by
@jdx in [jdx#9782](jdx#9782)
- **(ci)** set UTF-8 locale in e2e Docker image by @jdx in
[jdx#9820](jdx#9820)
- **(ci)** pass UTF-8 locale through to e2e tests by @jdx in
[jdx#9823](jdx#9823)
- **(conda)** dedup repodata by archive identifier instead of URL by
@jdx in [jdx#9831](jdx#9831)
- **(github)** use default shell for credential command by @risu729 in
[jdx#9664](jdx#9664)
- **(settings)** distinguish unset known settings from unknown ones by
@jdx in [jdx#9818](jdx#9818)
- **(upgrade)** remove completed progress jobs to prevent duplicate
output by @jdx in [jdx#9779](jdx#9779)
- **(vfox)** resolve GitHub token lazily inside Lua plugins by @jdx in
[jdx#9816](jdx#9816)

### 🚜 Refactor

- **(config)** separate core and backend tool options by @risu729 in
[jdx#9753](jdx#9753)
- **(schema)** reuse env directive property schemas by @risu729 in
[jdx#9651](jdx#9651)

### 📚 Documentation

- **(aliases)** fix Aliased Versions example and drop stale asdf callout
by @jdx in [jdx#9830](jdx#9830)

### ⚡ Performance

- **(aqua)** use phf for baked registry lookups by @risu729 in
[jdx#9763](jdx#9763)
- **(task)** cache per-file content hashes for
source_freshness_hash_contents by @jdx in
[jdx#9819](jdx#9819)

### 🧪 Testing

- **(e2e)** pin aube to known-good version in npm package_manager test
by @jdx in [jdx#9794](jdx#9794)

### 📦 Registry

- replace unsupported exe options by @risu729 in
[jdx#9587](jdx#9587)
- update pi by @garysassano in
[jdx#9792](jdx#9792)

### Chore

- **(ci)** use non-large runners for release builds by @jdx in
[jdx#9786](jdx#9786)
- **(ci)** compare registry PRs from fork point by @risu729 in
[jdx#9643](jdx#9643)
- **(ci)** make build-copr.sh the single source of truth for COPR
chroots by @jdx in [jdx#9788](jdx#9788)
- **(ci)** use crates.io trusted publishing in release-plz by @jdx in
[jdx#9793](jdx#9793)
- **(ci)** remove autofix.ci workflow by @jdx in
[jdx#9801](jdx#9801)
- **(ci)** restore -large runner for Linux release builds by @jdx in
[jdx#9815](jdx#9815)
- **(ci)** add zizmor workflow for github actions security analysis by
@jdx in [jdx#9804](jdx#9804)
- **(ci)** assert mise run render produces no diff by @jdx in
[jdx#9803](jdx#9803)
- **(copr)** publish EL9 builds via centos-stream+epel-next-9 chroot by
@jdx in [jdx#9787](jdx#9787)

### Ci

- remove pull_request_target workflow by @jdx in
[jdx#9799](jdx#9799)
- remove caching from publishing workflows by @jdx in
[jdx#9800](jdx#9800)

### Security

- reject shell metacharacters in version strings and CI inputs by @jdx
in [jdx#9814](jdx#9814)

## 📦 Aqua Registry Updates

### New Packages (11)

- [`Code-Hex/Neo-cowsay`](https://github.com/Code-Hex/Neo-cowsay)
-
[`SonarSource/sonarqube-cli`](https://github.com/SonarSource/sonarqube-cli)
- [`earendil-works/pi`](https://github.com/earendil-works/pi)
- [`hylo-lang/hylo-new`](https://github.com/hylo-lang/hylo-new)
- [`jfernandez/bpftop`](https://github.com/jfernandez/bpftop)
- [`modem-dev/hunk`](https://github.com/modem-dev/hunk)
- [`npm/cli`](https://github.com/npm/cli)
- [`racket/racket/minimal`](https://github.com/racket/racket)
- [`slackapi/slack-cli`](https://github.com/slackapi/slack-cli)
- [`vectordotdev/vector`](https://github.com/vectordotdev/vector)
- [`wasilibs/go-yamllint`](https://github.com/wasilibs/go-yamllint)

### Updated Packages (10)

- [`DataDog/pup`](https://github.com/DataDog/pup)
- [`aquasecurity/trivy`](https://github.com/aquasecurity/trivy)
- [`astral-sh/uv`](https://github.com/astral-sh/uv)
- [`caarlos0/svu`](https://github.com/caarlos0/svu)
-
[`cargo-bins/cargo-binstall`](https://github.com/cargo-bins/cargo-binstall)
- [`foundry-rs/foundry`](https://github.com/foundry-rs/foundry)
- [`gastownhall/beads`](https://github.com/gastownhall/beads)
-
[`gruntwork-io/terragrunt`](https://github.com/gruntwork-io/terragrunt)
- [`pnpm/pnpm`](https://github.com/pnpm/pnpm)
- [`santosr2/TerraTidy`](https://github.com/santosr2/TerraTidy)
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.

2 participants