diff --git a/CHANGELOG.md b/CHANGELOG.md index 2aa6229d..92f9364a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,10 @@ ## Unreleased +#### 🚀 Updates + +- Updated parallel tool loading to only loads tools that have a configured version, instead of loading all tools that proto is aware of (like built-in tools). Should see better performance for commands that require loading multiple tools. + #### ⚙️ Internal - Updated Rust to v1.84. diff --git a/crates/cli/src/commands/activate.rs b/crates/cli/src/commands/activate.rs index 7d5f06d6..1efaf27b 100644 --- a/crates/cli/src/commands/activate.rs +++ b/crates/cli/src/commands/activate.rs @@ -7,7 +7,6 @@ use serde::Serialize; use starbase::AppResult; use starbase_shell::{Hook, ShellType, Statement}; use starbase_utils::json; -use std::collections::HashSet; use std::env; use std::path::{Path, PathBuf}; use tokio::task::JoinSet; @@ -82,9 +81,7 @@ pub async fn activate(session: ProtoSession, args: ActivateArgs) -> AppResult { let config = session.env.load_config()?; // Load necessary tools so that we can extract info - let tools = session - .load_tools_with_filters(HashSet::from_iter(config.versions.keys())) - .await?; + let tools = session.load_tools().await?; let mut info = ActivateInfo::default(); let mut set = JoinSet::>::new(); diff --git a/crates/cli/src/commands/install.rs b/crates/cli/src/commands/install.rs index acafaaf2..58839674 100644 --- a/crates/cli/src/commands/install.rs +++ b/crates/cli/src/commands/install.rs @@ -177,7 +177,8 @@ pub async fn install_one(session: ProtoSession, args: InstallArgs, id: Id) -> Ap async fn install_all(session: ProtoSession, args: InstallArgs) -> AppResult { debug!("Loading all tools"); - let tools = session.load_tools().await?; + // We need all tools so we can attempt to detect a version + let tools = session.load_all_tools().await?; debug!("Detecting tool versions to install"); diff --git a/crates/cli/src/commands/plugin/list.rs b/crates/cli/src/commands/plugin/list.rs index d9f73ff0..97eb2122 100644 --- a/crates/cli/src/commands/plugin/list.rs +++ b/crates/cli/src/commands/plugin/list.rs @@ -36,7 +36,13 @@ pub async fn list(session: ProtoSession, args: ListPluginsArgs) -> AppResult { let mut tools = session .load_tools_with_options(LoadToolOptions { - ids: FxHashSet::from_iter(args.ids.clone()), + ids: FxHashSet::from_iter(if args.ids.is_empty() { + // Use plugins instead of versions since we want to + // list all plugins currently in use, even built-ins + global_config.plugins.keys().cloned().collect::>() + } else { + args.ids.clone() + }), inherit_local: true, inherit_remote: true, ..Default::default() diff --git a/crates/cli/src/commands/status.rs b/crates/cli/src/commands/status.rs index 3c986d4e..77bb899b 100644 --- a/crates/cli/src/commands/status.rs +++ b/crates/cli/src/commands/status.rs @@ -73,7 +73,8 @@ async fn find_versions_from_ecosystem( ) -> AppResult { let mut set = JoinSet::new(); - for tool in session.load_tools().await? { + // We need all tools so we can attempt to detect a version + for tool in session.load_all_tools().await? { let env = Arc::clone(&session.env); set.spawn(async move { diff --git a/crates/cli/src/session.rs b/crates/cli/src/session.rs index 58bcc7ce..84d631bb 100644 --- a/crates/cli/src/session.rs +++ b/crates/cli/src/session.rs @@ -131,10 +131,18 @@ impl ProtoSession { #[tracing::instrument(name = "load_tools", skip(self))] pub async fn load_tools_with_options( &self, - options: LoadToolOptions, + mut options: LoadToolOptions, ) -> miette::Result> { let config = self.env.load_config()?; + // If no filter IDs provided, inherit the IDs from the current + // config for every tool that has a version. Otherwise, we'll + // load all tools, even built-ins, when the user isn't using them. + // This causes quite a performance hit. + if options.ids.is_empty() { + options.ids.extend(config.versions.keys().cloned()); + } + // Download the schema plugin before loading plugins. // We must do this here, otherwise when multiple schema // based tools are installed in parallel, they will @@ -183,6 +191,16 @@ impl ProtoSession { Ok(records) } + pub async fn load_all_tools(&self) -> miette::Result> { + let config = self.load_config()?; + + let mut set = FxHashSet::default(); + set.extend(config.versions.keys().collect::>()); + set.extend(config.plugins.keys().collect::>()); + + self.load_tools_with_filters(set).await + } + pub async fn load_proto_tool(&self) -> miette::Result { load_tool_from_locator( Id::new(PROTO_PLUGIN_KEY)?,