Skip to content

fix: failing rebuild of runtime symlinks for shared tools#8647

Merged
jdx merged 1 commit intojdx:mainfrom
roele:issues/8596
Mar 19, 2026
Merged

fix: failing rebuild of runtime symlinks for shared tools#8647
jdx merged 1 commit intojdx:mainfrom
roele:issues/8596

Conversation

@roele
Copy link
Copy Markdown
Contributor

@roele roele commented Mar 18, 2026

Currently installing a tool with --system fails at rebuilding the runtime symlinks because the installs path is pointing to a wrong directory. The install state reads the tools from the shared directory but does not contain an install path which leads to a BackendArg using the default (user) install directory.

Copilot AI review requested due to automatic review settings March 18, 2026 18:42
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses a critical issue where installing tools with the --system flag prevented the correct rebuilding of runtime symlinks. Previously, the system would incorrectly default to the user's installation directory, leading to failures. The changes introduce explicit tracking of the installation path within the tool's state and ensure this path is correctly propagated and used during the backend argument resolution process, thereby resolving the symlink rebuilding problem for shared tools.

Highlights

  • Enhanced Install State Tracking: The InstallStateTool struct now includes an installs_path field, allowing it to correctly store the installation directory for tools, especially those installed with --system.
  • Corrected Backend Argument Resolution: The BackendArg conversion from InstallStateTool has been updated to utilize the newly tracked installs_path, ensuring that runtime symlinks for shared tools are rebuilt using the correct directory instead of defaulting to the user's directory.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Mar 18, 2026

Greptile Summary

This PR fixes a bug where installing a tool with --system (shared install directory) would fail during runtime-symlink rebuilding because the resulting BackendArg always used the default user-level dirs::INSTALLS path instead of the actual shared install path.

The fix introduces an installs_path: Option<PathBuf> field to InstallStateTool, populated with the real on-disk directory during both the user-level and shared-level scan passes in init_tools. In From<InstallStateTool> for BackendArg, the stored path is then used to override the default that new_raw would otherwise produce.

Key observations:

  • The logic correctly preserves user-dir precedence: for tools present in both the user dir and a shared dir, installs_path points to the user-level directory (the shared scan's or_insert_with closure is skipped for already-seen tools).
  • Plugin-only entries (no on-disk installs) deliberately receive installs_path: None, causing BackendArg to retain its default user path, which is the expected behavior.
  • cache_path and downloads_path in BackendArg are still derived from dirs::CACHE / dirs::DOWNLOADS regardless of the shared install root (flagged separately in a prior thread).
  • No unit test covers the new installs_path override in From<InstallStateTool> for BackendArg, leaving a gap that could silently regress.

Confidence Score: 4/5

  • This PR is safe to merge; it fixes a targeted regression for shared/system installs with no impact on the existing user-level install flow.
  • The change is minimal and surgical — one new optional field on InstallStateTool and a one-line override in From<InstallStateTool> for BackendArg. The user-level path is unaffected (the stored path equals the default for user-level tools, so the override is a no-op there). The only gap is the absence of a regression test for the shared-path override path, which is why the score is 4 rather than 5.
  • No files require special attention; both changed files are small and well-scoped.

Important Files Changed

Filename Overview
src/toolset/install_state.rs Adds installs_path: Option<PathBuf> to InstallStateTool, populated with the actual on-disk directory for user-level and shared-level tools (and None for plugin-only entries). This is the source-of-truth change enabling the fix.
src/cli/args/backend_arg.rs In From<InstallStateTool> for BackendArg, overrides the default user-level installs_path with the one stored in InstallStateTool when present; fixes runtime-symlink rebuild failure for shared/system installs.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[init_tools scans install dirs] --> B{User-level dir?}
    B -- yes --> C[Create InstallStateTool\ninstalls_path = Some user_dir]
    B -- no --> D{Shared/system dir?}
    D -- yes, tool not yet seen --> E[Create InstallStateTool\ninstalls_path = Some shared_dir]
    D -- yes, tool already seen --> F[Merge versions only\ninstalls_path unchanged]
    D -- no, plugin only --> G[Create InstallStateTool\ninstalls_path = None]

    C --> H[From InstallStateTool for BackendArg]
    E --> H
    F --> H
    G --> H

    H --> I[new_raw sets installs_path\n= dirs::INSTALLS default user path]
    I --> J{ist.installs_path Some?}
    J -- yes --> K[Override installs_path\nwith stored path]
    J -- no --> L[Keep default user path]

    K --> M[BackendArg.installs_path\n= actual on-disk path]
    L --> N[BackendArg.installs_path\n= default user path]

    style E fill:#90EE90
    style K fill:#90EE90
    style M fill:#90EE90
Loading

Last reviewed commit: "fix: failing rebuild..."

Comment thread src/cli/args/backend_arg.rs Outdated
Copy link
Copy Markdown
Contributor

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

Choose a reason for hiding this comment

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

Code Review

The pull request effectively addresses the issue of failing runtime symlink rebuilds by correctly propagating the installs_path from InstallStateTool to BackendArg. The changes involve adding a new field to the InstallStateTool struct and ensuring its proper initialization and usage during the conversion to BackendArg. The modifications are clear, concise, and directly resolve the described bug.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes runtime symlink rebuild failures for tools installed via --system/--shared by ensuring the resolved backend uses the correct installs directory (instead of falling back to the default user installs dir).

Changes:

  • Track the concrete installs directory for each discovered installed tool in InstallStateTool.
  • Propagate InstallStateTool.installs_path into BackendArg so runtime symlink rebuild targets the correct directory.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
src/toolset/install_state.rs Adds installs_path to InstallStateTool and populates it for tools discovered in local and shared installs directories.
src/cli/args/backend_arg.rs Updates From<InstallStateTool> to override BackendArg.installs_path when install state provides a concrete installs directory.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/cli/args/backend_arg.rs Outdated
Comment on lines +89 to +99
let mut tool = Self::new_raw(
short,
ist.full,
tool_name,
opts,
BackendResolution::new(ist.explicit_backend),
)
);
if let Some(install_path) = ist.installs_path {
tool.installs_path = install_path;
}
tool
@jdx jdx merged commit 4dd51b1 into jdx:main Mar 19, 2026
32 of 34 checks passed
@roele roele deleted the issues/8596 branch March 20, 2026 22:41
jdx pushed a commit that referenced this pull request Mar 21, 2026
### 🐛 Bug Fixes

- **(config)** resolve trust hash collision for same-name directories by
@tdragon in [#8628](#8628)
- **(docs)** fix width of tools table by @himkt in
[#8625](#8625)
- **(docs)** prevent homepage hero atmosphere overflow by @nygmaaa in
[#8642](#8642)
- **(doctor)** detect PATH ordering issues when mise is activated by
@jdx in [#8585](#8585)
- **(git)** use origin as remote name by @bentinata in
[#8626](#8626)
- **(installer)** normalize current version before comparison by @tak848
in [#8649](#8649)
- **(lockfile)** Resolve symlink when updating lockfiles by @chancez in
[#8589](#8589)
- **(python)** verify checksums for precompiled binary downloads by
@malept in [#8593](#8593)
- **(rust)** resolve relative CARGO_HOME/RUSTUP_HOME to absolute paths
by @simonepri in [#8604](#8604)
- **(task)** correctly resolve task name for _default files with
extensions by @youta1119 in
[#8646](#8646)
- **(tasks)** global file tasks not properly marked as such by @roele in
[#8618](#8618)
- **(tasks)** handle broken pipe in table print and task completion
output by @vmaleze in [#8608](#8608)
- use dark/light logo variants in README for GitHub dark mode by @jdx in
[#8656](#8656)
- failing rebuild of runtime symlinks for shared tools by @roele in
[#8647](#8647)
- add spaces around current element operator in flutter version_expr by
@roele in [#8616](#8616)
- complete task arguments correctly by @KevSlashNull in
[#8601](#8601)

### 📚 Documentation

- switch body font to DM Sans and darken dark mode background by @jdx in
[6e3ad34](6e3ad34)
- use Cormorant Garamond for headers and Roc Grotesk for body text by
@jdx in
[010812a](010812a)
- resolve chaotic heading hierarchy in task-arguments.md by @muzimuzhi
in [#8644](#8644)

### 🧪 Testing

- fix test_java and mark as slow by @roele in
[#8634](#8634)

### 📦️ Dependency Updates

- update docker/dockerfile:1 docker digest to 4a43a54 by @renovate[bot]
in [#8657](#8657)
- update ghcr.io/jdx/mise:alpine docker digest to 2584470 by
@renovate[bot] in [#8658](#8658)

### 📦 Registry

- add viteplus (npm:vite-plus) by @risu729 in
[#8594](#8594)
- remove backend.options for podman by @roele in
[#8633](#8633)
- add pi.dev coding agent by @dector in
[#8635](#8635)
- add ormolu ([github:tweag/ormolu](https://github.com/tweag/ormolu)) by
@3w36zj6 in [#8617](#8617)
- use version_expr for dart and sort versions by @roele in
[#8631](#8631)

### New Contributors

- @bentinata made their first contribution in
[#8626](#8626)
- @tdragon made their first contribution in
[#8628](#8628)
- @nygmaaa made their first contribution in
[#8642](#8642)
- @youta1119 made their first contribution in
[#8646](#8646)
- @chancez made their first contribution in
[#8589](#8589)
- @dector made their first contribution in
[#8635](#8635)
- @tak848 made their first contribution in
[#8649](#8649)

## 📦 Aqua Registry Updates

#### New Packages (5)

- [`acsandmann/rift`](https://github.com/acsandmann/rift)
-
[`alltuner/mise-completions-sync`](https://github.com/alltuner/mise-completions-sync)
- [`berbicanes/apiark`](https://github.com/berbicanes/apiark)
-
[`gitlab.com/graphviz/graphviz`](https://github.com/gitlab.com/graphviz/graphviz)
-
[`jorgelbg/pinentry-touchid`](https://github.com/jorgelbg/pinentry-touchid)

#### Updated Packages (7)

- [`UpCloudLtd/upcloud-cli`](https://github.com/UpCloudLtd/upcloud-cli)
- [`aquaproj/registry-tool`](https://github.com/aquaproj/registry-tool)
- [`go-swagger/go-swagger`](https://github.com/go-swagger/go-swagger)
-
[`gopinath-langote/1build`](https://github.com/gopinath-langote/1build)
- [`sassman/t-rec-rs`](https://github.com/sassman/t-rec-rs)
- [`sharkdp/fd`](https://github.com/sharkdp/fd)
- [`temporalio/cli`](https://github.com/temporalio/cli)
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.

4 participants