use anyhow::anyhow;
use clap::Parser;
use havocompare::{compare_files, compare_folders, get_schema, validate_config, ComparisonMode};
use std::path::{Path, PathBuf};
use tracing::{info, Level};
use tracing_subscriber::FmtSubscriber;
const DEFAULT_REPORT_FOLDER: &str = "report";
#[derive(clap::Subcommand)]
enum Commands {
Compare {
nominal: String,
actual: String,
compare_config: String,
#[arg(short, long = "report_path", default_value_t = DEFAULT_REPORT_FOLDER.to_string())]
report_config: String,
#[arg(short, long)]
open: bool,
},
FileCompare {
nominal: PathBuf,
actual: PathBuf,
config: String,
},
Schema,
Validate { compare_config: String },
}
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
struct Arguments {
#[clap(short, long)]
verbose: bool,
#[clap(subcommand)]
command: Commands,
}
fn main() -> Result<(), vg_errortools::MainError> {
let args = Arguments::parse();
let level = if args.verbose {
Level::DEBUG
} else {
Level::INFO
};
let _ = enable_ansi_support::enable_ansi_support();
let subscriber = FmtSubscriber::builder().with_max_level(level).finish();
tracing::subscriber::set_global_default(subscriber).expect("setting default subscriber failed");
match args.command {
Commands::Schema => {
println!(
"{}",
get_schema().expect("Error occurred writing json schema")
);
Ok(())
}
Commands::Compare {
compare_config,
nominal,
actual,
report_config,
open,
} => {
let report_path = Path::new(report_config.as_str());
let result = compare_folders(nominal, actual, compare_config, report_path)?;
if open {
info!("Opening report");
opener::open(report_path.join("index.html")).expect("Could not open report!");
}
if result {
Ok(())
} else {
Err(anyhow!("Comparison failed!").into())
}
}
Commands::FileCompare {
nominal,
actual,
config,
} => {
use anyhow::Context;
let config: ComparisonMode =
serde_json::from_str(&config).context("Couldn't deserialize the config string")?;
let result = compare_files(nominal, actual, &config);
info!("Diff results: {result:#?}");
if result.is_error {
Err(anyhow!("Comparison failed!").into())
} else {
Ok(())
}
}
Commands::Validate { compare_config } => {
if validate_config(compare_config) {
Ok(())
} else {
Err(anyhow!("Validation failed!").into())
}
}
}
}