From 25a657ad517bd2d6c95d695384131ce0cca9692d Mon Sep 17 00:00:00 2001 From: jdx <216188+jdx@users.noreply.github.com> Date: Wed, 11 Dec 2024 15:29:57 -0600 Subject: [PATCH] fix: use config_root for env._.source Fixes #2335 --- src/backend/asdf.rs | 3 +- src/config/config_file/mod.rs | 81 +++++++++++++++++++++++++++++------ src/config/env_directive.rs | 11 ++--- src/config/mod.rs | 1 - src/env_diff.rs | 10 +++-- 5 files changed, 80 insertions(+), 26 deletions(-) diff --git a/src/backend/asdf.rs b/src/backend/asdf.rs index 2c519544c5..84f2de2929 100644 --- a/src/backend/asdf.rs +++ b/src/backend/asdf.rs @@ -142,7 +142,8 @@ impl AsdfBackend { sm.prepend_path(p); } let script = sm.get_script_path(&ExecEnv); - let ed = EnvDiff::from_bash_script(&script, &sm.env)?; + let dir = dirs::CWD.clone().unwrap_or_default(); + let ed = EnvDiff::from_bash_script(&script, &dir, &sm.env)?; let env = ed .to_patches() .into_iter() diff --git a/src/config/config_file/mod.rs b/src/config/config_file/mod.rs index d5d3ab6e28..1a43e82b74 100644 --- a/src/config/config_file/mod.rs +++ b/src/config/config_file/mod.rs @@ -12,13 +12,13 @@ use once_cell::sync::Lazy; use path_absolutize::Absolutize; use serde_derive::Deserialize; use versions::Versioning; - +use xx::regex; use tool_versions::ToolVersions; use crate::cli::args::{BackendArg, ToolArg}; use crate::config::config_file::mise_toml::MiseToml; use crate::config::env_directive::EnvDirective; -use crate::config::{settings, AliasMap, Settings, SETTINGS}; +use crate::config::{is_global_config, settings, AliasMap, Settings, SETTINGS}; use crate::errors::Error::UntrustedConfig; use crate::file::display_path; use crate::hash::hash_to_str; @@ -232,9 +232,9 @@ pub fn parse(path: &Path) -> Result> { } } -pub fn config_trust_root(path: &Path) -> PathBuf { - if settings::is_loaded() && SETTINGS.paranoid { - return path.to_path_buf(); +pub fn config_root(path: &Path) -> PathBuf { + if is_global_config(path) { + return env::HOME.to_path_buf(); } let path = path .absolutize() @@ -245,7 +245,7 @@ pub fn config_trust_root(path: &Path) -> PathBuf { .map(|c| c.as_os_str().to_string_lossy().to_string()) .collect::>(); const EMPTY: &str = ""; - // let filename = parts.last().map(|p| p.as_str()).unwrap_or(EMPTY); + let filename = parts.last().map(|p| p.as_str()).unwrap_or(EMPTY); let parent = parts .get(parts.len() - 2) .map(|p| p.as_str()) @@ -254,20 +254,44 @@ pub fn config_trust_root(path: &Path) -> PathBuf { .get(parts.len() - 3) .map(|p| p.as_str()) .unwrap_or(EMPTY); - let cur_path = || path.parent().unwrap().to_path_buf(); - let parent_path = || cur_path().parent().unwrap().to_path_buf(); + let great_grandparent = parts + .get(parts.len() - 4) + .map(|p| p.as_str()) + .unwrap_or(EMPTY); + let parent_path = || path.parent().unwrap().to_path_buf(); let grandparent_path = || parent_path().parent().unwrap().to_path_buf(); + let great_grandparent_path = || grandparent_path().parent().unwrap().to_path_buf(); + let great_great_grandparent_path = || great_grandparent_path().parent().unwrap().to_path_buf(); let is_mise_dir = |d: &str| d == "mise" || d == ".mise"; + let is_config_filename = |f: &str| { + f == "config.toml" + || f == "config.local.toml" + || regex!(r"config\..+\.toml").is_match(f) + }; if parent == "conf.d" && is_mise_dir(grandparent) { - grandparent_path() - } else if is_mise_dir(parent) { + if great_grandparent == ".config" { + great_great_grandparent_path() + } else { + great_grandparent_path() + } + } else if is_mise_dir(parent) && is_config_filename(filename) { if grandparent == ".config" { - grandparent_path() + great_grandparent_path() } else { - parent_path() + grandparent_path() } + } else if parent == ".config" { + grandparent_path() + } else { + parent_path() + } +} + +pub fn config_trust_root(path: &Path) -> PathBuf { + if settings::is_loaded() && SETTINGS.paranoid { + path.to_path_buf() } else { - cur_path() + config_root(path) } } @@ -544,4 +568,35 @@ mod tests { Some(ConfigFileType::MiseToml) ); } + + #[test] + fn test_config_root() { + for p in &[ + "/foo/bar/.config/mise/conf.d/config.toml", + "/foo/bar/.config/mise/conf.d/foo.toml", + "/foo/bar/.config/mise/config.local.toml", + "/foo/bar/.config/mise/config.toml", + "/foo/bar/.config/mise.local.toml", + "/foo/bar/.config/mise.toml", + "/foo/bar/.mise.env.toml", + "/foo/bar/.mise.local.toml", + "/foo/bar/.mise.toml", + "/foo/bar/.mise/conf.d/config.toml", + "/foo/bar/.mise/config.local.toml", + "/foo/bar/.mise/config.toml", + "/foo/bar/.tool-versions", + "/foo/bar/mise.env.toml", + "/foo/bar/mise.local.toml", + "/foo/bar/mise.toml", + "/foo/bar/mise/config.local.toml", + "/foo/bar/mise/config.toml", + "/foo/bar/.config/mise/config.env.toml", + "/foo/bar/.config/mise.env.toml", + "/foo/bar/.mise/config.env.toml", + "/foo/bar/.mise.env.toml", + ] { + println!("{}", p); + assert_eq!(config_root(Path::new(p)), PathBuf::from("/foo/bar")); + } + } } diff --git a/src/config/env_directive.rs b/src/config/env_directive.rs index 3675cab7a4..9a0d9babb1 100644 --- a/src/config/env_directive.rs +++ b/src/config/env_directive.rs @@ -9,7 +9,7 @@ use indexmap::IndexMap; use serde::{Deserialize, Deserializer}; use crate::cmd::CmdLineRunner; -use crate::config::config_file::trust_check; +use crate::config::config_file::{config_root, trust_check}; use crate::config::{Config, SETTINGS}; use crate::env::PATH_KEY; use crate::env_diff::{EnvDiff, EnvDiffOperation}; @@ -164,11 +164,7 @@ impl EnvResults { // &directive, // &source // ); - let config_root = source - .parent() - .map(Path::to_path_buf) - .or_else(|| dirs::CWD.clone()) - .unwrap_or_default(); + let config_root = config_root(&source); ctx.insert("cwd", &*dirs::CWD); ctx.insert("config_root", &config_root); let env_vars = env @@ -237,7 +233,8 @@ impl EnvResults { { r.env_scripts.push(p.clone()); let env_diff = - EnvDiff::from_bash_script(&p, env_vars.clone()).unwrap_or_default(); + EnvDiff::from_bash_script(&p, &config_root, env_vars.clone()) + .unwrap_or_default(); for p in env_diff.to_patches() { match p { EnvDiffOperation::Add(k, v) diff --git a/src/config/mod.rs b/src/config/mod.rs index eff369cdf5..184b504b08 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -682,7 +682,6 @@ static LOCAL_CONFIG_FILENAMES: Lazy> = Lazy::new(|| { ".config/mise.toml", ".mise/config.toml", "mise/config.toml", - ".mise/config.toml", ".rtx.toml", "mise.toml", &*env::MISE_DEFAULT_CONFIG_FILENAME, // mise.toml diff --git a/src/env_diff.rs b/src/env_diff.rs index 9a8c4f9726..8f97bbcb40 100644 --- a/src/env_diff.rs +++ b/src/env_diff.rs @@ -58,7 +58,7 @@ impl EnvDiff { diff } - pub fn from_bash_script(script: &Path, env: T) -> Result + pub fn from_bash_script(script: &Path, dir: &Path, env: T) -> Result where T: IntoIterator, U: Into, @@ -75,6 +75,7 @@ impl EnvDiff { export -p ", script = script.display()} ) + .dir(dir) .full_env(&env) .read()?; let env: HashMap = env @@ -246,12 +247,12 @@ fn normalize_escape_sequences(input: &str) -> String { #[cfg(test)] mod tests { + use super::*; + use insta::assert_debug_snapshot; use pretty_assertions::assert_str_eq; use test_log::test; - use super::*; - #[test] fn test_diff() { let diff = EnvDiff::new(&new_from_hashmap(), new_to_hashmap()); @@ -347,7 +348,8 @@ mod tests { .into_iter() .map(|(k, v)| (k.into(), v.into())) .collect::>(); - let ed = EnvDiff::from_bash_script(path.as_path(), orig).unwrap(); + let cwd = dirs::CWD.clone().unwrap(); + let ed = EnvDiff::from_bash_script(path.as_path(), &cwd, orig).unwrap(); assert_debug_snapshot!(ed); }