Skip to content

Commit

Permalink
fix: remove shims directory in mise activate (#3232)
Browse files Browse the repository at this point in the history
* fix: remove shims directory in `mise activate`

Fixes #3230

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
  • Loading branch information
jdx and autofix-ci[bot] authored Nov 27, 2024
1 parent a530e44 commit 7de1111
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 8 deletions.
17 changes: 12 additions & 5 deletions docs/dev-tools/shims.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,26 +46,33 @@ If you prefer to use shims, you can run the following to use mise without activa

You can use `.bashrc`/`.zshrc` instead of `.bash_profile`/`.zprofile` if you prefer to only use
mise in interactive sessions (`.bash_profile`/`.zprofile` will work in non-interactive places
like scripts or IDEs).
like scripts or IDEs). Note that `mise activate` will remove the shims directory so it's fine
to call `mise activate --shims` in the profile file then later call `mise activate` in an interactive
session.

::: code-group

```sh [bash]
# note that bash will read from ~/.profile or ~/.bash_profile if the latter exists
# ergo, you may want to check to see which is defined on your system and only append to the existing file
echo 'export PATH="$HOME/.local/share/mise/shims:$PATH"' >> ~/.bash_profile
echo 'eval "$(mise activate bash --shims)"' >> ~/.bash_profile # this sets up non-interactive sessions
echo 'eval "$(mise activate bash)"' >> ~/.bashrc # this sets up interactive sessions
```

```sh [zsh]
echo 'export PATH="$HOME/.local/share/mise/shims:$PATH"' >> ~/.zprofile
echo 'eval "$(mise activate zsh --shims)"' >> ~/.zprofile # this sets up non-interactive sessions
echo 'eval "$(mise activate zsh)"' >> ~/.zshrc # this sets up interactive sessions
```

```sh [fish]
fish_add_path ~/.local/share/mise/shims
echo 'mise activate fish --shims | source' >> ~/.config/fish/config.fish
echo 'mise activate fish | source' >> ~/.config/fish/fish.config
```

:::tip
You can also run `mise activate --shims` which will do the above for you.
You can also run `export PATH="$HOME/.local/share/mise/shims:$PATH"` which is what `mise activate --shims` does.
This can be helpful is mise may not be available at that point in time. It's also a tiny bit faster,
but since this is only run once per shell session it's not a big deal.
:::

## Shims vs PATH
Expand Down
23 changes: 21 additions & 2 deletions src/cli/activate.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use std::path::{Path, PathBuf};

use eyre::Result;

use crate::env::PATH_KEY;
use crate::file::touch_dir;
use crate::path_env::PathEnv;
use crate::shell::{get_shell, Shell, ShellType};
use crate::{dirs, env};
use eyre::Result;
use itertools::Itertools;

/// Initializes mise in the current shell session
///
Expand Down Expand Up @@ -94,6 +95,7 @@ impl Activate {
}
miseprint!("{}", self.prepend_path(shell, exe_dir))?;
miseprint!("{}", shell.activate(mise_bin, flags.join("")))?;
remove_shims(shell)?;
Ok(())
}

Expand All @@ -106,6 +108,23 @@ impl Activate {
}
}

fn remove_shims(shell: &dyn Shell) -> std::io::Result<()> {
let shims = dirs::SHIMS
.canonicalize()
.unwrap_or(dirs::SHIMS.to_path_buf());
if env::PATH
.iter()
.filter_map(|p| p.canonicalize().ok())
.contains(&shims)
{
let path_env = PathEnv::from_iter(env::PATH.clone());
// PathEnv automatically removes the shims directory
let cmd = shell.set_env(&PATH_KEY, path_env.join().to_string_lossy().as_ref());
miseprintln!("{cmd}");
}
Ok(())
}

fn is_dir_in_path(dir: &Path) -> bool {
let dir = dir.canonicalize().unwrap_or(dir.to_path_buf());
env::PATH
Expand Down
2 changes: 1 addition & 1 deletion src/shims.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ fn make_shim(target: &Path, shim: &Path) -> Result<()> {

fn err_no_version_set(ts: Toolset, bin_name: &str, tvs: Vec<ToolVersion>) -> Result<PathBuf> {
if tvs.is_empty() {
bail!("{} is not a valid shim", bin_name);
bail!("{bin_name} is not a valid shim. This likely means you uninstalled a tool and the shim does not point to anything. Run `mise use <TOOL>` to reinstall the tool.");
}
let missing_plugins = tvs.iter().map(|tv| tv.ba()).collect::<HashSet<_>>();
let mut missing_tools = ts
Expand Down

0 comments on commit 7de1111

Please sign in to comment.