Skip to content

fix(config): limit resolved backend opts to aliases#9315

Merged
jdx merged 7 commits intojdx:mainfrom
risu729:codex/e2e-install-short-ignores-full-config
Apr 24, 2026
Merged

fix(config): limit resolved backend opts to aliases#9315
jdx merged 7 commits intojdx:mainfrom
risu729:codex/e2e-install-short-ignores-full-config

Conversation

@risu729
Copy link
Copy Markdown
Contributor

@risu729 risu729 commented Apr 23, 2026

Suggested follow-up

Consider removing the remaining fallback where a configured tool_alias with no [tools.<alias>] entry reads options from [tools."<resolved-backend>"]. That behavior is kept in this PR for compatibility, but it can be ambiguous once both the alias and resolved backend are configured:

[tool_alias]
hw = "github:jdx/mise-test-fixtures"

[tools.hw]
version = "1.0.0"
asset_pattern = "hello-world-1.0.0.tar.gz"

[tools."github:jdx/mise-test-fixtures"]
version = "1.0.0"
asset_pattern = "hello-world-test-1.0.0.tar.gz"

In that case, this PR treats [tools.hw] as more specific and does not fall back to the resolved backend options.

What changed

Examples

Registry short-name installs no longer inherit options from the resolved full backend key:

[tools]
"github:aquaproj/aqua" = { version = "2.0.0", asset_pattern = "definitely-not-a-real-aqua-asset" }
mise install [email protected]

Configured backend aliases can still use options from the resolved full backend config when there is no alias-specific tool entry:

[tools]
"gitlab:jdxcode/mise-test-fixtures" = { version = "1.0.0", asset_pattern = "hello-world-1.0.0.tar.gz" }

[tool_alias]
my-test-tool = "gitlab:jdxcode/mise-test-fixtures"
mise ls-remote my-test-tool
mise x my-test-tool -- hello-world

Alias-specific tool config remains more specific than the resolved full backend config:

[tool_alias]
hw = "github:jdx/mise-test-fixtures"

[tools.hw]
version = "1.0.0"
asset_pattern = "hello-world-1.0.0.tar.gz"

[tools."github:jdx/mise-test-fixtures"]
version = "1.0.0"
asset_pattern = "definitely-not-a-real-hello-world-asset"

Why

mise install [email protected] resolves the registry short name aqua to github:aquaproj/aqua. The previous get_tool_opts fallback looked up options by that resolved full backend even when the user requested the short registry name, causing options such as asset_pattern from [tools."github:aquaproj/aqua"] to leak into the install.

Configured backend aliases still need the resolved-full fallback for compatibility when there is no alias-specific tool entry. The fix narrows the fallback to configured aliases and keeps alias-specific config more specific whenever it exists.

Validation

  • mise run format
  • mise run test:e2e e2e/cli/test_install_short_ignores_full_backend_config e2e/backend/test_gitlab e2e/backend/test_github_tool_alias_asset_pattern

This PR was updated by an AI coding assistant.

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

This pull request introduces a new end-to-end test to verify that tool installations using registry short names do not inherit configuration from entries keyed by full backend names. Feedback suggests enhancing the test's robustness by using the --force flag and adding a verification step to ensure the tool is correctly installed.

Comment thread e2e/cli/test_install_short_ignores_full_backend_config Outdated
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 23, 2026

Greptile Summary

This PR fixes a bug where mise install [email protected] (using a registry short name) would incorrectly inherit options like asset_pattern from a [tools."github:aquaproj/aqua"] config entry, because get_tool_opts previously fell back to any resolved full-backend match in the ToolRequestSet. The fix introduces has_tool_alias to gate that fallback: only explicitly configured backend aliases ([tool_alias] entries) or custom plugin URLs (repo_urls) may use the resolved-backend fallback, while plain registry short-name resolution is excluded. The three e2e tests provide solid coverage of the short-name install case, the ambiguous alias+backend config case, and the compatibility fallback for configured aliases with no alias-specific tool entry.

Confidence Score: 5/5

Safe to merge; the narrowed fallback is well-reasoned and all three behavioural cases are covered by e2e tests

The core logic change is small and correct: or_else only fires when no direct short-name match exists, and has_tool_alias precisely distinguishes configured aliases from registry short-name resolution. No P1/P0 findings; all remaining observations are P2 or lower.

No files require special attention

Important Files Changed

Filename Overview
src/config/mod.rs Rewrites get_tool_opts to use has_tool_alias gating instead of a has_opts preference heuristic, correctly scoping the resolved-backend fallback to configured aliases only; logic is sound and narrower than the original
e2e/backend/test_github_tool_alias_asset_pattern Adds regression test verifying alias-specific [tools.hw] options win over [tools."github:jdx/mise-test-fixtures"] when both are configured; correctly verifies install dir rather than command output
e2e/cli/test_install_short_ignores_full_backend_config New e2e test verifying that mise install [email protected] succeeds even when [tools."github:aquaproj/aqua"] has a bogus asset_pattern; validates the core bug is fixed

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["get_tool_opts(backend_arg)"] --> B["short_match = trs.find(short == ba.short)"]
    B --> C{short_match found?}
    C -- Yes --> G["Return short_match options\n(alias-specific wins)"]
    C -- No --> D{"has_tool_alias(ba.short)?"}
    D -- No\n(registry short name) --> H["Return None\n(no options leaked)"]
    D -- Yes\n(configured alias or plugin URL) --> E["resolved_ba = BackendArg::new(ba.full())"]
    E --> F["resolved_match = trs.find(short == resolved_ba.short)"]
    F --> I["Return resolved_match options\n(compatibility fallback)"]
Loading

Reviews (7): Last reviewed commit: "Rename has_backend_alias to has_tool_ali..." | Re-trigger Greptile

Comment thread e2e/cli/test_install_short_ignores_full_backend_config Outdated
@risu729 risu729 changed the title test(install): cover short installs ignoring full backend config fix(config): ignore full backend opts for short installs Apr 24, 2026
@risu729 risu729 changed the title fix(config): ignore full backend opts for short installs fix(config): limit resolved backend opts to aliases Apr 24, 2026
@risu729 risu729 marked this pull request as ready for review April 24, 2026 19:33
@jdx jdx enabled auto-merge (squash) April 24, 2026 20:27
@jdx jdx merged commit a02f64e into jdx:main Apr 24, 2026
34 checks passed
@risu729 risu729 deleted the codex/e2e-install-short-ignores-full-config branch April 24, 2026 20:44
mise-en-dev added a commit that referenced this pull request Apr 25, 2026
### 🚀 Features

- **(registry)** add --security flag to include security info in JSON
output by @jdx in [#9364](#9364)

### 🐛 Bug Fixes

- **(config)** limit resolved backend opts to aliases by @risu729 in
[#9315](#9315)
- **(docs)** stack banner message and link on mobile by @jdx in
[#9362](#9362)
- **(github)** prefer shortest asset name as tiebreaker in
auto-detection by @jdx in [#9361](#9361)
- **(java)** newer zulu versions use a different directory structure by
@roele in [#9365](#9365)
- **(prune)** respect tracked lockfiles by @jdx in
[#9373](#9373)
- **(task)** skip tool install for missing naked tasks by @jdx in
[#9374](#9374)
- **(trust)** add untrust command by @jdx in
[#9370](#9370)
- fix - flux-operator-mcp aqua path by @monotek in
[#9357](#9357)

### 📚 Documentation

- update ruby compile msg by @fladson in
[#9338](#9338)

### 📦️ Dependency Updates

- update ubuntu docker tag to v26 by @renovate[bot] in
[#9347](#9347)
- update ghcr.io/jdx/mise:deb docker digest to 1af5a69 by @renovate[bot]
in [#9352](#9352)
- update taiki-e/install-action digest to 787505c by @renovate[bot] in
[#9354](#9354)
- update ghcr.io/jdx/mise:rpm docker digest to 7015ff3 by @renovate[bot]
in [#9353](#9353)
- update ghcr.io/jdx/mise:copr docker digest to da63a0f by
@renovate[bot] in [#9351](#9351)
- update ghcr.io/jdx/mise:alpine docker digest to 461700f by
@renovate[bot] in [#9350](#9350)
- bump communique 1.0.3 → 1.0.4 by @jdx in
[#9378](#9378)

### 📦 Registry

- remove openshift-install by @jdx in
[#9372](#9372)
- remove go-sdk by @jdx in
[#9371](#9371)

### Chore

- **(npm-publish)** use aube publish instead of npm publish by @jdx in
[#9328](#9328)

### New Contributors

- @fladson made their first contribution in
[#9338](#9338)
jdx pushed a commit that referenced this pull request May 5, 2026
## What

- Add a shared backend option resolver that preserves where each
effective option came from.
- Resolve backend options in this order, with later layers overriding
earlier ones:
  1. Registry backend defaults.
2. Backend alias `[...]` options from `[tool_alias]` / `[alias]` backend
entries.
  3. Config options selected by the existing tool config lookup rules.
4. Inline backend options from the current tool spec, such as
`tool[...]`.
- Apply that resolved option path consistently in GitHub/GitLab/Forgejo,
HTTP, S3, UBI, vfox backend plugins, Conda channel resolution, SPM
provider/API URL resolution, Java release type listing, versions-host
cache filtering, fuzzy version matching, `minimum_release_age` handling,
runtime args, and install request initialization.
- Preserve inline backend options across the short-name backend cache,
so commands like `ls-remote 'github:owner/repo[api_url=...]'` do not
accidentally use a cached installed backend without those inline
options.
- Preserve config options when runtime args include inline overrides,
while still letting inline options win for the one command.
- Switch Go install to use the resolved request options.
- Fix shorthand parsing for URL-valued inline options such as
`tool[api_url=https://example/api/v3]`.

## Follow-up

The versions-host behavior for locally overridden backend options has
been split into #9568. That PR is stacked on this one and should be
rebased after this merges.

## Relationship to #9315

This PR does not change which config entry is eligible for a tool. That
behavior comes from #9315:

- Registry short names should not inherit config from their resolved
full backend key.
- Configured aliases can fall back to resolved full-backend config when
there is no alias-specific entry.
- Alias-specific `[tools.<alias>]` config is more specific than
`[tools."<resolved-backend>"]` config.

This PR builds on that lookup and changes what happens after config has
been selected: registry defaults, backend alias options, config options,
and inline options are merged through one resolver, with provenance
retained for callers that need to distinguish where an option came from.

## Relationship to #8902

#8902 was a narrower `ls-remote` fix for inline backend options. This PR
covers the same installed-tool cache failure mode generically: when a
caller supplies inline backend options, mise builds a backend from that
caller `BackendArg` instead of returning a short-name cache entry that
was loaded from install state without the inline options.

## Example

Given config selected through an alias fallback:

```toml
[tool_alias]
hw = "github:jdx/mise-test-fixtures[api_url=https://api.github.com]"

[tools."github:jdx/mise-test-fixtures"]
version = "1.0.0"
asset_pattern = "definitely-not-a-real-hello-world-asset"
```

Inline options should still win for this invocation:

```sh
mise install 'hw[asset_pattern=hello-world-1.0.0.tar.gz,bin_path=hello-world-1.0.0/bin]@1.0.0'
```

Before this PR, the resolved full-backend config could replace the
inline `asset_pattern`, and alias `[...]` options were only visible as
part of a resolved string. After this PR, alias options are their own
layer and inline options are applied over the selected config options.

## Why

Backend-level code had several config-or-inline branches. Depending on
the path:

- Inline options could be ignored when config existed for the same tool
or resolved backend.
- Inline options could be dropped at the installed-tool backend cache
boundary.
- Config options could be dropped when runtime args included inline
options.
- Backend alias `[...]` options were not represented as a distinct
layer.
- Backend-specific list/install paths could read raw backend args
instead of the resolved tool options.
- Registry defaults were not always part of the same overlay path as
config and inline options.

This PR centralizes that overlay so config-aware paths use the same
precedence, while preserving source information separately from the
effective option values.

## Validation

- `cargo fmt --all`
- `git diff --check`
- `cargo test --all-features tool_opts`
- `cargo test --all-features opts_with_config`
- `cargo test --all-features test_git_provider_from_ba`
- `mise run test:e2e e2e/backend/test_github_ls_remote_inline_opts`

*This PR was updated by an AI coding assistant.*

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.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.

2 participants