From 0ca56386cc04dfd6791d64bd0c79cf022e60d5ed Mon Sep 17 00:00:00 2001 From: Jeff Dickey <216188+jdx@users.noreply.github.com> Date: Sat, 12 Oct 2024 14:00:00 -0500 Subject: [PATCH] fix: remove shims directory from PATH when executing shims A follow-up to #2735 which was missing some cases --- docs/dev-tools/backends/vfox.md | 3 +-- src/cli/exec.rs | 29 ++--------------------------- src/shims.rs | 26 +++++++++++++++++++++----- 3 files changed, 24 insertions(+), 34 deletions(-) diff --git a/docs/dev-tools/backends/vfox.md b/docs/dev-tools/backends/vfox.md index 3657a1755..8e0fafa35 100644 --- a/docs/dev-tools/backends/vfox.md +++ b/docs/dev-tools/backends/vfox.md @@ -3,8 +3,7 @@ [Vfox](https://github.com/version-fox/vfox) plugins may be used in mise as an alternative for asdf plugins. On Windows, only vfox plugins are supported since asdf plugins require POSIX compatibility. -The code for this is inside of the mise repository at [ -`./src/backend/vfox.rs`](https://github.com/jdx/mise/blob/main/src/backend/vfox.rs). +The code for this is inside of the mise repository at [`./src/backend/vfox.rs`](https://github.com/jdx/mise/blob/main/src/backend/vfox.rs). ## Dependencies diff --git a/src/cli/exec.rs b/src/cli/exec.rs index 6775e07ea..1ac4d4b7e 100644 --- a/src/cli/exec.rs +++ b/src/cli/exec.rs @@ -12,8 +12,8 @@ use crate::cli::args::ToolArg; #[cfg(any(test, windows))] use crate::cmd; use crate::config::Config; +use crate::env; use crate::toolset::{InstallOptions, ToolsetBuilder}; -use crate::{dirs, env}; /// Execute a command with tool(s) set /// @@ -68,11 +68,7 @@ impl Exec { ts.notify_if_versions_missing(); let (program, args) = parse_command(&env::SHELL, &self.command, &self.c); - let mut env = ts.env_with_path(&config)?; - - if let Some(path) = self.remove_shims_from_path(env.get(&*env::PATH_KEY)) { - env.insert(env::PATH_KEY.to_string(), path); - } + let env = ts.env_with_path(&config)?; self.exec(program, args, env) } @@ -134,27 +130,6 @@ impl Exec { None => Err(eyre!("command failed: terminated by signal")), } } - - // remove the shims dir when using `mise x` since the tools will already be on PATH and shims won't - // be needed. This is to avoid shims from being called in a loop. - fn remove_shims_from_path(&self, path: Option<&String>) -> Option { - if let Some(path) = path { - let paths = env::split_paths(path).filter(|p| { - p != *dirs::SHIMS - && !p - .canonicalize() - .is_ok_and(|p| p == dirs::SHIMS.canonicalize().unwrap_or_default()) - }); - Some( - env::join_paths(paths) - .unwrap() - .to_string_lossy() - .to_string(), - ) - } else { - None - } - } } fn parse_command( diff --git a/src/shims.rs b/src/shims.rs index 30527c950..f995d8d81 100644 --- a/src/shims.rs +++ b/src/shims.rs @@ -13,7 +13,8 @@ use rayon::prelude::*; use crate::backend::Backend; use crate::cli::exec::Exec; -use crate::config::{Config, Settings}; +use crate::config::settings::SETTINGS; +use crate::config::CONFIG; use crate::file::display_path; use crate::lock_file::LockFile; use crate::toolset::{ToolVersion, Toolset, ToolsetBuilder}; @@ -30,6 +31,7 @@ pub fn handle_shim() -> Result<()> { let args = env::ARGS.read().unwrap(); trace!("shim[{bin_name}] args: {}", args.join(" ")); let mut args: Vec = args.iter().map(OsString::from).collect(); + remove_shim_dir_from_path(); args[0] = which_shim(&env::MISE_BIN_NAME)?.into(); env::set_var("__MISE_SHIM", "1"); let exec = Exec { @@ -44,8 +46,7 @@ pub fn handle_shim() -> Result<()> { } fn which_shim(bin_name: &str) -> Result { - let config = Config::try_get()?; - let mut ts = ToolsetBuilder::new().build(&config)?; + let mut ts = ToolsetBuilder::new().build(&CONFIG)?; if let Some((p, tv)) = ts.which(bin_name) { if let Some(bin) = p.which(&tv, bin_name)? { trace!( @@ -55,8 +56,7 @@ fn which_shim(bin_name: &str) -> Result { return Ok(bin); } } - let settings = Settings::try_get()?; - if settings.not_found_auto_install { + if SETTINGS.not_found_auto_install { for tv in ts.install_missing_bin(bin_name)?.unwrap_or_default() { let p = tv.get_backend(); if let Some(bin) = p.which(&tv, bin_name)? { @@ -280,6 +280,22 @@ fn make_shim(target: &Path, shim: &Path) -> Result<()> { Ok(()) } +/// prevent shims from being called in a loop +fn remove_shim_dir_from_path() { + let path = env::var_os(&*env::PATH_KEY).unwrap_or_default(); + let paths = env::split_paths(&path).filter(|p| { + p != *dirs::SHIMS + && !p + .canonicalize() + .is_ok_and(|p| p == dirs::SHIMS.canonicalize().unwrap_or_default()) + }); + let path = env::join_paths(paths) + .unwrap() + .to_string_lossy() + .to_string(); + env::set_var(&*env::PATH_KEY, &path); +} + fn err_no_version_set(ts: Toolset, bin_name: &str, tvs: Vec) -> Result { if tvs.is_empty() { bail!("{} is not a valid shim", bin_name);