diff --git a/src/csv/mod.rs b/src/csv/mod.rs index 2fa613e..a666430 100644 --- a/src/csv/mod.rs +++ b/src/csv/mod.rs @@ -519,7 +519,8 @@ pub(crate) fn compare_paths( }); let is_error = !results.is_empty(); let result = report::Difference { - file_path: nominal.as_ref().to_path_buf(), + nominal_file: nominal.as_ref().to_path_buf(), + actual_file: actual.as_ref().to_path_buf(), is_error, detail: results.into_iter().map(report::DiffDetail::CSV).collect(), }; diff --git a/src/external.rs b/src/external.rs index f3a2e05..23bb2b7 100644 --- a/src/external.rs +++ b/src/external.rs @@ -18,7 +18,7 @@ pub(crate) fn compare_files>( actual: P, config: &ExternalConfig, ) -> Result { - let mut diff = Difference::new_for_file(&nominal); + let mut diff = Difference::new_for_file(&nominal, &actual); let compared_file_name = nominal.as_ref().to_string_lossy().into_owned(); let output = std::process::Command::new(&config.executable) .args(&config.extra_params) diff --git a/src/hash.rs b/src/hash.rs index 8de94cf..c709205 100644 --- a/src/hash.rs +++ b/src/hash.rs @@ -71,7 +71,7 @@ pub fn compare_files>( .function .hash_file(fat_io_wrap_std(nominal_path.as_ref(), &File::open)?)?; - let mut difference = Difference::new_for_file(nominal_path); + let mut difference = Difference::new_for_file(nominal_path, actual_path); if act != nom { difference.push_detail(DiffDetail::Hash { actual: HEXLOWER.encode(&act), diff --git a/src/html.rs b/src/html.rs index 9666a69..67d2336 100644 --- a/src/html.rs +++ b/src/html.rs @@ -64,7 +64,7 @@ pub fn compare_files>( let nominal = BufReader::new(fat_io_wrap_std(nominal_path.as_ref(), &File::open)?); let exclusion_list = config.get_ignore_list()?; - let mut difference = Difference::new_for_file(nominal_path); + let mut difference = Difference::new_for_file(nominal_path, actual_path); actual .lines() .enumerate() diff --git a/src/image.rs b/src/image.rs index b8c9fd8..8fa5671 100644 --- a/src/image.rs +++ b/src/image.rs @@ -53,7 +53,7 @@ pub fn compare_paths>( nominal_path.as_ref() )))?; let out_path = (nominal_file_name + "diff_image.png").to_string(); - let mut result_diff = report::Difference::new_for_file(&nominal_path); + let mut result_diff = report::Difference::new_for_file(&nominal_path, &actual_path); if result.score < config.threshold { let color_map = result.image.to_color_map(); diff --git a/src/lib.rs b/src/lib.rs index 787593b..0ab0681 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -201,7 +201,7 @@ fn process_file(nominal: impl AsRef, actual: impl AsRef, rule: &Rule Err(e) => { let e = e.to_string(); error!("Problem comparing the files {}", &e); - let mut d = Difference::new_for_file(nominal); + let mut d = Difference::new_for_file(nominal, actual); d.error(); d.push_detail(DiffDetail::Error(e)); d diff --git a/src/pdf.rs b/src/pdf.rs index d5e840e..cce7f44 100644 --- a/src/pdf.rs +++ b/src/pdf.rs @@ -33,7 +33,7 @@ pub fn compare_files>( let nominal = extract_text(nominal_path.as_ref())?; let exclusion_list = config.get_ignore_list()?; - let mut difference = Difference::new_for_file(&nominal); + let mut difference = Difference::new_for_file(&nominal_path, &actual_path); actual .lines() .enumerate() diff --git a/src/properties.rs b/src/properties.rs index 94817d5..4aabbe8 100644 --- a/src/properties.rs +++ b/src/properties.rs @@ -38,7 +38,7 @@ fn regex_matches_any_path( let regex = Regex::new(regex)?; if regex.is_match(nominal_path) || regex.is_match(actual_path) { error!("One of the files ({nominal_path}, {actual_path}) matched the regex {regex}"); - let mut result = Difference::new_for_file(nominal_path); + let mut result = Difference::new_for_file(nominal_path, actual_path); result.error(); result.push_detail(DiffDetail::Properties(MetaDataPropertyDiff::IllegalName)); result.is_error = true; @@ -48,7 +48,7 @@ fn regex_matches_any_path( } fn file_size_out_of_tolerance(nominal: &Path, actual: &Path, tolerance: u64) -> Difference { - let mut result = Difference::new_for_file(nominal); + let mut result = Difference::new_for_file(nominal, actual); if let (Ok(nominal_meta), Ok(actual_meta)) = (nominal.metadata(), actual.metadata()) { let size_diff = (nominal_meta.len() as i128 - actual_meta.len() as i128).unsigned_abs() as u64; @@ -78,7 +78,7 @@ fn file_modification_time_out_of_tolerance( actual: &Path, tolerance: u64, ) -> Difference { - let mut result = Difference::new_for_file(nominal); + let mut result = Difference::new_for_file(nominal, actual); if let (Ok(nominal_meta), Ok(actual_meta)) = (nominal.metadata(), actual.metadata()) { if let (Ok(mod_time_act), Ok(mod_time_nom)) = (nominal_meta.modified(), actual_meta.modified()) @@ -142,7 +142,7 @@ pub(crate) fn compare_files>( .to_string_lossy() .to_string(); - let mut total_diff = Difference::new_for_file(nominal); + let mut total_diff = Difference::new_for_file(nominal, actual); let result = if let Some(name_regex) = config.forbid_name_regex.as_deref() { regex_matches_any_path(&compared_file_name_full, &actual_file_name_full, name_regex)? } else { diff --git a/src/report/mod.rs b/src/report/mod.rs index af22890..ffd1471 100644 --- a/src/report/mod.rs +++ b/src/report/mod.rs @@ -30,7 +30,7 @@ pub enum Error { #[error("fs_extra crate error {0}")] FsExtraFailed(#[from] fs_extra::error::Error), #[error("JSON serialization failed {0}")] - SerdeError(#[from] serde_json::Error), + Serde(#[from] serde_json::Error), } #[derive(Serialize, Debug)] @@ -89,15 +89,17 @@ pub struct RuleDifferences { #[derive(Serialize, Debug, Clone, Default)] pub struct Difference { - pub file_path: PathBuf, + pub nominal_file: PathBuf, + pub actual_file: PathBuf, pub is_error: bool, pub detail: Vec, } impl Difference { - pub fn new_for_file(f: impl AsRef) -> Self { + pub fn new_for_file(nominal: impl AsRef, actual: impl AsRef) -> Self { Self { - file_path: f.as_ref().to_path_buf(), + nominal_file: nominal.as_ref().to_path_buf(), + actual_file: actual.as_ref().to_path_buf(), ..Default::default() } } @@ -111,7 +113,7 @@ impl Difference { } pub fn join(&mut self, other: Self) -> bool { - if self.file_path != other.file_path { + if self.nominal_file != other.nominal_file { return false; } self.is_error |= other.is_error; @@ -132,12 +134,6 @@ pub enum DiffDetail { Error(String), } -impl From for DiffDetail { - fn from(value: T) -> Self { - DiffDetail::Error(value.to_string()) - } -} - pub fn create_sub_folder() -> Result { let temp_path = tempfile::Builder::new() .prefix("havocompare-") @@ -605,6 +601,33 @@ pub(crate) fn create_json( Ok(()) } +pub(crate) fn create_html( + rule_results: &[RuleDifferences], + report_path: impl AsRef, +) -> Result<(), Error> { + let _reporting_span = span!(tracing::Level::INFO, "JSON Reporting"); + let _reporting_span = _reporting_span.enter(); + let report_dir = report_path.as_ref(); + if report_dir.is_dir() { + info!("Delete report folder"); + fat_io_wrap_std(&report_dir, &fs::remove_dir_all)?; + } + + info!("create report folder"); + fat_io_wrap_std(&report_dir, &fs::create_dir)?; + + for rule_result in rule_results.iter() { + let sub_folder = report_dir.join(&rule_result.rule.name); + debug!("Create subfolder {:?}", &sub_folder); + fat_io_wrap_std(&sub_folder, &fs::create_dir)?; + for file in rule_result.diffs.iter() { + // for + } + } + + Ok(()) +} + pub(crate) fn create( rule_results: &[RuleResult], report_path: impl AsRef,