use std::{fs, path::Path};
use clap::ArgEnum;
use displaydoc::Display;
use crate::fs::dir_size;
pub mod cargo;
pub mod elm;
pub mod flutter;
pub mod gradle;
pub mod maven;
pub mod mix;
pub mod npm;
#[derive(Debug, Display, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ArgEnum)]
pub enum BuildToolKind {
Cargo,
Rust,
Rs,
Elm,
Flutter,
Gradle,
Maven,
Mvn,
Mix,
Elixir,
Ex,
Exs,
Npm,
}
pub trait BuildToolProbe: std::fmt::Debug {
fn probe(&self, dir: &Path) -> Option<Box<dyn BuildTool>>;
fn applies_to(&self, kind: BuildToolKind) -> bool;
}
pub trait BuildTool: std::fmt::Debug + std::fmt::Display {
fn clean_project(&mut self, dry_run: bool) -> anyhow::Result<()>;
fn status(&self) -> anyhow::Result<BuildStatus> {
Ok(BuildStatus::Unknown)
}
fn project_name(&self) -> Option<anyhow::Result<String>> {
None
}
}
#[derive(Debug, Clone, Copy)]
pub enum BuildStatus {
Clean,
Built { freeable_bytes: u64 },
Unknown,
}
fn remove_dirs(project_dir: &Path, ephemeral_dirs: &[&str], dry_run: bool) -> anyhow::Result<()> {
for dir in ephemeral_dirs
.iter()
.map(|dirname| project_dir.join(dirname))
.filter(|dir| dir.is_dir())
{
if dry_run {
println!("rm -r '{}'", dir.display());
} else {
fs::remove_dir_all(dir)?;
}
}
Ok(())
}
fn status_from_dirs(project_dir: &Path, ephemeral_dirs: &[&str]) -> anyhow::Result<BuildStatus> {
let size: u64 = ephemeral_dirs
.iter()
.map(|dirname| project_dir.join(dirname))
.filter(|dir| dir.is_dir())
.map(|dir| dir_size(&dir))
.sum();
let status = match size {
0 => BuildStatus::Clean,
freeable_bytes => BuildStatus::Built { freeable_bytes },
};
Ok(status)
}