diff --git a/src/cli/prune.rs b/src/cli/prune.rs index b89d0e073..dafc861d1 100644 --- a/src/cli/prune.rs +++ b/src/cli/prune.rs @@ -5,12 +5,15 @@ use console::style; use eyre::Result; use crate::cli::args::ForgeArg; +use crate::config::tracking::Tracker; use crate::config::{Config, Settings}; use crate::forge::Forge; use crate::toolset::{ToolVersion, ToolsetBuilder}; use crate::ui::multi_progress_report::MultiProgressReport; use crate::ui::prompt; +use super::trust::Trust; + /// Delete unused versions of tools /// /// mise tracks which config files have been used in ~/.local/share/mise/tracked_config_files @@ -27,10 +30,39 @@ pub struct Prune { /// Do not actually delete anything #[clap(long, short = 'n')] pub dry_run: bool, + + /// Prune only tracked and trusted configuration links that point to non-existent configurations + #[clap(long)] + pub configs: bool, + + /// Prune only unused versions of tools + #[clap(long)] + pub tools: bool, } impl Prune { pub fn run(self) -> Result<()> { + if self.configs || !self.tools { + self.prune_configs()?; + } + if self.tools || !self.configs { + self.prune_tools()?; + } + Ok(()) + } + + fn prune_configs(&self) -> Result<()> { + if self.dry_run { + info!("pruned configuration links {}", style("[dryrun]").bold()); + } else { + Tracker::clean()?; + Trust::clean()?; + info!("pruned configuration links"); + } + Ok(()) + } + + fn prune_tools(&self) -> Result<()> { let config = Config::try_get()?; let ts = ToolsetBuilder::new().build(&config)?; let mut to_delete = ts diff --git a/src/cli/trust.rs b/src/cli/trust.rs index 48795ae17..9af937ab2 100644 --- a/src/cli/trust.rs +++ b/src/cli/trust.rs @@ -1,3 +1,4 @@ +use std::fs::read_dir; use std::path::PathBuf; use clap::ValueHint; @@ -5,6 +6,8 @@ use eyre::Result; use crate::config; use crate::config::{config_file, DEFAULT_CONFIG_FILENAMES}; +use crate::dirs::TRUSTED_CONFIGS; +use crate::file::remove_file; /// Marks a config file as trusted /// @@ -44,6 +47,17 @@ impl Trust { self.trust() } } + pub fn clean() -> Result<()> { + if TRUSTED_CONFIGS.is_dir() { + for path in read_dir(&*TRUSTED_CONFIGS)? { + let path = path?.path(); + if !path.exists() { + remove_file(&path)?; + } + } + } + Ok(()) + } fn untrust(&self) -> Result<()> { let path = match &self.config_file { Some(filename) => PathBuf::from(filename), diff --git a/src/config/mod.rs b/src/config/mod.rs index e8b449828..9a45a020f 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -29,7 +29,7 @@ use crate::{dirs, env, file, forge}; pub mod config_file; mod env_directive; pub mod settings; -mod tracking; +pub mod tracking; type AliasMap = BTreeMap>; type ConfigMap = IndexMap>; diff --git a/src/config/tracking.rs b/src/config/tracking.rs index 32f70b1fe..5b53b8fda 100644 --- a/src/config/tracking.rs +++ b/src/config/tracking.rs @@ -21,7 +21,6 @@ impl Tracker { } pub fn list_all() -> Result> { - Self::clean()?; let mut output = vec![]; for path in read_dir(&*TRACKED_CONFIGS)? { let path = path?.path(); @@ -37,10 +36,12 @@ impl Tracker { } pub fn clean() -> Result<()> { - for path in read_dir(&*TRACKED_CONFIGS)? { - let path = path?.path(); - if !path.exists() { - remove_file(&path)?; + if TRACKED_CONFIGS.is_dir() { + for path in read_dir(&*TRACKED_CONFIGS)? { + let path = path?.path(); + if !path.exists() { + remove_file(&path)?; + } } } Ok(())