Skip to content

Commit 2c16bda

Browse files
committed
fix(lock): report stale version pruning in dry-run for filtered runs
Add dry-run reporting for stale version entries that would be pruned during filtered `mise lock <tool>` runs. Previously, `--dry-run` only reported stale tool pruning for unfiltered runs, silently omitting the version-level pruning that filtered runs perform. Also report version pruning in the non-dry-run path for consistency. jdx#8599 (comment)
1 parent a56583b commit 2c16bda

File tree

2 files changed

+78
-1
lines changed

2 files changed

+78
-1
lines changed

src/cli/lock.rs

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,18 +120,23 @@ impl Lock {
120120

121121
if self.dry_run {
122122
self.show_dry_run(&tools, &target_platforms)?;
123+
let lockfile = Lockfile::read(lockfile_path)?;
123124
if self.is_unfiltered_lock_run() {
124-
let lockfile = Lockfile::read(lockfile_path)?;
125125
let stale_tools = self.stale_entries_if_pruned(&lockfile, &tools);
126126
self.show_stale_prune_message(lockfile_path, &stale_tools, true)?;
127+
} else {
128+
let stale_versions = self.stale_versions_if_pruned(&lockfile, &tools);
129+
self.show_stale_version_prune_message(lockfile_path, &stale_versions, true)?;
127130
}
128131
continue;
129132
}
130133

131134
// Process tools and update lockfile
132135
let mut lockfile = Lockfile::read(lockfile_path)?;
133136
self.prune_stale_entries_if_needed(&mut lockfile, &tools);
137+
let stale_versions = self.stale_versions_if_pruned(&lockfile, &tools);
134138
self.prune_stale_versions_for_targeted_tools(&mut lockfile, &tools);
139+
self.show_stale_version_prune_message(lockfile_path, &stale_versions, false)?;
135140
let results = self
136141
.process_tools(&settings, &tools, &target_platforms, &mut lockfile)
137142
.await?;
@@ -214,6 +219,60 @@ impl Lock {
214219
self.stale_entries_for_selectors(lockfile, &configured_tools, &configured_backends)
215220
}
216221

222+
fn stale_versions_if_pruned(
223+
&self,
224+
lockfile: &Lockfile,
225+
tools: &[LockTool],
226+
) -> BTreeMap<String, Vec<String>> {
227+
let mut stale: BTreeMap<String, Vec<String>> = BTreeMap::new();
228+
let mut current_versions: BTreeMap<String, BTreeSet<String>> = BTreeMap::new();
229+
for (ba, tv) in tools {
230+
current_versions
231+
.entry(ba.short.clone())
232+
.or_default()
233+
.insert(tv.version.clone());
234+
}
235+
for (short, versions) in &current_versions {
236+
let stale_versions = lockfile.stale_tool_versions(short, versions);
237+
if !stale_versions.is_empty() {
238+
stale.insert(short.clone(), stale_versions);
239+
}
240+
}
241+
stale
242+
}
243+
244+
fn show_stale_version_prune_message(
245+
&self,
246+
lockfile_path: &Path,
247+
stale_versions: &BTreeMap<String, Vec<String>>,
248+
dry_run: bool,
249+
) -> Result<()> {
250+
if stale_versions.is_empty() {
251+
return Ok(());
252+
}
253+
let total: usize = stale_versions.values().map(|v| v.len()).sum();
254+
let entry_word = if total == 1 { "entry" } else { "entries" };
255+
let (icon, message) = if dry_run {
256+
(style("→").yellow(), "Dry run - would prune")
257+
} else {
258+
(style("✓").green(), "Pruned")
259+
};
260+
let details: Vec<String> = stale_versions
261+
.iter()
262+
.flat_map(|(short, versions)| versions.iter().map(move |v| format!("{short}@{v}")))
263+
.collect();
264+
miseprintln!(
265+
"{} {} {} stale version {} from {}: {}",
266+
icon,
267+
message,
268+
total,
269+
entry_word,
270+
style(display_path(lockfile_path)).cyan(),
271+
details.join(", ")
272+
);
273+
Ok(())
274+
}
275+
217276
fn configured_tool_selectors(
218277
&self,
219278
tools: &[(crate::cli::args::BackendArg, crate::toolset::ToolVersion)],

src/lockfile.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -634,6 +634,24 @@ impl Lockfile {
634634
self.cleanup_unreferenced_conda_packages();
635635
}
636636

637+
/// Return versions of a tool that would be removed by `retain_tool_versions`.
638+
pub fn stale_tool_versions(
639+
&self,
640+
short: &str,
641+
keep_versions: &BTreeSet<String>,
642+
) -> Vec<String> {
643+
self.tools
644+
.get(short)
645+
.map(|tools| {
646+
tools
647+
.iter()
648+
.filter(|t| !keep_versions.contains(&t.version))
649+
.map(|t| t.version.clone())
650+
.collect()
651+
})
652+
.unwrap_or_default()
653+
}
654+
637655
/// Return tool keys that would be removed by `retain_tools_by_short_or_backend`.
638656
pub fn stale_tool_shorts(
639657
&self,

0 commit comments

Comments
 (0)