Skip to content

fix(cli): resolve the base of sub-N: before subtracting - #11796

Merged
jdx merged 1 commit into
jdx:mainfrom
JamBalaya56562:fix/sub-version-resolves-alias-base
Aug 9, 2026
Merged

jdx merged 1 commit into
jdx:mainfrom
JamBalaya56562:fix/sub-version-resolves-alias-base

Conversation

@JamBalaya56562

@JamBalaya56562 JamBalaya56562 commented Aug 9, 2026 •

Copy link
Copy Markdown
Contributor

Problem

sub-N:<base> accepts latest and aliases as its base — docs/configuration.md documents
node sub-2:lts and python sub-0.1:latest. But version_sub() can only subtract from a concrete
version, so the base has to be resolved first. ToolVersion::resolve_sub does that, which is why
mise use and mise install handle it. Two other call sites do not.

Measured on v2026.8.3 linux-x64:

command node@sub-2:lts node@sub-1:24
mise ls-remote panic ok (lists 23.x)
mise latest invalid version invalid version
mise use --dry-run ok → 22.23.2 ok
mise install --dry-run ok → 22.23.2 ok
[tools] node = ["lts", "sub-2:lts"] ok → 24.19.0 and 22.23.2 ok
$ mise ls-remote node@sub-2:lts
The application panicked (crashed).
Message:  called `Option::unwrap()` on a `None` value
Location: src/toolset/tool_request.rs:592

Version::new("lts") parses fine, but the resulting chunk is alphanumeric, so
Chunk::single_digit() returns None and the unwrap() aborts. A numeric base does not reach that
line, which is why sub-1:24 works and sub-2:lts does not.

  • src/cli/ls_remote.rs passed orig_version to version_sub() verbatim.
  • src/cli/latest.rs had no ToolRequest::Sub arm; every sub-N: spec fell into
    _ => bail!("invalid version: …").

Change

  • resolve_sub_base() (src/toolset/tool_version.rs) holds the resolution that was inline in
    ToolVersion::resolve_sub — latest via the backend, anything else via Config::resolve_alias —
    and then subtracts. resolve_sub, ls-remote and latest all go through it, so the three cannot
    drift again.
  • version_sub() returns Result<String>. The four unwrap()s become errors naming the offending
    value, so an unresolved base is a message rather than an abort. Subtraction and underflow
    behaviour are unchanged; the existing tests only gained .unwrap().
  • ToolRequest::local_resolve's Sub arm treats a version it cannot subtract from as "no matching
    install", which is what the surrounding lookup already means.

resolve_sub's latest + offline early return is untouched — the comment there explains why
version_sub must not run in that case.

Tests

  • test_version_sub_rejects_non_numeric_base in src/toolset/tool_request.rs. Without the fix
    this test panics rather than fails
    , which is the point of it.
  • e2e/cli/test_ls_remote already covered a numeric base (dummy@sub-1:2); an alias base is added
    next to it via mise alias set dummy lts 2, expecting the same output.
  • e2e/cli/test_latest gains both forms. dummy publishes 1.0.0, 1.1.0, 2.0.0
    (test/data/plugins/dummy/bin/list-all), so sub-1:2 selects prefix 1 and the latest of that
    is 1.1.0.

Why draft

  1. version_sub returning Result. The alternative is a total function returning the input
    unchanged for a non-numeric base — smaller diff, but then ls-remote filters on a nonsense
    prefix and prints nothing at all. An error seemed clearly better; flagging it since it is a
    public signature.
  2. Where resolve_sub_base lives. It sits in tool_version.rs because it needs the backend and
    config. Next to version_sub in tool_request.rs would keep the pair together at the cost of
    more dependencies there.
  3. ToolRequest::Prefix has the same shape of gap and is not touched here — latest bails on
    prefix:20, and ls-remote silently drops the filter and lists everything. Happy to fold it in
    if wanted.

Summary by CodeRabbit

  • New Features

    • Added support for resolving aliases, numeric bases, and latest in sub-N: selectors for latest and ls-remote.
    • Version subtraction now consistently resolves the base version before selecting or displaying results.
  • Bug Fixes

    • Invalid or non-numeric subtraction values now produce clear errors instead of unexpected failures.
    • Invalid subtraction requests no longer generate misleading installation paths.
    • Added coverage for alias-based and latest-based version subtraction scenarios.

@coderabbitai

coderabbitai Bot commented Aug 9, 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: b6368638-1115-4c8f-8d81-19b77decc8a1

📥 Commits

Reviewing files that changed from the base of the PR and between 5221b06 and 296c7c0.

📒 Files selected for processing (3)
  • e2e/cli/test_latest
  • e2e/cli/test_ls_remote
  • src/toolset/tool_version.rs
🚧 Files skipped from review as they are similar to previous changes (3)
  • e2e/cli/test_latest
  • e2e/cli/test_ls_remote
  • src/toolset/tool_version.rs

📝 Walkthrough

Walkthrough

The change adds shared resolution for sub-N bases. latest and ls-remote now resolve aliases and backend-provided latest versions before subtraction. Invalid subtraction inputs return errors, and end-to-end tests cover numeric, alias, and latest bases.

Changes

Sub-version resolution

Layer / File(s) Summary
Validate version subtraction
src/toolset/tool_request.rs
version_sub validates inputs and returns errors. install_path handles subtraction failures without creating invalid paths. Tests cover successful and invalid inputs.
Resolve sub-version bases
src/toolset/tool_version.rs, src/toolset/mod.rs
resolve_sub_base resolves aliases and latest before applying subtraction. resolve_sub uses the shared helper. The helper is re-exported within the crate.
Wire CLI resolution and coverage
src/cli/latest.rs, src/cli/ls_remote.rs, e2e/cli/test_latest, e2e/cli/test_ls_remote
Both commands use backend-aware sub-version resolution. End-to-end tests cover numeric bases, aliases, and direct or aliased latest references.

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

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant resolve_sub_base
  participant ABackend
  participant version_sub
  CLI->>resolve_sub_base: Resolve sub-N base
  resolve_sub_base->>ABackend: Resolve latest version
  resolve_sub_base->>version_sub: Apply subtraction
  version_sub-->>resolve_sub_base: Return version or error
Loading

Possibly related PRs

  • jdx/mise#10962: Both changes involve sub-N:latest handling in src/toolset/mod.rs, but they modify different behavior.
  • jdx/mise#11580: Both changes modify sub-N: selector resolution and alias or base handling.

Poem

A rabbit hops through aliases bright,
Resolves each base to the right.
latest joins the version trail,
Subtraction errors now fail clean.
Tests watch every route with care.

🚥 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 describes the main fix: resolving the base of sub-N requests before version subtraction.
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.

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/toolset/tool_version.rs`:
- Around line 710-717: Update resolve_sub_base around the existing base match so
aliases resolving to the literal "latest" are resolved through
latest_version_with_refresh before calling tool_request::version_sub, while
preserving the current direct-"latest" branch. Add regression coverage for both
sub-1:latest and a sub-1 request using an alias mapped to latest.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Pro Plus

Run ID: 408d1ebe-0a85-452f-9496-5cff4d45e1e4

📥 Commits

Reviewing files that changed from the base of the PR and between b3ebfb9 and 5221b06.

📒 Files selected for processing (7)
  • e2e/cli/test_latest
  • e2e/cli/test_ls_remote
  • src/cli/latest.rs
  • src/cli/ls_remote.rs
  • src/toolset/mod.rs
  • src/toolset/tool_request.rs
  • src/toolset/tool_version.rs

Comment thread src/toolset/tool_version.rs Resolved
@JamBalaya56562
JamBalaya56562 force-pushed the fix/sub-version-resolves-alias-base branch from 5221b06 to 296c7c0 Compare August 9, 2026 05:46
`sub-N:<base>` accepts `latest` and aliases as its base, but `version_sub()`
can only subtract from a concrete version. `ToolVersion::resolve_sub` resolves
the base first, which is why `mise use`/`mise install` handle `sub-2:lts`; two
other call sites did not.

`mise ls-remote node@sub-2:lts` passed the raw string through and panicked:

    called `Option::unwrap()` on a `None` value
    src/toolset/tool_request.rs:592

`mise latest node@sub-2:lts` had no `Sub` arm at all and bailed with
"invalid version" for every `sub-N:` spec, numeric base included.

Extracts the base resolution into `resolve_sub_base()` and routes all three
callers through it, and makes `version_sub()` return a `Result` so an
unresolved base can no longer abort the process.
@JamBalaya56562
JamBalaya56562 force-pushed the fix/sub-version-resolves-alias-base branch from 296c7c0 to 21b87bc Compare August 9, 2026 07:03
@JamBalaya56562
JamBalaya56562 marked this pull request as ready for review August 9, 2026 07:26
@greptile-apps

greptile-apps Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR centralizes resolution of sub-N: bases so latest and aliases are converted to concrete versions before subtraction.

  • Adds sub-N: handling to mise latest and fixes alias-based subtraction in mise ls-remote.
  • Makes version subtraction fallible instead of panicking on nonnumeric inputs.
  • Adds unit and end-to-end coverage for numeric, alias, and latest bases.

Confidence Score: 5/5

The PR appears safe to merge, with no concrete changed-code defect identified.

The shared resolver consistently converts aliases and latest to concrete versions before subtraction, while malformed nonnumeric values now return errors rather than panicking and the affected CLI paths have focused end-to-end coverage.

Important Files Changed

Filename Overview
src/toolset/tool_version.rs Extracts shared alias/latest base resolution while preserving the existing offline early return and cutoff behavior.
src/toolset/tool_request.rs Replaces panic-prone subtraction parsing with explicit errors and maps invalid local subtraction to no matching install.
src/cli/latest.rs Adds ToolRequest::Sub support and uses the shared resolver before selecting the latest matching version.
src/cli/ls_remote.rs Resolves symbolic subtraction bases before applying the remote-version prefix filter.
e2e/cli/test_latest Covers numeric, alias, literal-latest, and alias-to-latest subtraction bases.
e2e/cli/test_ls_remote Verifies alias and latest subtraction bases produce the expected filtered remote versions.

Reviews (1): Last reviewed commit: "fix(cli): resolve the base of `sub-N:` b..." | Re-trigger Greptile

@jdx
jdx merged commit b3ab626 into jdx:main Aug 9, 2026
30 checks passed
@JamBalaya56562
JamBalaya56562 deleted the fix/sub-version-resolves-alias-base branch August 9, 2026 15:05
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