use clap::{Args, ValueEnum};
use rumdl_lib::exit_codes::exit;
use rumdl_lib::unused_assets::{AssetScanOptions, scan};
use std::path::PathBuf;
#[derive(Debug, Clone, Copy, Default, ValueEnum)]
pub enum AssetOutput {
#[default]
Text,
Json,
}
#[derive(Debug, Args)]
pub struct CheckAssetsArgs {
#[arg(long, value_name = "DIR")]
pub root: PathBuf,
#[arg(long, required = true, value_name = "DIR")]
pub source: Vec<PathBuf>,
#[arg(long, required = true, value_name = "DIR")]
pub assets: Vec<PathBuf>,
#[arg(long, value_name = "GLOB")]
pub include: Vec<String>,
#[arg(long, value_name = "GLOB")]
pub keep: Vec<String>,
#[arg(long, value_enum, default_value_t)]
pub output_format: AssetOutput,
}
pub fn handle(args: CheckAssetsArgs) {
let report = match scan(&AssetScanOptions {
root: args.root,
sources: args.source,
assets: args.assets,
include: args.include,
keep: args.keep,
}) {
Ok(report) => report,
Err(e) => {
eprintln!("error: asset scan incomplete: {e}");
exit::tool_error();
}
};
match args.output_format {
AssetOutput::Json => println!(
"{}",
serde_json::to_string_pretty(&report).expect("serializable asset report")
),
AssetOutput::Text => {
for path in &report.unreferenced {
println!("{path}: unreferenced in scanned Markdown sources");
}
for path in &report.mentioned_but_unresolved {
println!("{path}: mentioned but unresolved (kept)");
}
println!(
"Scanned {} sources ({}), {} assets; {} unreferenced, {} mentioned but unresolved.",
report.sources_scanned,
report.source_extensions.join(", "),
report.assets_considered,
report.unreferenced.len(),
report.mentioned_but_unresolved.len()
);
}
}
if !report.unreferenced.is_empty() {
exit::violations_found();
}
}