diff --git a/src/backend/mod.rs b/src/backend/mod.rs index 72fc1b766..c0a5aae0a 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -80,7 +80,8 @@ impl Display for BackendType { static TOOLS: Mutex> = Mutex::new(None); fn load_tools() -> BackendMap { - if let Some(backends) = TOOLS.lock().unwrap().as_ref() { + let mut memo_tools = TOOLS.lock().unwrap(); + if let Some(backends) = &*memo_tools { return backends.clone(); } time!("load_tools: start"); @@ -109,7 +110,7 @@ fn load_tools() -> BackendMap { .into_iter() .map(|plugin| (plugin.id().to_string(), plugin)) .collect(); - *TOOLS.lock().unwrap() = Some(tools.clone()); + *memo_tools = Some(tools.clone()); time!("load_tools done"); tools } @@ -351,19 +352,21 @@ pub trait Backend: Debug + Send + Sync { None } fn ensure_dependencies_installed(&self) -> eyre::Result<()> { - trace!("Ensuring dependencies installed for {}", self.id()); let deps = self .get_all_dependencies(&ToolRequest::System(self.id().into()))? .into_iter() .collect::>(); - let config = Config::get(); - let ts = config.get_tool_request_set()?.filter_by_tool(&deps); - if !ts.missing_tools().is_empty() { - bail!( - "Dependency {} not installed for {}", - deps.iter().map(|d| d.to_string()).join(", "), - self.id() - ); + if !deps.is_empty() { + trace!("Ensuring dependencies installed for {}", self.id()); + let config = Config::get(); + let ts = config.get_tool_request_set()?.filter_by_tool(&deps); + if !ts.missing_tools().is_empty() { + bail!( + "Dependency {} not installed for {}", + deps.iter().map(|d| d.to_string()).join(", "), + self.id() + ); + } } Ok(()) } diff --git a/src/cli/mod.rs b/src/cli/mod.rs index 88fd4bcb8..47b4c09e2 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -182,7 +182,6 @@ impl Commands { pub static CLI: Lazy = Lazy::new(|| { Commands::augment_subcommands( clap::Command::new("mise") - .version(version::VERSION.to_string()) .about(env!("CARGO_PKG_DESCRIPTION")) .author("Jeff Dickey <@jdx>") .long_about(LONG_ABOUT) @@ -196,7 +195,8 @@ pub static CLI: Lazy = Lazy::new(|| { .arg(args::QUIET_ARG.clone()) .arg(args::TRACE_ARG.clone()) .arg(args::VERBOSE_ARG.clone()) - .arg(args::YES_ARG.clone()), + .arg(args::YES_ARG.clone()) + .version(version::VERSION.to_string()), ) }); diff --git a/src/config/config_file/legacy_version.rs b/src/config/config_file/legacy_version.rs index 1454e9ff0..28269015b 100644 --- a/src/config/config_file/legacy_version.rs +++ b/src/config/config_file/legacy_version.rs @@ -7,7 +7,7 @@ use crate::cli::args::BackendArg; use crate::config::config_file::ConfigFile; use crate::toolset::{ToolRequest, ToolRequestSet, ToolSource}; -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct LegacyVersionFile { path: PathBuf, tools: ToolRequestSet, @@ -74,4 +74,8 @@ impl ConfigFile for LegacyVersionFile { fn to_tool_request_set(&self) -> Result { Ok(self.tools.clone()) } + + fn clone_box(&self) -> Box { + Box::new(self.clone()) + } } diff --git a/src/config/config_file/mise_toml.rs b/src/config/config_file/mise_toml.rs index ea7c6b239..8eaa73dd7 100644 --- a/src/config/config_file/mise_toml.rs +++ b/src/config/config_file/mise_toml.rs @@ -362,6 +362,10 @@ impl ConfigFile for MiseToml { fn task_config(&self) -> &TaskConfig { &self.task_config } + + fn clone_box(&self) -> Box { + Box::new(self.clone()) + } } impl Debug for MiseToml { diff --git a/src/config/config_file/mod.rs b/src/config/config_file/mod.rs index cdde18aea..9af7e1a7b 100644 --- a/src/config/config_file/mod.rs +++ b/src/config/config_file/mod.rs @@ -85,6 +85,7 @@ pub trait ConfigFile: Debug + Send + Sync { static DEFAULT_TASK_CONFIG: Lazy = Lazy::new(TaskConfig::default); &DEFAULT_TASK_CONFIG } + fn clone_box(&self) -> Box; } impl dyn ConfigFile { diff --git a/src/config/config_file/tool_versions.rs b/src/config/config_file/tool_versions.rs index 72f30678b..0df4930d3 100644 --- a/src/config/config_file/tool_versions.rs +++ b/src/config/config_file/tool_versions.rs @@ -20,7 +20,7 @@ use crate::toolset::{ToolRequest, ToolRequestSet, ToolSource}; // shfmt 3.6.0 /// represents asdf's .tool-versions file -#[derive(Debug, Default)] +#[derive(Debug, Default, Clone)] pub struct ToolVersions { context: Context, path: PathBuf, @@ -29,7 +29,7 @@ pub struct ToolVersions { tools: ToolRequestSet, } -#[derive(Debug)] +#[derive(Debug, Clone)] struct ToolVersionPlugin { orig_name: String, versions: Vec, @@ -201,6 +201,10 @@ impl ConfigFile for ToolVersions { fn to_tool_request_set(&self) -> eyre::Result { Ok(self.tools.clone()) } + + fn clone_box(&self) -> Box { + Box::new(self.clone()) + } } #[cfg(test)] diff --git a/src/config/mod.rs b/src/config/mod.rs index 1464732fd..e82d6e88b 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -626,7 +626,10 @@ pub fn load_config_paths(config_filenames: &[String]) -> Vec { config_files.extend(global_config_files()); config_files.extend(system_config_files()); - config_files.into_iter().unique().collect() + config_files + .into_iter() + .unique_by(|p| file::desymlink_path(p)) + .collect() } pub fn is_global_config(path: &Path) -> bool { diff --git a/src/config/settings.rs b/src/config/settings.rs index 96ccdf366..d8005c033 100644 --- a/src/config/settings.rs +++ b/src/config/settings.rs @@ -1,6 +1,6 @@ use crate::config::{system_config_files, DEFAULT_CONFIG_FILENAMES}; use crate::file::FindUp; -use crate::{config, dirs, env, file}; +use crate::{config, dirs, eager, env, file}; #[allow(unused_imports)] use confique::env::parse::{list_by_colon, list_by_comma}; use confique::{Config, Partial}; @@ -213,6 +213,9 @@ impl Settings { if let Some(cd) = m.get_one::("cd") { s.cd = Some(cd.clone()); } + if let Some(profile) = m.get_one::("profile") { + s.profile = Some(profile.clone()); + } if let Some(true) = m.get_one::("yes") { s.yes = Some(true); } @@ -265,6 +268,10 @@ impl Settings { fn parse_settings_file(path: &PathBuf) -> Result { let raw = file::read_to_string(path)?; let settings_file: SettingsFile = toml::from_str(&raw)?; + + // eagerly parse the file as a config file in the background for later + eager::CONFIG_FILES.lock().unwrap().push(path.clone()); + Ok(settings_file.settings) } diff --git a/src/eager.rs b/src/eager.rs index 060479890..b4b1ad5ef 100644 --- a/src/eager.rs +++ b/src/eager.rs @@ -1,20 +1,20 @@ -use xx::regex; +use crate::cli::version::VERSION; +use crate::plugins::VERSION_REGEX; +use once_cell::sync::Lazy; +use std::path::PathBuf; +use std::sync::Mutex; /// initializes slow parts of mise eagerly in the background pub fn early_init() { rayon::spawn(|| { - regex!(""); - }); // initialize regex library + let _ = &*VERSION_REGEX; + }); + rayon::spawn(|| { + let _ = &*VERSION; + }) } +pub static CONFIG_FILES: Lazy>> = Lazy::new(|| Mutex::new(Vec::new())); + /// run after SETTING has been loaded -pub fn post_settings() { - // if std::env::var("EAGER").is_err() { - // return; - // } - // rayon::spawn(|s| { - // s.spawn(|_| { - // // let _ = load_toolset(); - // }); - // }); -} +pub fn post_settings() {} diff --git a/src/file.rs b/src/file.rs index 61d2407f8..3838e2122 100644 --- a/src/file.rs +++ b/src/file.rs @@ -521,14 +521,17 @@ pub fn split_file_name(path: &Path) -> (String, String) { } pub fn same_file(a: &Path, b: &Path) -> bool { - let canonicalize = |p: &Path| p.canonicalize().unwrap_or_else(|_| p.to_path_buf()); - if canonicalize(a) == canonicalize(b) { - return true; - } - if let (Ok(a), Ok(b)) = (fs::read_link(a), fs::read_link(b)) { - return canonicalize(&a) == canonicalize(&b); + desymlink_path(a) == desymlink_path(b) +} + +pub fn desymlink_path(p: &Path) -> PathBuf { + if let Ok(target) = fs::read_link(p) { + target + .canonicalize() + .unwrap_or_else(|_| target.to_path_buf()) + } else { + p.canonicalize().unwrap_or_else(|_| p.to_path_buf()) } - false } #[cfg(test)]