fix(github): use registry platform options during install#8492
Conversation
Two bugs prevented registry-defined platform-specific options (like `asset_pattern`) from being applied during installation: 1. `backend_options()` stored serialized TOML table strings as `toml::Value::String` instead of parsing them back to `toml::Value::Table`, so `get_nested_string()` couldn't navigate the nested platform structure. 2. `install_version_()` fell back to `tv.request.options()` (user config only) instead of `self.ba.opts()` (which merges registry options), so registry-defined options never reached the install path. This caused tools like flyway to select the wrong asset (e.g., alpine instead of linux-x64) because the platform-specific `asset_pattern` from the registry was silently ignored. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Summary of ChangesHello, 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 bug in how platform-specific configuration options from tool registries were processed during installation. Previously, these options were not correctly applied, leading to tools downloading incompatible or incorrect assets. The changes ensure that registry-defined options, especially those with nested structures, are properly parsed and merged with user configurations, guaranteeing that the correct assets are selected and installed for various platforms. Highlights
Changelog
Activity
Using Gemini Code AssistThe 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
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 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. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request correctly addresses an issue where platform-specific options from the tool registry were being ignored during installation. The changes are well-targeted and effectively resolve the problem. First, by modifying src/registry.rs, it ensures that serialized TOML tables in registry options are properly parsed, preserving nested structures needed for platform-specific configurations. Second, the update in src/backend/github.rs guarantees that the installation process uses the fully merged options, including registry defaults, rather than just the user-provided request options. The implementation is clean and robust. I have no further comments.
Greptile SummaryThis PR fixes two related bugs that caused registry-defined platform-specific options (like Changes:
Potential issue: Confidence Score: 3/5
Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[install_version_ called] --> B[get_tool_opts from config]
B -->|Some opts| C[Use config opts]
B -->|None| D{Before fix vs After fix}
D -->|Before: tv.request.options\nuser options only| E[Missing registry platform options]
D -->|After: self.ba.opts\nregistry + user merged| F[Platform options resolved correctly]
F --> G[resolve_asset_url with correct opts]
G --> H[Downloads correct asset e.g. linux-x64]
I[resolve_lock_info called\ncross-platform lockfile gen] --> J[tv.request.options\nSTILL user options only - unfixed]
J --> K[resolve_asset_url_for_target with incomplete opts]
K --> L[Wrong asset URL written to lockfile for other platforms]
M[backend_options in registry.rs] -->|Before fix| N[toml::Value::String for all values\nnested tables unnavigable]
M -->|After fix| O[toml::from_str parses tables correctly\nplatform-specific options navigable]
|
| let value = match toml::from_str::<toml::Value>(v) { | ||
| Ok(parsed) if parsed.is_table() => parsed, | ||
| _ => toml::Value::String(v.to_string()), | ||
| }; |
There was a problem hiding this comment.
Non-table TOML scalars are silently demoted to strings
The guard if parsed.is_table() means valid non-table TOML literals (booleans, integers, floats, and arrays) will be stored as toml::Value::String rather than their native types. For example, if a registry entry ever sets a numeric or boolean option (e.g., timeout = 30), toml::from_str::<toml::Value>("30") returns Ok(Integer(30)) but because !parsed.is_table() it falls through to String("30"), losing type information.
A more future-proof guard would be to only fall back to String when parsing fails outright:
| let value = match toml::from_str::<toml::Value>(v) { | |
| Ok(parsed) if parsed.is_table() => parsed, | |
| _ => toml::Value::String(v.to_string()), | |
| }; | |
| let value = if let Ok(parsed) = toml::from_str::<toml::Value>(&format!("v={v}")) | |
| && let Some(v) = parsed.get("v") | |
| && !v.is_str() | |
| { | |
| v.clone() | |
| } else { | |
| toml::Value::String(v.to_string()) | |
| }; |
Or, more simply, only skip the table guard by falling back to String for everything that isn't a table or array, since those are the only composite types that need reconstruction. This is a low-risk style concern for now, but worth addressing before adding integer/boolean registry options.
Hyperfine Performance
|
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.3.3 x -- echo |
23.5 ± 0.7 | 22.8 | 33.5 | 1.00 ± 0.03 |
mise x -- echo |
23.4 ± 0.3 | 22.7 | 24.9 | 1.00 |
mise env
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.3.3 env |
23.0 ± 0.7 | 22.3 | 29.8 | 1.00 |
mise env |
23.1 ± 0.5 | 22.2 | 25.0 | 1.00 ± 0.04 |
mise hook-env
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.3.3 hook-env |
23.8 ± 0.3 | 23.1 | 25.7 | 1.00 |
mise hook-env |
24.0 ± 0.5 | 23.3 | 27.6 | 1.01 ± 0.03 |
mise ls
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.3.3 ls |
23.1 ± 0.5 | 22.4 | 30.2 | 1.01 ± 0.03 |
mise ls |
22.9 ± 0.3 | 22.2 | 25.9 | 1.00 |
xtasks/test/perf
| Command | mise-2026.3.3 | mise | Variance |
|---|---|---|---|
| install (cached) | 152ms | 151ms | +0% |
| ls (cached) | 83ms | 82ms | +1% |
| bin-paths (cached) | 85ms | 85ms | +0% |
| task-ls (cached) | 807ms | 810ms | +0% |
### 🚀 Features - **(github)** keep exe extensions on Windows by @iki in [#8424](#8424) - **(task)** add `interactive` field for exclusive terminal access by @jdx in [#8491](#8491) - add header comment to generated lockfiles by @ivy in [#8481](#8481) - runtime musl/glibc detection for correct libc variant selection by @jdx in [#8490](#8490) ### 🐛 Bug Fixes - **(github)** use registry platform options during install by @jdx in [#8492](#8492) - **(http)** store tool opts as native TOML to fix platform switching by @jdx in [#8448](#8448) - **(installer)** error if MISE_INSTALL_PATH is a directory by @jdx in [#8468](#8468) - **(prepare)** resolve sources/outputs relative to `dir` when set by @jdx in [#8472](#8472) - **(ruby)** fetch precompiled binary by release tag instead of listing all releases by @jdx in [#8488](#8488) - **(schema)** support structured objects in task depends by @risu729 in [#8463](#8463) - **(task)** replace println!/eprintln! with calm_io in task output macros by @vmaleze in [#8485](#8485) - handle scoped npm package names without backend prefix by @jdx in [#8477](#8477) ### 📦️ Dependency Updates - update ghcr.io/jdx/mise:copr docker digest to c485c4c by @renovate[bot] in [#8484](#8484) - update ghcr.io/jdx/mise:alpine docker digest to 8118bc7 by @renovate[bot] in [#8483](#8483) ### 📦 Registry - disable sd version test by @jdx in [#8489](#8489) ### New Contributors - @ivy made their first contribution in [#8481](#8481) - @iki made their first contribution in [#8424](#8424) ## 📦 Aqua Registry Updates #### New Packages (5) - [`datadog-labs/pup`](https://github.com/datadog-labs/pup) - [`k1LoW/mo`](https://github.com/k1LoW/mo) - [`rtk-ai/rtk`](https://github.com/rtk-ai/rtk) - [`suzuki-shunsuke/docfresh`](https://github.com/suzuki-shunsuke/docfresh) - [`yashikota/exiftool-go`](https://github.com/yashikota/exiftool-go) #### Updated Packages (6) - [`cloudflare/cloudflared`](https://github.com/cloudflare/cloudflared) - [`mozilla/sccache`](https://github.com/mozilla/sccache) - [`owenlamont/ryl`](https://github.com/owenlamont/ryl) - [`spinel-coop/rv`](https://github.com/spinel-coop/rv) - [`technicalpickles/envsense`](https://github.com/technicalpickles/envsense) - [`weaviate/weaviate`](https://github.com/weaviate/weaviate)
Summary
asset_pattern) being silently ignored during tool installationbackend_options()stored serialized TOML table strings astoml::Value::Stringinstead of parsing them back totoml::Value::Table, soget_nested_string()couldn't navigate the nested platform structureinstall_version_()fell back totv.request.options()(user config only) instead ofself.ba.opts()(which merges registry options)Test plan
cargo testpasses (registry, github, tool_version_options tests)mise install flyway@12.0.3now downloadsflyway-commandline-12.0.3-linux-x64.tar.gzinstead of alpine variant🤖 Generated with Claude Code
Note
Medium Risk
Changes option parsing and install-time option precedence, which can alter which release asset URL gets selected/downloaded for some tools and platforms.
Overview
Ensures tool installation uses the merged backend options (including registry defaults) instead of falling back to request-only options when
Config::get_tool_optshas no override, so platform-specific settings likeasset_patternare honored during asset resolution.Updates
RegistryTool::backend_options()to parse option values that are serialized TOML tables back intotoml::Value::Table, preserving nested structures (e.g.,platforms.*) rather than flattening them into strings.Written by Cursor Bugbot for commit f2833dd. This will update automatically on new commits. Configure here.