use crate::compress::generic::GenericCompressor;
use crate::compress::Compressor;
pub struct PnpmCompressor;
impl Compressor for PnpmCompressor {
fn matches(&self, command: &str) -> bool {
command
.split_whitespace()
.next()
.is_some_and(|head| head == "pnpm")
}
fn compress(&self, command: &str, output: &str) -> String {
match pnpm_subcommand(command).as_deref() {
Some("install" | "i" | "add" | "remove") => compress_package(output),
Some("run" | "test" | "build") => GenericCompressor::compress_output(output),
_ => GenericCompressor::compress_output(output),
}
}
}
fn pnpm_subcommand(command: &str) -> Option<String> {
command
.split_whitespace()
.skip_while(|token| *token != "pnpm")
.skip(1)
.find(|token| !token.starts_with('-'))
.map(ToString::to_string)
}
fn compress_package(output: &str) -> String {
let mut result = Vec::new();
let mut progress_seen = 0usize;
let mut up_to_date_seen = false;
for line in output.lines() {
let trimmed = line.trim_start();
if trimmed.starts_with("Progress: resolved ") {
progress_seen += 1;
if progress_seen > 2 {
continue;
}
}
if trimmed == "Already up-to-date" {
if up_to_date_seen {
continue;
}
up_to_date_seen = true;
}
if trimmed.contains("WARN GET_NO_AUTH")
|| trimmed.starts_with("ERR_PNPM_")
|| trimmed.starts_with("Progress: resolved ")
|| trimmed == "Already up-to-date"
|| trimmed.starts_with("dependencies:")
|| trimmed.starts_with("devDependencies:")
|| trimmed.starts_with("Done in ")
{
result.push(line.to_string());
}
}
trim_trailing_lines(&result.join("\n"))
}
fn trim_trailing_lines(input: &str) -> String {
input
.lines()
.map(str::trim_end)
.collect::<Vec<_>>()
.join("\n")
}