cargo cleanup tool (plugin)
This commit is contained in:
+118
@@ -0,0 +1,118 @@
|
||||
use std::{
|
||||
path::{Path, PathBuf},
|
||||
process::Command,
|
||||
};
|
||||
|
||||
use anyhow::Result;
|
||||
use walkdir::WalkDir;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Slimmer {
|
||||
pub dry_run: bool,
|
||||
}
|
||||
|
||||
pub struct Report {
|
||||
pub output: String,
|
||||
}
|
||||
|
||||
impl Slimmer {
|
||||
#[must_use]
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
pub fn cleanup(&self, path: impl AsRef<Path>) -> Result<Report> {
|
||||
let mut output = String::new();
|
||||
for target in manifests(path)? {
|
||||
let mut command = self.cargo_clean_cmd(&target);
|
||||
let cmd_output = command.output()?;
|
||||
output.push_str(&summary(target, &cmd_output));
|
||||
}
|
||||
Ok(Report { output })
|
||||
}
|
||||
|
||||
fn cargo_clean_cmd(&self, target: &PathBuf) -> Command {
|
||||
let mut command = Command::new("cargo");
|
||||
command.arg("clean");
|
||||
command.arg("--manifest-path");
|
||||
command.arg(target);
|
||||
|
||||
if self.dry_run {
|
||||
command.arg("--dry-run");
|
||||
}
|
||||
|
||||
command
|
||||
}
|
||||
}
|
||||
|
||||
fn summary(target: impl AsRef<Path>, cmd_output: &std::process::Output) -> String {
|
||||
format!(
|
||||
"{}: {}",
|
||||
target.as_ref().parent().unwrap().display(),
|
||||
String::from_utf8_lossy(&cmd_output.stderr).trim_start()
|
||||
)
|
||||
}
|
||||
|
||||
fn manifests(path: impl AsRef<Path>) -> Result<Vec<PathBuf>> {
|
||||
let mut targets: Vec<PathBuf> = Vec::new();
|
||||
let tmp = WalkDir::new(path)
|
||||
.into_iter()
|
||||
.filter_entry(|e| !e.path().ends_with("target/package"));
|
||||
for entry in tmp {
|
||||
let entry = entry?;
|
||||
if entry.file_name() == "Cargo.toml" {
|
||||
targets.push(entry.into_path());
|
||||
}
|
||||
}
|
||||
|
||||
Ok(targets)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::process::{ExitStatus, Output};
|
||||
|
||||
use super::*;
|
||||
#[test]
|
||||
fn manifestes_returns_toml_paths() {
|
||||
let mut manifest = manifests("tests/data").unwrap();
|
||||
manifest.sort();
|
||||
assert_eq!(
|
||||
manifest,
|
||||
vec![
|
||||
PathBuf::from("tests/data/proj_1/Cargo.toml"),
|
||||
PathBuf::from("tests/data/proj_2/Cargo.toml"),
|
||||
PathBuf::from("tests/data/proj_3/Cargo.toml"),
|
||||
],
|
||||
"wrong path",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cargo_clean_cmd_returns_correct_command() {
|
||||
let slimmer = Slimmer::new();
|
||||
let cmd = slimmer.cargo_clean_cmd(&PathBuf::from("tests/data/proj_1/Cargo.toml"));
|
||||
assert_eq!(cmd.get_program(), "cargo", "wrong program");
|
||||
assert_eq!(
|
||||
cmd.get_args().collect::<Vec<_>>(),
|
||||
["clean", "--manifest-path", "tests/data/proj_1/Cargo.toml"],
|
||||
"wrong args"
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn summary_returns_correct_string() {
|
||||
let cmd_output = summary(
|
||||
PathBuf::from("./target/Cargo.toml"),
|
||||
&Output {
|
||||
stdout: Vec::new(),
|
||||
stderr: String::from(" Removed 2 files, 1.6MiB total\n").into_bytes(),
|
||||
status: ExitStatus::default(),
|
||||
},
|
||||
);
|
||||
assert_eq!(
|
||||
cmd_output, "./target: Removed 2 files, 1.6MiB total\n",
|
||||
"wrong formatting"
|
||||
);
|
||||
}
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
use anyhow::Result;
|
||||
use clap::Parser;
|
||||
use cleanup::{Slimmer};
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
#[command(bin_name = "cargo")]
|
||||
enum CargoCommand {
|
||||
Slim(Args),
|
||||
}
|
||||
|
||||
#[derive(clap::Args, Debug)]
|
||||
/// Runs `cargo clean` recursively to save disk space by deleting build
|
||||
/// artifacts.
|
||||
struct Args {
|
||||
#[arg(default_value = ".")]
|
||||
paths: Vec<String>,
|
||||
#[arg(long)]
|
||||
dry_run: bool,
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let CargoCommand::Slim(args) = CargoCommand::parse();
|
||||
let mut slimmer = Slimmer::new();
|
||||
|
||||
if args.dry_run {
|
||||
slimmer.dry_run = true;
|
||||
}
|
||||
|
||||
for path in &args.paths {
|
||||
let output = slimmer.cleanup(path)?;
|
||||
println!("{}", output.output);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user