use forge::signal::compactor;
use once_cell::sync::Lazy;
use regex::Regex;
static PROGRESS_RE: Lazy<Regex> = Lazy::new(|| {
Regex::new(r"(?m)^(Downloading|Extracting|Installing|Verifying|Reshimming|Running) [^\n]+\n?")
.unwrap()
});
pub fn compress_mise(subcmd: &str, raw: &str) -> String {
let sub = subcmd.trim();
match sub {
"install" | "i" => compress_install(raw),
"use" | "u" => compress_use(raw),
"run" | "exec" | "x" => compactor::normalise(raw), "ls" | "list" | "current" | "latest" | "outdated" => compactor::normalise(raw),
_ => compress_install(raw),
}
}
fn compress_install(raw: &str) -> String {
let cleaned = compactor::normalise(raw);
let s = PROGRESS_RE.replace_all(&cleaned, "");
let kept: Vec<&str> = s
.lines()
.filter(|l| {
let t = l.trim();
t.is_empty()
|| t.starts_with("mise")
|| t.contains("installed")
|| t.contains("already installed")
|| t.contains("error")
|| t.contains("failed")
})
.collect();
let out = compactor::collapse_blanks(&kept.join("\n"));
if out.trim().is_empty() {
"(mise install: completed)".to_string()
} else {
out
}
}
fn compress_use(raw: &str) -> String {
let cleaned = compactor::normalise(raw);
let s = PROGRESS_RE.replace_all(&cleaned, "");
let kept: Vec<&str> = s
.lines()
.filter(|l| {
let t = l.trim();
t.is_empty()
|| t.starts_with("mise")
|| t.contains(".mise.toml")
|| t.contains("set ")
|| t.contains("error")
})
.collect();
compactor::collapse_blanks(&kept.join("\n"))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn install_strips_download_progress() {
let raw = "Downloading node 20.0.0...\nExtracting node 20.0.0...\nInstalling node 20.0.0...\nmise node@20.0.0 installed\n";
let out = compress_mise("install", raw);
assert!(!out.contains("Downloading"), "{out}");
assert!(out.contains("installed") || out.contains("node"), "{out}");
}
#[test]
fn run_is_passthrough() {
let raw = "hello from task\ndone\n";
let out = compress_mise("run", raw);
assert!(out.contains("hello"), "{out}");
}
#[test]
fn use_keeps_config_update() {
let raw = "Reshimming mise...\nmise: set node@20.0.0 in .mise.toml\n";
let out = compress_mise("use", raw);
assert!(!out.contains("Reshimming"), "{out}");
assert!(out.contains(".mise.toml") || out.contains("set"), "{out}");
}
}