Skip to content

fix(activate): don't reorder PATH for the mise dir in --shims mode#10394

Merged
jdx merged 1 commit into
jdx:mainfrom
JamBalaya56562:fix-activate-shims-exe-dir-path
Jun 13, 2026
Merged

fix(activate): don't reorder PATH for the mise dir in --shims mode#10394
jdx merged 1 commit into
jdx:mainfrom
JamBalaya56562:fix-activate-shims-exe-dir-path

Conversation

@JamBalaya56562

@JamBalaya56562 JamBalaya56562 commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Problem

On a deb/rpm install (mise at /usr/bin/mise), mise activate bash --shims emits:

export PATH="/usr/bin:$PATH"
export PATH="/home/viktor/.local/share/mise/shims:$PATH"

The first line duplicates /usr/bin and moves it ahead of /usr/local/bin, changing command resolution — locally/admin-installed binaries in /usr/local/bin no longer take precedence. Reported in #10264.

Root cause

activate_shims() prepends both the shims dir and the directory containing the mise executable. PR #8757 made --shims activation always prepend (dropping the "already in PATH" guard) so the shims dir reliably moves to the front when shell config is re-sourced (e.g. VS Code terminals). But activate_shims() routes both the shims dir and the mise exe dir through that same unconditional helper, so the exe dir lost the guard too. For a deb install the exe dir is /usr/bin, which is already in PATH — so it gets re-prepended and reordered.

Fix

Keep always-prepending the shims dir (preserving #8757''s re-source behavior), but emit the mise executable''s own dir through the guarded prepend_path, which skips directories already in PATH. The exe dir only needs to be present so mise is callable — never at the front.

For a deb install, activation now emits only:

export PATH="$HOME/.local/share/mise/shims:$PATH"

and never reorders existing PATH entries.

Testing

  • Extended e2e/shell/test_shims_activate_prepend: when the mise executable''s dir is already in PATH, exactly one export PATH= line (the shims dir) is emitted — the exe dir is not re-prepended. The existing assertions (shims dir is always prepended, with or without it already in PATH) still hold.
  • cargo fmt --all -- --check passes.

Addresses #10264

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Prevented shim activation from reordering PATH when the tool's install directory is already present, avoiding redundant PATH modifications.
  • Tests

    • Added a regression test to confirm activation emits a single PATH export and does not re-prepend an existing install directory.

@coderabbitai

coderabbitai Bot commented Jun 13, 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: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 0f950f3c-53c4-4130-abbe-0161ca94259f

📥 Commits

Reviewing files that changed from the base of the PR and between efbe835 and 5498a86.

📒 Files selected for processing (2)
  • e2e/shell/test_shims_activate_prepend
  • src/cli/activate.rs
🚧 Files skipped from review as they are similar to previous changes (2)
  • e2e/shell/test_shims_activate_prepend
  • src/cli/activate.rs

📝 Walkthrough

Walkthrough

Switches shims activation to use guarded prepend_path(exe_dir) (avoiding re-prepend/reorder of an already-present exe_dir) and adds an e2e test verifying activation emits a single PATH export that begins with SHIMS_DIR when exe_dir is already in PATH.

Changes

Executable Directory Prepend Fix

Layer / File(s) Summary
Guarded prepend logic for executable directory
src/cli/activate.rs
activate_shims now calls prepend_path(exe_dir) instead of shims_prepend_path(shell, exe_dir), so exe_dir is only emitted when allowed by guards; doc comment for shims_prepend_path updated to clarify shim-specific behavior.
Regression test for executable directory prepend
e2e/shell/test_shims_activate_prepend
Adds a test that sets PATH including EXE_DIR, runs mise activate bash --shims, asserts the exported PATH begins with SHIMS_DIR, and verifies exactly one export PATH= line is produced.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

A rabbit hops through PATH so fleet,
It checks the trail with nimble feet,
If exe is found, it will not shove—
Shims lead the dance, one path above. 🐰

🚥 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 directly and clearly summarizes the main fix: preventing PATH reordering for the mise directory in --shims mode, which is the core change across both modified files.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

@greptile-apps

greptile-apps Bot commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a PATH reordering bug in --shims activation mode where the directory containing the mise binary (e.g. /usr/bin on deb/rpm installs) was unconditionally prepended to PATH on every re-source, moving it ahead of entries like /usr/local/bin. The fix routes the mise executable's directory through the guarded prepend_path() (which skips directories already present in PATH) while keeping the shims directory on the unconditional shims_prepend_path() path so it reliably stays at the front on re-source.

  • src/cli/activate.rs: activate_shims() now calls self.prepend_path(exe_dir) instead of self.shims_prepend_path(shell, exe_dir), adding an is_dir_in_path guard for the executable directory without affecting the shims dir behaviour.
  • e2e/shell/test_shims_activate_prepend: Adds a regression test that pre-populates PATH with EXE_DIR and asserts only one export PATH= line (the shims dir) is emitted.

Confidence Score: 5/5

Safe to merge — the change is a one-line switch to an already-present guarded helper with a targeted regression test covering the fixed scenario.

The diff is minimal: one call-site change in activate_shims() and a new e2e test case. The guarded prepend_path() it switches to was already used by the non-shims activate() path and is well understood. The regression test directly exercises the fixed case and correctly uses the existing assert_contains_text harness helper. No logic around the shims directory itself is touched.

No files require special attention.

Important Files Changed

Filename Overview
src/cli/activate.rs Switches activate_shims() to use the guarded prepend_path() for exe_dir instead of the always-prepend shims_prepend_path(); the shims dir keeps its unconditional prepend via shims_prepend_path(). Change is minimal and correctly scoped.
e2e/shell/test_shims_activate_prepend Adds a regression test that sets PATH to include EXE_DIR before activation, then asserts exactly one export PATH= line is emitted (the shims dir); correctly uses the existing assert_contains_text helper.

Reviews (2): Last reviewed commit: "fix(activate): don't reorder PATH for th..." | Re-trigger Greptile

Comment thread src/cli/activate.rs
Comment on lines +112 to 114
if let Some(p) = self.prepend_path(exe_dir) {
prelude.push(p);
}

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.

P2 Fish: exe_dir switches from MovePrependEnv to PrependEnv

Before this PR, activate_shims() called shims_prepend_path(shell, exe_dir), which emitted MovePrependEnv for fish (using fish's native path dedup so re-sourcing is idempotent). The new prepend_path(exe_dir) always emits PrependEnv regardless of shell. For fish users where exe_dir is not already in PATH (e.g. a custom ~/.local/bin install), re-sourcing the config after a system-level rc resets PATH could duplicate exe_dir, because PrependEnv is not natively idempotent under fish. The guard !is_dir_in_path makes this safe for the common re-source case, but it breaks in the "PATH reset between sources" scenario that MovePrependEnv handles natively. Consider emitting MovePrependEnv(exe_dir) when shell.supports_move_path() is true, falling back to the guarded PrependEnv otherwise.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks, but I don''t think this one applies here. On fish, PrependEnv renders as fish_add_path --global --path (src/shell/fish.rs), and fish_add_path is idempotent — it won''t add a path that''s already present, so re-sourcing (even after a PATH reset) doesn''t duplicate exe_dir. The only behavioural difference vs MovePrependEnv (fish_add_path --move) is whether an already-present entry gets moved to the front.

Moving it is exactly what this PR is fixing: for a deb install exe_dir is /usr/bin, which is already in PATH, so MovePrependEnv would move /usr/bin ahead of /usr/local/bin — reintroducing #10264 on fish. The guarded prepend_path leaves an already-present exe_dir untouched on every shell (and fish_add_path --path adds it idempotently when it is genuinely missing), matching what the non-shims activate() path already does for exe_dir. So I''m keeping prepend_path here.

@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 `@e2e/shell/test_shims_activate_prepend`:
- Around line 23-29: The test currently masks failures by appending "|| true" to
the activation command that sets out, so replace that pattern: run the
activation command capturing its stdout/stderr into out (keep env
PATH="$EXE_DIR:..." "$MISE_BIN" activate bash --shims 2>&1), then immediately
check the command's exit status and fail the test if it's non-zero (print out
the captured out for diagnostics and exit non‑zero) before continuing with
assert_contains_text and the path_lines checks; this removes the "|| true"
suppression while preserving captured output for assertions.
🪄 Autofix (Beta)

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: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 4d9745a8-d5bf-4ba3-989b-458787537dae

📥 Commits

Reviewing files that changed from the base of the PR and between e420ad4 and 46296bd.

📒 Files selected for processing (2)
  • e2e/shell/test_shims_activate_prepend
  • src/cli/activate.rs

Comment thread e2e/shell/test_shims_activate_prepend Outdated
@JamBalaya56562 JamBalaya56562 force-pushed the fix-activate-shims-exe-dir-path branch from 46296bd to efbe835 Compare June 13, 2026 13:37
`mise activate <shell> --shims` prepended both the shims dir and the directory
containing the mise executable unconditionally (PR jdx#8757 dropped the
"already in PATH" guard so the shims dir reliably moves to the front on
re-source). For a deb/rpm install the mise binary lives at /usr/bin, so activation
emitted `export PATH="/usr/bin:$PATH"`, duplicating /usr/bin and moving it ahead
of /usr/local/bin -- changing command resolution (jdx#10264).

Keep always-prepending the shims dir (preserving jdx#8757's re-source behavior), but
emit the mise executable's own dir through the guarded prepend_path, which skips
dirs already in PATH. The exe dir only needs to be present so `mise` is callable,
never at the front. For a deb install, activation now emits only the shims line.

Addresses discussion jdx#10264.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@JamBalaya56562 JamBalaya56562 force-pushed the fix-activate-shims-exe-dir-path branch from efbe835 to 5498a86 Compare June 13, 2026 13:38
@jdx jdx merged commit 556074a into jdx:main Jun 13, 2026
33 checks passed
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