From d4a6c1132d78eae2508252309dfc7039827cd765 Mon Sep 17 00:00:00 2001 From: Ayrton Chilibeck Date: Fri, 12 Jan 2024 22:56:38 -0700 Subject: [PATCH 01/19] Added Stubs --- src/main.rs | 3 +-- src/validate.rs | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/main.rs b/src/main.rs index d3e298f..dfeffe3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,8 +16,7 @@ fn main() { let threads = get_threads(cli.threads); let config = util::config::parse_config(cli.config_file); - //parse the config file - // let config = parse_config(cli.config_file); + assert!(threads > 0); match &cli.command { Command::Validate => validate::validate(verbosity, config), diff --git a/src/validate.rs b/src/validate.rs index fb88886..c8f4ecb 100644 --- a/src/validate.rs +++ b/src/validate.rs @@ -1,7 +1,27 @@ +use std::{path::PathBuf, fs}; + use crate::util; pub fn validate(verbosity: u8, config: util::config::Config) { println!("Validating"); + + // get list of all file names in input/output + let in_files: Vec; + let out_files: Vec; + + // check if they end in .in or .out respectively + + // make sure each has a match +} + +fn get_dir_files(path: PathBuf) -> Result, &'static str> {} + +fn check_suffix(path: PathBuf, suf: String) -> bool { + return +} + +fn check_match(path1: PathBuf, path2: PathBuf, in_suf: String, out_suf: String) -> bool { + } From 4561caa6cfec7eb3bef4369d57860af4f960fe31 Mon Sep 17 00:00:00 2001 From: Ayrton Chilibeck Date: Fri, 12 Jan 2024 22:57:11 -0700 Subject: [PATCH 02/19] Implemented the get_dir_files function --- src/validate.rs | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/validate.rs b/src/validate.rs index c8f4ecb..231868e 100644 --- a/src/validate.rs +++ b/src/validate.rs @@ -14,7 +14,27 @@ pub fn validate(verbosity: u8, config: util::config::Config) { // make sure each has a match } -fn get_dir_files(path: PathBuf) -> Result, &'static str> {} +fn get_dir_files(path: PathBuf) -> Result, &'static str> { + let mut res: Vec; + + // get the readout of the path for error handling + let entries = match fs::read_dir(path) { + Ok(x) => x, + Err(error) => return Err("Failed to read from the given directory"), + }; + + for entry in entries { + let p = entry.expect("Bad element: validate::get_dir_files(..)"); + if p.path().is_dir() { + (); + } else { + res.push(p.path()); + } + } + + return Ok(res); +} + fn check_suffix(path: PathBuf, suf: String) -> bool { return From 3693ff16683e864814d138675e99d3a8f5f747bc Mon Sep 17 00:00:00 2001 From: Ayrton Chilibeck Date: Fri, 12 Jan 2024 23:01:28 -0700 Subject: [PATCH 03/19] Fixed README to include threading --- README.md | 4 ++-- src/validate.rs | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 680488e..b72023f 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ This is a (mostly) drop-in replacement for the previous tester written for CMPUT 415. Most of the options are specified in the [config file](#configuration-file), so the cli is minimal. We do specify some options: -``` rust +``` Usage: tester [OPTIONS] --config-file Commands: @@ -14,11 +14,11 @@ Commands: Options: -v, --verbosity... Sets the verbosity of the tester + -t, --threads Set the number of threads (only valid in run and grade mode) -c, --config-file Set the config file -g, --grading-conf Set the grading config file -h, --help Print help -V, --version Print version - ``` the verbosity defines the level of logging, you can play around with it (specify `-v[v]+` for more verbose logging). diff --git a/src/validate.rs b/src/validate.rs index 231868e..9b90c42 100644 --- a/src/validate.rs +++ b/src/validate.rs @@ -15,12 +15,12 @@ pub fn validate(verbosity: u8, config: util::config::Config) { } fn get_dir_files(path: PathBuf) -> Result, &'static str> { - let mut res: Vec; + let mut res: Vec = vec![]; // get the readout of the path for error handling let entries = match fs::read_dir(path) { Ok(x) => x, - Err(error) => return Err("Failed to read from the given directory"), + Err(..) => return Err("Failed to read from the given directory"), }; for entry in entries { @@ -37,11 +37,11 @@ fn get_dir_files(path: PathBuf) -> Result, &'static str> { fn check_suffix(path: PathBuf, suf: String) -> bool { - return + return false; } fn check_match(path1: PathBuf, path2: PathBuf, in_suf: String, out_suf: String) -> bool { - + return false; } From eaca213f2610075bff8fa9434169363cefbd7734 Mon Sep 17 00:00:00 2001 From: Ayrton Chilibeck Date: Fri, 12 Jan 2024 23:09:55 -0700 Subject: [PATCH 04/19] Pub-ed the Config fields --- src/util/config.rs | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/util/config.rs b/src/util/config.rs index 1aa5457..c47742b 100644 --- a/src/util/config.rs +++ b/src/util/config.rs @@ -5,39 +5,39 @@ use serde_yaml::{self}; #[derive(Debug, Deserialize)] pub struct Config { - tested_executables: Vec, + pub tested_executables: Vec, - input_path: PathBuf, - output_path: PathBuf, - in_stream_path: PathBuf, + pub input_path: PathBuf, + pub output_path: PathBuf, + pub in_stream_path: PathBuf, - runtimes: Option>, + pub runtimes: Option>, - toolchains: Vec, + pub toolchains: Vec, } #[derive(Debug, Deserialize)] pub struct Team { - name: String, - executable: PathBuf, + pub name: String, + pub executable: PathBuf, } #[derive(Debug, Deserialize)] pub struct Toolchain { - name: String, - steps: Vec,} + pub name: String, + pub steps: Vec,} #[derive(Debug, Deserialize)] pub struct Step { - name: String, + pub name: String, - executable_path: Option, // if None then we use the current executable path - arguments: Vec, // special string $INPUT corresponds to previous step output - output: String, // the output file name + pub executable_path: Option, // if None then we use the current executable path + pub arguments: Vec, // special string $INPUT corresponds to previous step output + pub output: String, // the output file name - uses_runtime: Option, - uses_in_stream: Option, - allow_error: Option + pub uses_runtime: Option, + pub uses_in_stream: Option, + pub allow_error: Option } pub fn parse_config(path: PathBuf) -> Config { From 8d4b5b3f1ce4076283e237130807985424a8ccf9 Mon Sep 17 00:00:00 2001 From: Ayrton Chilibeck Date: Fri, 12 Jan 2024 23:58:58 -0700 Subject: [PATCH 05/19] Initial implementation of the Validate function Added stubs and general flow, some rust stuff to figure out --- src/validate.rs | 67 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 61 insertions(+), 6 deletions(-) diff --git a/src/validate.rs b/src/validate.rs index 9b90c42..a9d3192 100644 --- a/src/validate.rs +++ b/src/validate.rs @@ -5,11 +5,37 @@ use crate::util; pub fn validate(verbosity: u8, config: util::config::Config) { println!("Validating"); + let in_suffix = "in"; //TODO make this configurable? + let out_suffix = "out"; // get list of all file names in input/output - let in_files: Vec; - let out_files: Vec; + let in_files: Vec = get_dir_files(config.input_path).expect("Failed to read the input directory contents"); + let out_files: Vec = get_dir_files(config.output_path).expect("Failed to read the output directory contents"); + + let mismatch: Vec<(PathBuf, PathBuf)>; + let mut invalid_suffix_in: Vec = vec![]; + let mut invalid_suffix_out: Vec = vec![]; // check if they end in .in or .out respectively + for file in in_files { + if !file.ends_with(in_suffix) { + invalid_suffix_in.push(file); + } + } + + for file in out_files { + if !file.ends_with(out_suffix) { + invalid_suffix_out.push(file); + } + } + + // print the delinquints + if invalid_suffix_in.len() > 0 { + print_invalid_suffixes(invalid_suffix_in, String::from(in_suffix)); + } + + if invalid_suffix_out.len() > 0 { + print_invalid_suffixes(invalid_suffix_out, String::from(out_suffix)); + } // make sure each has a match } @@ -35,15 +61,44 @@ fn get_dir_files(path: PathBuf) -> Result, &'static str> { return Ok(res); } +fn compare_files(in_files: Vec, out_files: Vec) -> Vec { + let mut res: Vec = vec![]; -fn check_suffix(path: PathBuf, suf: String) -> bool { - return false; + res.append(&mut compare_list(in_files, out_files)); + res.append(&mut compare_list(out_files, in_files)); + + return res; } -fn check_match(path1: PathBuf, path2: PathBuf, in_suf: String, out_suf: String) -> bool { - return false; +fn compare_list(from: Vec, against: Vec) -> Vec { + let res: Vec = vec![]; + + // Compare each input file to each output file + for file in from { + let beg = file.file_stem().unwrap(); // ignore suffix + for out in against { + if beg == out.file_stem().unwrap() { + break; + } + } + res.push(file); // if the file does not have a counterpart, then push to the lost files + } + + return res; } +fn print_invalid_suffixes(files: Vec, exp: String) { + println!("Invalid suffixes detected 😱:" ); + println!("Current => Suggested"); + for mut file in files { + let initial = match file.to_str() { + Some(x) => x, + _ => panic!("Failed to load the file"), + }; + + println!("{} => {}", initial, file.set_extension(exp).to_string()); + } +} #[cfg(test)] mod tests { From c798b44f45e8e559066e6d9daf397bff8039e3a4 Mon Sep 17 00:00:00 2001 From: Ayrton Chilibeck Date: Sat, 13 Jan 2024 23:24:29 -0700 Subject: [PATCH 06/19] Implemented a function to collect invalid suffixes --- src/validate.rs | 68 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 48 insertions(+), 20 deletions(-) diff --git a/src/validate.rs b/src/validate.rs index a9d3192..9cb7356 100644 --- a/src/validate.rs +++ b/src/validate.rs @@ -12,21 +12,10 @@ pub fn validate(verbosity: u8, config: util::config::Config) { let out_files: Vec = get_dir_files(config.output_path).expect("Failed to read the output directory contents"); let mismatch: Vec<(PathBuf, PathBuf)>; - let mut invalid_suffix_in: Vec = vec![]; - let mut invalid_suffix_out: Vec = vec![]; - // check if they end in .in or .out respectively - for file in in_files { - if !file.ends_with(in_suffix) { - invalid_suffix_in.push(file); - } - } - - for file in out_files { - if !file.ends_with(out_suffix) { - invalid_suffix_out.push(file); - } - } + // check the files for valid suffixes + let invalid_suffix_in: Vec = collect_invalid(&in_files, in_suffix); + let invalid_suffix_out: Vec = collect_invalid(&out_files, out_suffix); // print the delinquints if invalid_suffix_in.len() > 0 { @@ -40,6 +29,19 @@ pub fn validate(verbosity: u8, config: util::config::Config) { // make sure each has a match } +fn collect_invalid(files: &Vec, suf: &str) -> Vec { + let mut res: Vec = vec![]; + + for file in files { + let extension = file.extension().expect("Invalid file name for validation"); + if extension.to_str() != Some(suf) { + res.push(file.clone()); + } + } + + return res +} + fn get_dir_files(path: PathBuf) -> Result, &'static str> { let mut res: Vec = vec![]; @@ -64,14 +66,14 @@ fn get_dir_files(path: PathBuf) -> Result, &'static str> { fn compare_files(in_files: Vec, out_files: Vec) -> Vec { let mut res: Vec = vec![]; - res.append(&mut compare_list(in_files, out_files)); - res.append(&mut compare_list(out_files, in_files)); + res.append(&mut compare_list(&in_files, &out_files)); + res.append(&mut compare_list(&out_files, &in_files)); return res; } -fn compare_list(from: Vec, against: Vec) -> Vec { - let res: Vec = vec![]; +fn compare_list(from: &Vec, against: &Vec) -> Vec { + let mut res: Vec = vec![]; // Compare each input file to each output file for file in from { @@ -81,7 +83,7 @@ fn compare_list(from: Vec, against: Vec) -> Vec { break; } } - res.push(file); // if the file does not have a counterpart, then push to the lost files + res.push(file.clone()); // if the file does not have a counterpart, then push to the lost files } return res; @@ -96,11 +98,37 @@ fn print_invalid_suffixes(files: Vec, exp: String) { _ => panic!("Failed to load the file"), }; - println!("{} => {}", initial, file.set_extension(exp).to_string()); + println!("{} => {}", initial, file.clone().set_extension(&exp).to_string()); } } #[cfg(test)] mod tests { + use super::*; + #[test] + fn test_collect_invalid() { + let suffix = "suf"; + let valid_path1 = PathBuf::from("path/file.suf"); + let valid_path2 = PathBuf::from("path/file_stupid.suf"); + let valid_path3 = PathBuf::from("path/file/dead.suf"); + let invalid_path1 = PathBuf::from("path/file.sub"); + let invalid_path2 = PathBuf::from("path/file_stupid.sur"); + let invalid_path3 = PathBuf::from("path/file.bub"); + + let files: Vec = vec![valid_path1.clone(), valid_path2.clone(), valid_path3.clone(), + invalid_path1.clone(), invalid_path2.clone(), invalid_path3.clone()]; + + let invalid = collect_invalid(&files, suffix); + + println!("{:?}", invalid); + + assert!(invalid.contains(&invalid_path1)); + assert!(invalid.contains(&invalid_path2)); + assert!(invalid.contains(&invalid_path3)); + + assert!(!invalid.contains(&valid_path1)); + assert!(!invalid.contains(&valid_path2)); + assert!(!invalid.contains(&valid_path3)); + } } From c142ccc4dc6dc8b44cd00be65758117c25f19786 Mon Sep 17 00:00:00 2001 From: Ayrton Chilibeck Date: Sun, 14 Jan 2024 11:58:14 -0700 Subject: [PATCH 07/19] Fixecd printing implementation for invalid suffix --- src/validate.rs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/validate.rs b/src/validate.rs index 9cb7356..dcddc5d 100644 --- a/src/validate.rs +++ b/src/validate.rs @@ -19,11 +19,11 @@ pub fn validate(verbosity: u8, config: util::config::Config) { // print the delinquints if invalid_suffix_in.len() > 0 { - print_invalid_suffixes(invalid_suffix_in, String::from(in_suffix)); + print_invalid_suffixes(invalid_suffix_in, in_suffix); } if invalid_suffix_out.len() > 0 { - print_invalid_suffixes(invalid_suffix_out, String::from(out_suffix)); + print_invalid_suffixes(invalid_suffix_out, out_suffix); } // make sure each has a match @@ -89,7 +89,7 @@ fn compare_list(from: &Vec, against: &Vec) -> Vec { return res; } -fn print_invalid_suffixes(files: Vec, exp: String) { +fn print_invalid_suffixes(files: Vec, exp: &str) { println!("Invalid suffixes detected 😱:" ); println!("Current => Suggested"); for mut file in files { @@ -98,7 +98,11 @@ fn print_invalid_suffixes(files: Vec, exp: String) { _ => panic!("Failed to load the file"), }; - println!("{} => {}", initial, file.clone().set_extension(&exp).to_string()); + println!("{} => {}.{}", + initial.to_string(), + file.file_stem().expect("failed to extract") + .to_str().expect("failed to transform"), + exp); } } @@ -122,6 +126,7 @@ mod tests { let invalid = collect_invalid(&files, suffix); println!("{:?}", invalid); + print_invalid_suffixes(invalid.clone(), suffix); assert!(invalid.contains(&invalid_path1)); assert!(invalid.contains(&invalid_path2)); From 777654b5746c5e94f6383fa94800d89e6ef9f8f0 Mon Sep 17 00:00:00 2001 From: Ayrton Chilibeck Date: Sun, 14 Jan 2024 12:31:51 -0700 Subject: [PATCH 08/19] Chaged tests, Added stubs --- Cargo.lock | 229 ++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/validate.rs | 93 +++++++++++--------- 3 files changed, 283 insertions(+), 40 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a646b96..308cc5d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + [[package]] name = "anstream" version = "0.6.7" @@ -50,6 +59,18 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + [[package]] name = "clap" version = "4.4.16" @@ -102,6 +123,107 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "futures" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-executor" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-timer" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + [[package]] name = "hashbrown" version = "0.14.3" @@ -130,6 +252,24 @@ version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +[[package]] +name = "memchr" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + [[package]] name = "proc-macro2" version = "1.0.76" @@ -148,12 +288,91 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "regex" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + +[[package]] +name = "relative-path" +version = "1.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e898588f33fdd5b9420719948f9f2a32c922a246964576f71ba7f24f80610fbc" + +[[package]] +name = "rstest" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97eeab2f3c0a199bc4be135c36c924b6590b88c377d416494288c14f2db30199" +dependencies = [ + "futures", + "futures-timer", + "rstest_macros", + "rustc_version", +] + +[[package]] +name = "rstest_macros" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d428f8247852f894ee1be110b375111b586d4fa431f6c46e64ba5a0dcccbe605" +dependencies = [ + "cfg-if", + "glob", + "proc-macro2", + "quote", + "regex", + "relative-path", + "rustc_version", + "syn", + "unicode-ident", +] + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + [[package]] name = "ryu" version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" +[[package]] +name = "semver" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" + [[package]] name = "serde" version = "1.0.195" @@ -187,6 +406,15 @@ dependencies = [ "unsafe-libyaml", ] +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + [[package]] name = "strsim" version = "0.10.0" @@ -209,6 +437,7 @@ name = "tester" version = "0.1.0" dependencies = [ "clap", + "rstest", "serde", "serde_yaml", ] diff --git a/Cargo.toml b/Cargo.toml index b78d78d..79402b1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,5 +7,6 @@ edition = "2021" [dependencies] clap = { version = "4.4.16", features = ["derive"] } +rstest = "0.18.2" serde = { version = "1.0.195", features = ["derive"] } serde_yaml = "0.9.30" diff --git a/src/validate.rs b/src/validate.rs index dcddc5d..8064ae6 100644 --- a/src/validate.rs +++ b/src/validate.rs @@ -1,4 +1,4 @@ -use std::{path::PathBuf, fs}; +use std::{path::PathBuf, fs, collections::HashMap}; use crate::util; @@ -27,8 +27,26 @@ pub fn validate(verbosity: u8, config: util::config::Config) { } // make sure each has a match + // - check the file stems + // - compare the file stems + // - check if either file is in the invalid list + // - add to the notification queue + let mut in_to_out: (Vec<(PathBuf, PathBuf)>, Vec) = map_files(in_files, out_files); + let invalid: Vec<(PathBuf, PathBuf)> = check_files(in_to_out[0]); + + print_invalid_mappings(in_to_out[1]); + print_invalid_pairs(invalid); + } +/** + * @brief Collects paths with invalid suffixes + * + * @param files: A vector of PathBuf containing file names + * @param suf: The expected suffix for the files + * + * @return A vector of paths with invalid suffixes +*/ fn collect_invalid(files: &Vec, suf: &str) -> Vec { let mut res: Vec = vec![]; @@ -41,7 +59,13 @@ fn collect_invalid(files: &Vec, suf: &str) -> Vec { return res } - +/** + * @brief Get all file names in a directory + * + * @param path: the path to the target directory + * + * @returns Result with a Vector of PathBuf or error +*/ fn get_dir_files(path: PathBuf) -> Result, &'static str> { let mut res: Vec = vec![]; @@ -63,32 +87,12 @@ fn get_dir_files(path: PathBuf) -> Result, &'static str> { return Ok(res); } -fn compare_files(in_files: Vec, out_files: Vec) -> Vec { - let mut res: Vec = vec![]; - - res.append(&mut compare_list(&in_files, &out_files)); - res.append(&mut compare_list(&out_files, &in_files)); - - return res; -} - -fn compare_list(from: &Vec, against: &Vec) -> Vec { - let mut res: Vec = vec![]; - - // Compare each input file to each output file - for file in from { - let beg = file.file_stem().unwrap(); // ignore suffix - for out in against { - if beg == out.file_stem().unwrap() { - break; - } - } - res.push(file.clone()); // if the file does not have a counterpart, then push to the lost files - } - - return res; -} - +/** + * @brief Print utility for the invalid paths + * + * @param files: A vector containing the invalid path names + * @param exp: The expected suffix +*/ fn print_invalid_suffixes(files: Vec, exp: &str) { println!("Invalid suffixes detected 😱:" ); println!("Current => Suggested"); @@ -108,14 +112,15 @@ fn print_invalid_suffixes(files: Vec, exp: &str) { #[cfg(test)] mod tests { + use rstest::{fixture, rstest}; + use super::*; - #[test] - fn test_collect_invalid() { - let suffix = "suf"; - let valid_path1 = PathBuf::from("path/file.suf"); - let valid_path2 = PathBuf::from("path/file_stupid.suf"); - let valid_path3 = PathBuf::from("path/file/dead.suf"); + #[fixture] + fn files() -> Vec { + let valid_path1 = PathBuf::from("path/file.suf"); + let valid_path2 = PathBuf::from("path/file_stupid.suf"); + let valid_path3 = PathBuf::from("path/file/dead.suf"); let invalid_path1 = PathBuf::from("path/file.sub"); let invalid_path2 = PathBuf::from("path/file_stupid.sur"); let invalid_path3 = PathBuf::from("path/file.bub"); @@ -123,17 +128,25 @@ mod tests { let files: Vec = vec![valid_path1.clone(), valid_path2.clone(), valid_path3.clone(), invalid_path1.clone(), invalid_path2.clone(), invalid_path3.clone()]; + return files; + } + + #[rstest] + fn test_collect_invalid(files: Vec) { + let suffix = "suf"; let invalid = collect_invalid(&files, suffix); println!("{:?}", invalid); + + // visual testing for the print formatting print_invalid_suffixes(invalid.clone(), suffix); - assert!(invalid.contains(&invalid_path1)); - assert!(invalid.contains(&invalid_path2)); - assert!(invalid.contains(&invalid_path3)); + assert!(!invalid.contains(&files[0])); + assert!(!invalid.contains(&files[1])); + assert!(!invalid.contains(&files[2])); - assert!(!invalid.contains(&valid_path1)); - assert!(!invalid.contains(&valid_path2)); - assert!(!invalid.contains(&valid_path3)); + assert!(invalid.contains(&files[3])); + assert!(invalid.contains(&files[4])); + assert!(invalid.contains(&files[5])); } } From b290c924a81edf315898673ac73779f802be0f2a Mon Sep 17 00:00:00 2001 From: Ayrton Chilibeck Date: Sun, 14 Jan 2024 12:45:20 -0700 Subject: [PATCH 09/19] Added function stubs --- src/validate.rs | 50 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/src/validate.rs b/src/validate.rs index 8064ae6..afab496 100644 --- a/src/validate.rs +++ b/src/validate.rs @@ -32,13 +32,40 @@ pub fn validate(verbosity: u8, config: util::config::Config) { // - check if either file is in the invalid list // - add to the notification queue let mut in_to_out: (Vec<(PathBuf, PathBuf)>, Vec) = map_files(in_files, out_files); - let invalid: Vec<(PathBuf, PathBuf)> = check_files(in_to_out[0]); + let invalid: Vec<(PathBuf, PathBuf)> = check_mappings(in_to_out.0, in_suffix, out_suffix); - print_invalid_mappings(in_to_out[1]); + print_unmached(in_to_out.1); print_invalid_pairs(invalid); } +/** + * @brief Maps input files to output files based on their stem + * + * @param in_files: The test input files + * @param out_files: The test output files + * + * @return A tuple of two elements: + * - A vector containing the file mappings from input to output (if found) + * - A vector containing paths for which a match was not found +*/ +fn map_files(in_files: Vec, out_files: Vec) -> (Vec<(PathBuf, PathBuf)>, Vec) { + +} + +/** + * @brief Checks that a given mapping is valid, containing the correct suffixes + * + * @param mappings between two files + * @param the expected in_suffix + * @param the expected out_suffix + * + * @return A vector of tuples with (input, output) PathBufs +*/ +fn check_mappings(mappings: Vec<(PathBuf, PathBuf)>, in_suffix: &str, out_suffix: &str) -> Vec<(PathBuf, PathBuf)> { + +} + /** * @brief Collects paths with invalid suffixes * @@ -110,6 +137,25 @@ fn print_invalid_suffixes(files: Vec, exp: &str) { } } +/** + * @brief Utility function to pring unmatched files + * + * @param unmatched: Unmatched files +*/ +fn print_unmached(unmatched: Vec) { + +} + +/** + * @brief Utility function to print invalid pairs + * + * @param invalid: A vector of invalid pairs +*/ +fn print_invalid_pairs(invalid: Vec<(PathBuf, PathBuf)>) { + +} + + #[cfg(test)] mod tests { use rstest::{fixture, rstest}; From 775dfab3493af1cb2c354143a19607078be7227c Mon Sep 17 00:00:00 2001 From: Ayrton Chilibeck Date: Sun, 14 Jan 2024 13:21:23 -0700 Subject: [PATCH 10/19] Added tests for stubbed functions --- src/validate.rs | 73 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 65 insertions(+), 8 deletions(-) diff --git a/src/validate.rs b/src/validate.rs index afab496..8e60e85 100644 --- a/src/validate.rs +++ b/src/validate.rs @@ -1,4 +1,4 @@ -use std::{path::PathBuf, fs, collections::HashMap}; +use std::{path::PathBuf, fs, collections::HashMap, borrow::BorrowMut}; use crate::util; @@ -27,15 +27,11 @@ pub fn validate(verbosity: u8, config: util::config::Config) { } // make sure each has a match - // - check the file stems - // - compare the file stems - // - check if either file is in the invalid list - // - add to the notification queue let mut in_to_out: (Vec<(PathBuf, PathBuf)>, Vec) = map_files(in_files, out_files); let invalid: Vec<(PathBuf, PathBuf)> = check_mappings(in_to_out.0, in_suffix, out_suffix); print_unmached(in_to_out.1); - print_invalid_pairs(invalid); + print_invalid_pairs(invalid, in_suffix, out_suffix); } @@ -147,11 +143,11 @@ fn print_unmached(unmatched: Vec) { } /** - * @brief Utility function to print invalid pairs + * @brief Utility function to print invalid pairs and suggest a fix * * @param invalid: A vector of invalid pairs */ -fn print_invalid_pairs(invalid: Vec<(PathBuf, PathBuf)>) { +fn print_invalid_pairs(invalid: Vec<(PathBuf, PathBuf)>, in_suffix: &str, out_suffix: &str) { } @@ -177,6 +173,38 @@ mod tests { return files; } + #[fixture] + fn in_files() -> Vec { + let invalid_map11 = PathBuf::from("in/inv/path/file.in "); + let invalid_map12 = PathBuf::from("in/inv/path/file_stupid.in"); + let invalid_map13 = PathBuf::from("in/inv/path/file/dead.inn"); + + let valid_map11 = PathBuf::from("in/val/path/file.in"); + let valid_map12 = PathBuf::from("in/val/path/file_stupid.in"); + let valid_map13 = PathBuf::from("in/val/path/file/dead.in"); + + let in_files = vec![invalid_map11, invalid_map12, invalid_map13, + valid_map11, valid_map12, valid_map13]; + + return in_files; + } + + #[fixture] + fn out_files() -> Vec { + let invalid_map21 = PathBuf::from("out/inv/path/file.out"); + let invalid_map22 = PathBuf::from("out/inv/path/file_stupid.out "); + let invalid_map23 = PathBuf::from("out/inv/path/file.outt"); + + let valid_map21 = PathBuf::from("out/val/path/file.out"); + let valid_map22 = PathBuf::from("out/val/path/file_stupid.out"); + let valid_map23 = PathBuf::from("out/val/path/file.out"); + + let out_files = vec![invalid_map21, invalid_map22, invalid_map23, + valid_map21, valid_map22, valid_map23]; + + return out_files; + } + #[rstest] fn test_collect_invalid(files: Vec) { let suffix = "suf"; @@ -195,4 +223,33 @@ mod tests { assert!(invalid.contains(&files[4])); assert!(invalid.contains(&files[5])); } + + #[rstest] + fn test_map(in_files: Vec, out_files: Vec) { + let mappings: (Vec<(PathBuf, PathBuf)>, Vec) = map_files(in_files, out_files); + + print_unmached(mappings.1); + assert!(&mappings.0.contains(&(in_files[0], out_files[0]))); + assert!(&mappings.0.contains(&(in_files[1], out_files[1]))); + assert!(&mappings.0.contains(&(in_files[2], out_files[2]))); + assert!(&mappings.0.contains(&(in_files[3], out_files[3]))); + assert!(&mappings.0.contains(&(in_files[4], out_files[4]))); + assert!(&mappings.0.contains(&(in_files[5], out_files[5]))); + } + + #[rstest] + fn test_check_valid_mappings(in_files: Vec, out_files: Vec) { + let in_suffix = "in"; + let out_suffix = "out"; + let invalid: Vec<(PathBuf, PathBuf)> = check_mappings(map_files(in_files, out_files).0, in_suffix, out_suffix); + + print_invalid_pairs(invalid, in_suffix, out_suffix); + assert!(&invalid.contains(&(in_files[0], out_files[0]))); + assert!(&invalid.contains(&(in_files[1], out_files[1]))); + assert!(&invalid.contains(&(in_files[2], out_files[2]))); + + assert!(!&invalid.contains(&(in_files[3], out_files[3]))); + assert!(!&invalid.contains(&(in_files[4], out_files[4]))); + assert!(!&invalid.contains(&(in_files[5], out_files[5]))); + } } From 809e6837eb55c8637a04930bed1f076181898353 Mon Sep 17 00:00:00 2001 From: Ayrton Chilibeck Date: Sun, 14 Jan 2024 16:46:12 -0700 Subject: [PATCH 11/19] Implementation and Tests of map_files - Changed the config.yaml to reflect testing needs - Completed the function implementation - Tests passing --- src/util/test/parse_config/config.yaml | 6 +- src/validate.rs | 148 ++++++++++++++++++------- 2 files changed, 114 insertions(+), 40 deletions(-) diff --git a/src/util/test/parse_config/config.yaml b/src/util/test/parse_config/config.yaml index e166161..a9a36c7 100644 --- a/src/util/test/parse_config/config.yaml +++ b/src/util/test/parse_config/config.yaml @@ -1,6 +1,6 @@ -input_path: "/path/to/dir" -output_path: "/path/to/out/dir" -in_stream_path: "/path/to/in/stream" +input_path: "/test/in" +output_path: "/test/out" +in_stream_path: "/test/instream" tested_executables: - name: "team1" diff --git a/src/validate.rs b/src/validate.rs index 8e60e85..a544b57 100644 --- a/src/validate.rs +++ b/src/validate.rs @@ -1,4 +1,4 @@ -use std::{path::PathBuf, fs, collections::HashMap, borrow::BorrowMut}; +use std::{path::{PathBuf, Path, Components, Component}, fs, collections::{HashMap, VecDeque}, borrow::BorrowMut}; use crate::util; @@ -8,8 +8,8 @@ pub fn validate(verbosity: u8, config: util::config::Config) { let in_suffix = "in"; //TODO make this configurable? let out_suffix = "out"; // get list of all file names in input/output - let in_files: Vec = get_dir_files(config.input_path).expect("Failed to read the input directory contents"); - let out_files: Vec = get_dir_files(config.output_path).expect("Failed to read the output directory contents"); + let in_files: Vec = get_dir_files(&config.input_path).expect("Failed to read the input directory contents"); + let out_files: Vec = get_dir_files(&config.output_path).expect("Failed to read the output directory contents"); let mismatch: Vec<(PathBuf, PathBuf)>; @@ -27,7 +27,7 @@ pub fn validate(verbosity: u8, config: util::config::Config) { } // make sure each has a match - let mut in_to_out: (Vec<(PathBuf, PathBuf)>, Vec) = map_files(in_files, out_files); + let in_to_out: (Vec<(PathBuf, PathBuf)>, Vec) = map_files(in_files, out_files, &config); let invalid: Vec<(PathBuf, PathBuf)> = check_mappings(in_to_out.0, in_suffix, out_suffix); print_unmached(in_to_out.1); @@ -45,8 +45,73 @@ pub fn validate(verbosity: u8, config: util::config::Config) { * - A vector containing the file mappings from input to output (if found) * - A vector containing paths for which a match was not found */ -fn map_files(in_files: Vec, out_files: Vec) -> (Vec<(PathBuf, PathBuf)>, Vec) { +fn map_files(in_files: Vec, out_files: Vec, config: &util::config::Config) -> (Vec<(PathBuf, PathBuf)>, Vec) { + let mut res: (Vec<(PathBuf, PathBuf)>, Vec) = (vec![], vec![]); + // get the prefixes + let mut in_prefix = vec![]; + for pre in config.input_path.components() { + in_prefix.push(pre); + } + + let mut out_prefix = vec![]; + for pre in config.output_path.components() { + out_prefix.push(pre); + } + + // check if the files have the same paths relative to in/out directory + for ifile in &in_files { + let mut found = false; + + // get the components of the path + let mut in_comp: VecDeque = VecDeque::from(vec![]); + for tmp in ifile.components() { + in_comp.push_back(tmp); + } + in_comp.pop_back(); + + // check if the files share common ancestors except for the first path + for ofile in &out_files { + + // get the components of the path + let mut out_comp: VecDeque = VecDeque::from(vec![]); + for tmp in ofile.components() { + out_comp.push_back(tmp); + } + out_comp.pop_back(); + // println!("{:?}", ofile); + // println!("{:?}", out_comp); + + // check if the file names are the same + if ofile.file_stem() == ifile.file_stem() { + // check that their paths are the same relative to the input/output directory + for comp in &in_prefix { if &comp == &in_comp.front().expect("Failed to extract") { in_comp.pop_front(); } } + for comp in &out_prefix { if &comp == &out_comp.front().expect("Failed to extract") { out_comp.pop_front(); } } + println!("{:?}\n{:?}\n{:?}", in_prefix, in_comp,out_comp); + + // if the files match, then we add them to the mapping + if out_comp == in_comp { + println!("Added to map"); + res.0.push((ifile.clone(), ofile.clone())); + found = true; + } + } + } + + // if we fail to find a match, we add the file to the rest + if !found { res.1.push(ifile.clone()); } + } + + let mut cl: Vec = Vec::from(out_files.clone()); + let mut r: Vec = vec![]; + for tup in &res.0 { + r.push(tup.1.clone()); + } + + cl.retain(|x| !r.contains(&x)); + res.1.append(&mut cl); + println!("{:?}", res); + return res; } /** @@ -59,7 +124,7 @@ fn map_files(in_files: Vec, out_files: Vec) -> (Vec<(PathBuf, * @return A vector of tuples with (input, output) PathBufs */ fn check_mappings(mappings: Vec<(PathBuf, PathBuf)>, in_suffix: &str, out_suffix: &str) -> Vec<(PathBuf, PathBuf)> { - + return vec![(PathBuf::from("a"), PathBuf::from("b"))]; } /** @@ -89,7 +154,7 @@ fn collect_invalid(files: &Vec, suf: &str) -> Vec { * * @returns Result with a Vector of PathBuf or error */ -fn get_dir_files(path: PathBuf) -> Result, &'static str> { +fn get_dir_files(path: &PathBuf) -> Result, &'static str> { let mut res: Vec = vec![]; // get the readout of the path for error handling @@ -175,13 +240,13 @@ mod tests { #[fixture] fn in_files() -> Vec { - let invalid_map11 = PathBuf::from("in/inv/path/file.in "); - let invalid_map12 = PathBuf::from("in/inv/path/file_stupid.in"); - let invalid_map13 = PathBuf::from("in/inv/path/file/dead.inn"); + let invalid_map11 = PathBuf::from("/test/in/inv/path/file.in "); + let invalid_map12 = PathBuf::from("/test/in/inv/path/file_stupid.in"); + let invalid_map13 = PathBuf::from("/test/in/inv/path/dead.inn"); - let valid_map11 = PathBuf::from("in/val/path/file.in"); - let valid_map12 = PathBuf::from("in/val/path/file_stupid.in"); - let valid_map13 = PathBuf::from("in/val/path/file/dead.in"); + let valid_map11 = PathBuf::from("/test/in/val/path/file.in"); + let valid_map12 = PathBuf::from("/test/in/val/path/file_stupid.in"); + let valid_map13 = PathBuf::from("/test/in/val/path/file/dead.in"); let in_files = vec![invalid_map11, invalid_map12, invalid_map13, valid_map11, valid_map12, valid_map13]; @@ -191,13 +256,13 @@ mod tests { #[fixture] fn out_files() -> Vec { - let invalid_map21 = PathBuf::from("out/inv/path/file.out"); - let invalid_map22 = PathBuf::from("out/inv/path/file_stupid.out "); - let invalid_map23 = PathBuf::from("out/inv/path/file.outt"); + let invalid_map21 = PathBuf::from("/test/out/inv/path/file.out"); + let invalid_map22 = PathBuf::from("/test/out/inv/path/file_stupid.out "); + let invalid_map23 = PathBuf::from("/test/out/inv/path/file/dead.outt"); - let valid_map21 = PathBuf::from("out/val/path/file.out"); - let valid_map22 = PathBuf::from("out/val/path/file_stupid.out"); - let valid_map23 = PathBuf::from("out/val/path/file.out"); + let valid_map21 = PathBuf::from("/test/out/val/path/file.out"); + let valid_map22 = PathBuf::from("/test/out/val/path/file_stupid.out"); + let valid_map23 = PathBuf::from("/test/out/val/path/file/dead.out"); let out_files = vec![invalid_map21, invalid_map22, invalid_map23, valid_map21, valid_map22, valid_map23]; @@ -205,6 +270,11 @@ mod tests { return out_files; } + #[fixture] + fn config() -> util::config::Config { + return util::config::parse_config(PathBuf::from("src/util/test/parse_config/config.yaml")); + } + #[rstest] fn test_collect_invalid(files: Vec) { let suffix = "suf"; @@ -225,31 +295,35 @@ mod tests { } #[rstest] - fn test_map(in_files: Vec, out_files: Vec) { - let mappings: (Vec<(PathBuf, PathBuf)>, Vec) = map_files(in_files, out_files); + fn test_map(in_files: Vec, out_files: Vec, config: util::config::Config) { + let mappings: (Vec<(PathBuf, PathBuf)>, Vec) = map_files(in_files.clone(), out_files.clone(), &config); - print_unmached(mappings.1); - assert!(&mappings.0.contains(&(in_files[0], out_files[0]))); - assert!(&mappings.0.contains(&(in_files[1], out_files[1]))); - assert!(&mappings.0.contains(&(in_files[2], out_files[2]))); - assert!(&mappings.0.contains(&(in_files[3], out_files[3]))); - assert!(&mappings.0.contains(&(in_files[4], out_files[4]))); - assert!(&mappings.0.contains(&(in_files[5], out_files[5]))); + // print_unmached(mappings.1); + let test = (in_files[0].clone(), out_files[0].clone()); + assert!(&mappings.0.contains(&test), "The mapping does not contain {:?}", test); + assert!(&mappings.0.contains(&(in_files[1].clone(), out_files[1].clone()))); + assert!(!&mappings.0.contains(&(in_files[2].clone(), out_files[2].clone()))); + assert!(&mappings.0.contains(&(in_files[3].clone(), out_files[3].clone()))); + assert!(&mappings.0.contains(&(in_files[4].clone(), out_files[4].clone()))); + assert!(&mappings.0.contains(&(in_files[5].clone(), out_files[5].clone()))); + + assert!(&mappings.1.contains(&in_files[2])); + assert!(&mappings.1.contains(&out_files[2])); } #[rstest] - fn test_check_valid_mappings(in_files: Vec, out_files: Vec) { + fn test_check_valid_mappings(in_files: Vec, out_files: Vec, config: util::config::Config) { let in_suffix = "in"; let out_suffix = "out"; - let invalid: Vec<(PathBuf, PathBuf)> = check_mappings(map_files(in_files, out_files).0, in_suffix, out_suffix); + let invalid: Vec<(PathBuf, PathBuf)> = check_mappings(map_files(in_files.clone(), out_files.clone(), &config).0, in_suffix, out_suffix); - print_invalid_pairs(invalid, in_suffix, out_suffix); - assert!(&invalid.contains(&(in_files[0], out_files[0]))); - assert!(&invalid.contains(&(in_files[1], out_files[1]))); - assert!(&invalid.contains(&(in_files[2], out_files[2]))); + print_invalid_pairs(invalid.clone(), in_suffix, out_suffix); + assert!(&invalid.contains(&(in_files[0].clone(), out_files[0].clone()))); + assert!(&invalid.contains(&(in_files[1].clone(), out_files[1].clone()))); + assert!(&invalid.contains(&(in_files[2].clone(), out_files[2].clone()))); - assert!(!&invalid.contains(&(in_files[3], out_files[3]))); - assert!(!&invalid.contains(&(in_files[4], out_files[4]))); - assert!(!&invalid.contains(&(in_files[5], out_files[5]))); + assert!(!&invalid.contains(&(in_files[3].clone(), out_files[3].clone()))); + assert!(!&invalid.contains(&(in_files[4].clone(), out_files[4].clone()))); + assert!(!&invalid.contains(&(in_files[5].clone(), out_files[5].clone()))); } } From 4cd54923c94131cdb2c3682cb99254f3a73ddb24 Mon Sep 17 00:00:00 2001 From: Ayrton Chilibeck Date: Sun, 14 Jan 2024 17:00:12 -0700 Subject: [PATCH 12/19] Implemented the map checker - Tests passing --- src/validate.rs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/validate.rs b/src/validate.rs index a544b57..55ae5c2 100644 --- a/src/validate.rs +++ b/src/validate.rs @@ -32,7 +32,6 @@ pub fn validate(verbosity: u8, config: util::config::Config) { print_unmached(in_to_out.1); print_invalid_pairs(invalid, in_suffix, out_suffix); - } /** @@ -110,7 +109,7 @@ fn map_files(in_files: Vec, out_files: Vec, config: &util::con cl.retain(|x| !r.contains(&x)); res.1.append(&mut cl); - println!("{:?}", res); + // println!("{:?}", res); return res; } @@ -124,7 +123,15 @@ fn map_files(in_files: Vec, out_files: Vec, config: &util::con * @return A vector of tuples with (input, output) PathBufs */ fn check_mappings(mappings: Vec<(PathBuf, PathBuf)>, in_suffix: &str, out_suffix: &str) -> Vec<(PathBuf, PathBuf)> { - return vec![(PathBuf::from("a"), PathBuf::from("b"))]; + let mut res: Vec<(PathBuf, PathBuf)> = vec![]; + + for tup in &mappings { + if !(tup.0.as_path().extension().unwrap() == in_suffix) || !(tup.1.as_path().extension().unwrap() == out_suffix) { + res.push(tup.clone()); + } + } + // println!("{:?}", res); + return res; } /** @@ -144,7 +151,7 @@ fn collect_invalid(files: &Vec, suf: &str) -> Vec { res.push(file.clone()); } } - + println!("{:?}", res); return res } /** @@ -320,7 +327,7 @@ mod tests { print_invalid_pairs(invalid.clone(), in_suffix, out_suffix); assert!(&invalid.contains(&(in_files[0].clone(), out_files[0].clone()))); assert!(&invalid.contains(&(in_files[1].clone(), out_files[1].clone()))); - assert!(&invalid.contains(&(in_files[2].clone(), out_files[2].clone()))); + assert!(!&invalid.contains(&(in_files[2].clone(), out_files[2].clone()))); assert!(!&invalid.contains(&(in_files[3].clone(), out_files[3].clone()))); assert!(!&invalid.contains(&(in_files[4].clone(), out_files[4].clone()))); From b4cab67e283cac575a9f60b75c3acd55495328cf Mon Sep 17 00:00:00 2001 From: Ayrton Chilibeck Date: Sun, 14 Jan 2024 21:29:34 -0700 Subject: [PATCH 13/19] Added Verbosity as an argument to functions --- src/validate.rs | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/validate.rs b/src/validate.rs index 55ae5c2..b9120c6 100644 --- a/src/validate.rs +++ b/src/validate.rs @@ -8,30 +8,30 @@ pub fn validate(verbosity: u8, config: util::config::Config) { let in_suffix = "in"; //TODO make this configurable? let out_suffix = "out"; // get list of all file names in input/output - let in_files: Vec = get_dir_files(&config.input_path).expect("Failed to read the input directory contents"); - let out_files: Vec = get_dir_files(&config.output_path).expect("Failed to read the output directory contents"); + let in_files: Vec = get_dir_files(&config.input_path, verbosity).expect("Failed to read the input directory contents"); + let out_files: Vec = get_dir_files(&config.output_path, verbosity).expect("Failed to read the output directory contents"); let mismatch: Vec<(PathBuf, PathBuf)>; // check the files for valid suffixes - let invalid_suffix_in: Vec = collect_invalid(&in_files, in_suffix); - let invalid_suffix_out: Vec = collect_invalid(&out_files, out_suffix); + let invalid_suffix_in: Vec = collect_invalid(&in_files, in_suffix, verbosity); + let invalid_suffix_out: Vec = collect_invalid(&out_files, out_suffix, verbosity); // print the delinquints if invalid_suffix_in.len() > 0 { - print_invalid_suffixes(invalid_suffix_in, in_suffix); + print_invalid_suffixes(invalid_suffix_in, in_suffix, verbosity); } if invalid_suffix_out.len() > 0 { - print_invalid_suffixes(invalid_suffix_out, out_suffix); + print_invalid_suffixes(invalid_suffix_out, out_suffix, verbosity); } // make sure each has a match - let in_to_out: (Vec<(PathBuf, PathBuf)>, Vec) = map_files(in_files, out_files, &config); - let invalid: Vec<(PathBuf, PathBuf)> = check_mappings(in_to_out.0, in_suffix, out_suffix); + let in_to_out: (Vec<(PathBuf, PathBuf)>, Vec) = map_files(in_files, out_files, &config, verbosity); + let invalid: Vec<(PathBuf, PathBuf)> = check_mappings(in_to_out.0, in_suffix, out_suffix, verbosity); - print_unmached(in_to_out.1); - print_invalid_pairs(invalid, in_suffix, out_suffix); + print_unmached(in_to_out.1, verbosity); + print_invalid_pairs(invalid, in_suffix, out_suffix, verbosity); } /** @@ -44,7 +44,7 @@ pub fn validate(verbosity: u8, config: util::config::Config) { * - A vector containing the file mappings from input to output (if found) * - A vector containing paths for which a match was not found */ -fn map_files(in_files: Vec, out_files: Vec, config: &util::config::Config) -> (Vec<(PathBuf, PathBuf)>, Vec) { +fn map_files(in_files: Vec, out_files: Vec, config: &util::config::Config, verbosity: u8) -> (Vec<(PathBuf, PathBuf)>, Vec) { let mut res: (Vec<(PathBuf, PathBuf)>, Vec) = (vec![], vec![]); // get the prefixes @@ -122,7 +122,7 @@ fn map_files(in_files: Vec, out_files: Vec, config: &util::con * * @return A vector of tuples with (input, output) PathBufs */ -fn check_mappings(mappings: Vec<(PathBuf, PathBuf)>, in_suffix: &str, out_suffix: &str) -> Vec<(PathBuf, PathBuf)> { +fn check_mappings(mappings: Vec<(PathBuf, PathBuf)>, in_suffix: &str, out_suffix: &str, verbosity: u8) -> Vec<(PathBuf, PathBuf)> { let mut res: Vec<(PathBuf, PathBuf)> = vec![]; for tup in &mappings { @@ -142,7 +142,7 @@ fn check_mappings(mappings: Vec<(PathBuf, PathBuf)>, in_suffix: &str, out_suffix * * @return A vector of paths with invalid suffixes */ -fn collect_invalid(files: &Vec, suf: &str) -> Vec { +fn collect_invalid(files: &Vec, suf: &str, verbosity: u8) -> Vec { let mut res: Vec = vec![]; for file in files { @@ -161,7 +161,7 @@ fn collect_invalid(files: &Vec, suf: &str) -> Vec { * * @returns Result with a Vector of PathBuf or error */ -fn get_dir_files(path: &PathBuf) -> Result, &'static str> { +fn get_dir_files(path: &PathBuf, verbosity: u8) -> Result, &'static str> { let mut res: Vec = vec![]; // get the readout of the path for error handling @@ -188,7 +188,7 @@ fn get_dir_files(path: &PathBuf) -> Result, &'static str> { * @param files: A vector containing the invalid path names * @param exp: The expected suffix */ -fn print_invalid_suffixes(files: Vec, exp: &str) { +fn print_invalid_suffixes(files: Vec, exp: &str, verbosity: u8) { println!("Invalid suffixes detected 😱:" ); println!("Current => Suggested"); for mut file in files { @@ -210,7 +210,7 @@ fn print_invalid_suffixes(files: Vec, exp: &str) { * * @param unmatched: Unmatched files */ -fn print_unmached(unmatched: Vec) { +fn print_unmached(unmatched: Vec, verbosity: u8) { } @@ -219,7 +219,7 @@ fn print_unmached(unmatched: Vec) { * * @param invalid: A vector of invalid pairs */ -fn print_invalid_pairs(invalid: Vec<(PathBuf, PathBuf)>, in_suffix: &str, out_suffix: &str) { +fn print_invalid_pairs(invalid: Vec<(PathBuf, PathBuf)>, in_suffix: &str, out_suffix: &str, verbosity: u8) { } @@ -285,12 +285,12 @@ mod tests { #[rstest] fn test_collect_invalid(files: Vec) { let suffix = "suf"; - let invalid = collect_invalid(&files, suffix); + let invalid = collect_invalid(&files, suffix, 2); println!("{:?}", invalid); // visual testing for the print formatting - print_invalid_suffixes(invalid.clone(), suffix); + print_invalid_suffixes(invalid.clone(), suffix, 2); assert!(!invalid.contains(&files[0])); assert!(!invalid.contains(&files[1])); @@ -303,7 +303,7 @@ mod tests { #[rstest] fn test_map(in_files: Vec, out_files: Vec, config: util::config::Config) { - let mappings: (Vec<(PathBuf, PathBuf)>, Vec) = map_files(in_files.clone(), out_files.clone(), &config); + let mappings: (Vec<(PathBuf, PathBuf)>, Vec) = map_files(in_files.clone(), out_files.clone(), &config, 2); // print_unmached(mappings.1); let test = (in_files[0].clone(), out_files[0].clone()); @@ -322,9 +322,9 @@ mod tests { fn test_check_valid_mappings(in_files: Vec, out_files: Vec, config: util::config::Config) { let in_suffix = "in"; let out_suffix = "out"; - let invalid: Vec<(PathBuf, PathBuf)> = check_mappings(map_files(in_files.clone(), out_files.clone(), &config).0, in_suffix, out_suffix); + let invalid: Vec<(PathBuf, PathBuf)> = check_mappings(map_files(in_files.clone(), out_files.clone(), &config, 2).0, in_suffix, out_suffix, 2); - print_invalid_pairs(invalid.clone(), in_suffix, out_suffix); + print_invalid_pairs(invalid.clone(), in_suffix, out_suffix, 2); assert!(&invalid.contains(&(in_files[0].clone(), out_files[0].clone()))); assert!(&invalid.contains(&(in_files[1].clone(), out_files[1].clone()))); assert!(!&invalid.contains(&(in_files[2].clone(), out_files[2].clone()))); From 2d7e711930ef063067380257b5eb94cd196d289f Mon Sep 17 00:00:00 2001 From: Ayrton Chilibeck Date: Mon, 15 Jan 2024 00:40:48 -0700 Subject: [PATCH 14/19] Made changes to the config data struct --- src/util/config.rs | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/util/config.rs b/src/util/config.rs index c47742b..1aa5457 100644 --- a/src/util/config.rs +++ b/src/util/config.rs @@ -5,39 +5,39 @@ use serde_yaml::{self}; #[derive(Debug, Deserialize)] pub struct Config { - pub tested_executables: Vec, + tested_executables: Vec, - pub input_path: PathBuf, - pub output_path: PathBuf, - pub in_stream_path: PathBuf, + input_path: PathBuf, + output_path: PathBuf, + in_stream_path: PathBuf, - pub runtimes: Option>, + runtimes: Option>, - pub toolchains: Vec, + toolchains: Vec, } #[derive(Debug, Deserialize)] pub struct Team { - pub name: String, - pub executable: PathBuf, + name: String, + executable: PathBuf, } #[derive(Debug, Deserialize)] pub struct Toolchain { - pub name: String, - pub steps: Vec,} + name: String, + steps: Vec,} #[derive(Debug, Deserialize)] pub struct Step { - pub name: String, + name: String, - pub executable_path: Option, // if None then we use the current executable path - pub arguments: Vec, // special string $INPUT corresponds to previous step output - pub output: String, // the output file name + executable_path: Option, // if None then we use the current executable path + arguments: Vec, // special string $INPUT corresponds to previous step output + output: String, // the output file name - pub uses_runtime: Option, - pub uses_in_stream: Option, - pub allow_error: Option + uses_runtime: Option, + uses_in_stream: Option, + allow_error: Option } pub fn parse_config(path: PathBuf) -> Config { From ea823a2ea2802dc395f8d8b73c3cf87dde1b87d9 Mon Sep 17 00:00:00 2001 From: Ayrton Chilibeck Date: Mon, 15 Jan 2024 00:42:31 -0700 Subject: [PATCH 15/19] Made Config struct public --- src/util/config.rs | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/util/config.rs b/src/util/config.rs index 1aa5457..c47742b 100644 --- a/src/util/config.rs +++ b/src/util/config.rs @@ -5,39 +5,39 @@ use serde_yaml::{self}; #[derive(Debug, Deserialize)] pub struct Config { - tested_executables: Vec, + pub tested_executables: Vec, - input_path: PathBuf, - output_path: PathBuf, - in_stream_path: PathBuf, + pub input_path: PathBuf, + pub output_path: PathBuf, + pub in_stream_path: PathBuf, - runtimes: Option>, + pub runtimes: Option>, - toolchains: Vec, + pub toolchains: Vec, } #[derive(Debug, Deserialize)] pub struct Team { - name: String, - executable: PathBuf, + pub name: String, + pub executable: PathBuf, } #[derive(Debug, Deserialize)] pub struct Toolchain { - name: String, - steps: Vec,} + pub name: String, + pub steps: Vec,} #[derive(Debug, Deserialize)] pub struct Step { - name: String, + pub name: String, - executable_path: Option, // if None then we use the current executable path - arguments: Vec, // special string $INPUT corresponds to previous step output - output: String, // the output file name + pub executable_path: Option, // if None then we use the current executable path + pub arguments: Vec, // special string $INPUT corresponds to previous step output + pub output: String, // the output file name - uses_runtime: Option, - uses_in_stream: Option, - allow_error: Option + pub uses_runtime: Option, + pub uses_in_stream: Option, + pub allow_error: Option } pub fn parse_config(path: PathBuf) -> Config { From 4b22958a05027a8f73b013b52d34e2bc768b5d7a Mon Sep 17 00:00:00 2001 From: Ayrton Chilibeck Date: Mon, 15 Jan 2024 00:50:11 -0700 Subject: [PATCH 16/19] Added Logging functions --- src/util.rs | 1 + src/util/logger.rs | 13 +++++++++++++ 2 files changed, 14 insertions(+) create mode 100644 src/util/logger.rs diff --git a/src/util.rs b/src/util.rs index ef68c36..8354b60 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1 +1,2 @@ pub mod config; +pub mod logger; diff --git a/src/util/logger.rs b/src/util/logger.rs new file mode 100644 index 0000000..e3247d4 --- /dev/null +++ b/src/util/logger.rs @@ -0,0 +1,13 @@ +fn l1_log(verbosity: u8, message: &str) { + if verbosity > 0 { + println!("{}", message); + } +} + +fn l2_log(verbosity: u8, message: &str) { + if verbosity > 1 { + println!("{}", message); + } +} + +//TODO unit test, but these are trivial From f86106c9fa2335e1795d5c8b35c8663c7d723fe6 Mon Sep 17 00:00:00 2001 From: Ayrton Chilibeck Date: Mon, 15 Jan 2024 01:20:50 -0700 Subject: [PATCH 17/19] Added logger macro --- src/util/logger.rs | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/src/util/logger.rs b/src/util/logger.rs index e3247d4..c544502 100644 --- a/src/util/logger.rs +++ b/src/util/logger.rs @@ -1,13 +1,23 @@ -fn l1_log(verbosity: u8, message: &str) { - if verbosity > 0 { - println!("{}", message); - } +// prints output to the stderr if the verbosity is +// greater than or equal to the logging level of the +// notification. +macro_rules! log { + // NOTE: this uses a variadic argument system + // copied from the std::fmt eprintln! macro + // see the appropriate documentation + ($l:expr, $v:expr, $($arg:tt)*) => {{ + if $v >= $l { + eprintln!($($arg)*); + } + }}; } -fn l2_log(verbosity: u8, message: &str) { - if verbosity > 1 { - println!("{}", message); +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_name() { + log!(1, 1, "this is a {}", "test"); } } - -//TODO unit test, but these are trivial From 38d03f9d55beded38bb18bd64a99b96e3afc3b50 Mon Sep 17 00:00:00 2001 From: Ayrton Chilibeck Date: Mon, 15 Jan 2024 01:59:37 -0700 Subject: [PATCH 18/19] Added logging --- src/util/logger.rs | 3 +-- src/validate.rs | 37 +++++++++++++++++++++++++++++++------ 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/src/util/logger.rs b/src/util/logger.rs index c544502..f89070d 100644 --- a/src/util/logger.rs +++ b/src/util/logger.rs @@ -1,6 +1,7 @@ // prints output to the stderr if the verbosity is // greater than or equal to the logging level of the // notification. +#[macro_export] macro_rules! log { // NOTE: this uses a variadic argument system // copied from the std::fmt eprintln! macro @@ -14,8 +15,6 @@ macro_rules! log { #[cfg(test)] mod tests { - use super::*; - #[test] fn test_name() { log!(1, 1, "this is a {}", "test"); diff --git a/src/validate.rs b/src/validate.rs index b9120c6..f6f9188 100644 --- a/src/validate.rs +++ b/src/validate.rs @@ -1,19 +1,21 @@ use std::{path::{PathBuf, Path, Components, Component}, fs, collections::{HashMap, VecDeque}, borrow::BorrowMut}; use crate::util; +use crate::log; pub fn validate(verbosity: u8, config: util::config::Config) { println!("Validating"); let in_suffix = "in"; //TODO make this configurable? let out_suffix = "out"; + log!(1, verbosity, "LOG 1: Input suffix: {} \nOutput suffix: {}", in_suffix, out_suffix); // get list of all file names in input/output + log!(1, verbosity, "LOG 1:Reading the list of input and output files"); let in_files: Vec = get_dir_files(&config.input_path, verbosity).expect("Failed to read the input directory contents"); let out_files: Vec = get_dir_files(&config.output_path, verbosity).expect("Failed to read the output directory contents"); - let mismatch: Vec<(PathBuf, PathBuf)>; - // check the files for valid suffixes + log!(1, verbosity, "LOG 1:Collecting files with invalid suffixes"); let invalid_suffix_in: Vec = collect_invalid(&in_files, in_suffix, verbosity); let invalid_suffix_out: Vec = collect_invalid(&out_files, out_suffix, verbosity); @@ -27,7 +29,9 @@ pub fn validate(verbosity: u8, config: util::config::Config) { } // make sure each has a match + log!(1, verbosity, "LOG 1:Checking if valid mappings exist between input and output files"); let in_to_out: (Vec<(PathBuf, PathBuf)>, Vec) = map_files(in_files, out_files, &config, verbosity); + log!(1, verbosity, "LOG 1:Verifying file matches"); let invalid: Vec<(PathBuf, PathBuf)> = check_mappings(in_to_out.0, in_suffix, out_suffix, verbosity); print_unmached(in_to_out.1, verbosity); @@ -52,11 +56,13 @@ fn map_files(in_files: Vec, out_files: Vec, config: &util::con for pre in config.input_path.components() { in_prefix.push(pre); } + log!(2, verbosity, "LOG 2: Input prefixes found: {:?}", in_prefix); let mut out_prefix = vec![]; for pre in config.output_path.components() { out_prefix.push(pre); } + log!(2, verbosity, "LOG 2: Output prefixes found: {:?}", out_prefix); // check if the files have the same paths relative to in/out directory for ifile in &in_files { @@ -81,16 +87,21 @@ fn map_files(in_files: Vec, out_files: Vec, config: &util::con // println!("{:?}", ofile); // println!("{:?}", out_comp); + log!(2, verbosity, "LOG 2: Checking mapping of {} to {}", + &ifile.to_str().expect("failed to parse string"), + &ofile.to_str().expect("failed to parse string")); // check if the file names are the same if ofile.file_stem() == ifile.file_stem() { // check that their paths are the same relative to the input/output directory for comp in &in_prefix { if &comp == &in_comp.front().expect("Failed to extract") { in_comp.pop_front(); } } for comp in &out_prefix { if &comp == &out_comp.front().expect("Failed to extract") { out_comp.pop_front(); } } - println!("{:?}\n{:?}\n{:?}", in_prefix, in_comp,out_comp); + // println!("{:?}\n{:?}\n{:?}", in_prefix, in_comp,out_comp); // if the files match, then we add them to the mapping if out_comp == in_comp { - println!("Added to map"); + log!(1, verbosity, "LOG 1: Adding the mapping between {} and {} to the list of file mappings.", + ifile.to_str().expect("failed to parse string"), + ofile.to_str().expect("failed to parse string")); res.0.push((ifile.clone(), ofile.clone())); found = true; } @@ -98,7 +109,9 @@ fn map_files(in_files: Vec, out_files: Vec, config: &util::con } // if we fail to find a match, we add the file to the rest - if !found { res.1.push(ifile.clone()); } + if !found { + log!(1, verbosity, "LOG 1: Adding {} to the list of unmapped files", ifile.to_str().expect("failed to parse string")); + res.1.push(ifile.clone()); } } let mut cl: Vec = Vec::from(out_files.clone()); @@ -108,6 +121,7 @@ fn map_files(in_files: Vec, out_files: Vec, config: &util::con } cl.retain(|x| !r.contains(&x)); + log!(1, verbosity, "LOG 1: Adding the following files to the list of unmapped files:\n{:?}", cl); res.1.append(&mut cl); // println!("{:?}", res); return res; @@ -126,8 +140,10 @@ fn check_mappings(mappings: Vec<(PathBuf, PathBuf)>, in_suffix: &str, out_suffix let mut res: Vec<(PathBuf, PathBuf)> = vec![]; for tup in &mappings { + log!(2, verbosity, "LOG 2: Verifying the mapping {:?}", tup); if !(tup.0.as_path().extension().unwrap() == in_suffix) || !(tup.1.as_path().extension().unwrap() == out_suffix) { res.push(tup.clone()); + log!(2, verbosity, "LOG 2: Added {:?} to the list of invalid mappings", tup); } } // println!("{:?}", res); @@ -146,12 +162,19 @@ fn collect_invalid(files: &Vec, suf: &str, verbosity: u8) -> Vec = vec![]; for file in files { + log!(2, verbosity, "LOG 2: Checking the validity of {} against the suffix {}:\n$${}$$\n$${}$$", + file.to_str().expect("failed to parse string"), + suf, + file.extension().expect("Failed to extract suffix").to_str().expect("Failed to parse string"), + suf); + let extension = file.extension().expect("Invalid file name for validation"); if extension.to_str() != Some(suf) { res.push(file.clone()); + log!(2, verbosity, "LOG 2: Added {} to invalid files", file.to_str().expect("failed to parse string")); } } - println!("{:?}", res); + // println!("{:?}", res); return res } /** @@ -164,6 +187,7 @@ fn collect_invalid(files: &Vec, suf: &str, verbosity: u8) -> Vec Result, &'static str> { let mut res: Vec = vec![]; + log!(2, verbosity, "LOG 2: Checking the directory {} for files", path.to_str().expect("failed to parse string")); // get the readout of the path for error handling let entries = match fs::read_dir(path) { Ok(x) => x, @@ -175,6 +199,7 @@ fn get_dir_files(path: &PathBuf, verbosity: u8) -> Result, &'static if p.path().is_dir() { (); } else { + log!(2, verbosity, "LOG 2: Found file {}", stringify!(p)); res.push(p.path()); } } From 29423ca691b2985e46fab6dde8acacf8c7439668 Mon Sep 17 00:00:00 2001 From: Ayrton Chilibeck Date: Mon, 15 Jan 2024 02:10:52 -0700 Subject: [PATCH 19/19] Printing and Formatting results --- src/validate.rs | 38 +++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/src/validate.rs b/src/validate.rs index f6f9188..2594df4 100644 --- a/src/validate.rs +++ b/src/validate.rs @@ -1,4 +1,5 @@ -use std::{path::{PathBuf, Path, Components, Component}, fs, collections::{HashMap, VecDeque}, borrow::BorrowMut}; +use std::{collections::VecDeque, fs}; +use std::path::{PathBuf, Component}; use crate::util; use crate::log; @@ -21,11 +22,11 @@ pub fn validate(verbosity: u8, config: util::config::Config) { // print the delinquints if invalid_suffix_in.len() > 0 { - print_invalid_suffixes(invalid_suffix_in, in_suffix, verbosity); + print_invalid_suffixes(invalid_suffix_in, in_suffix); } if invalid_suffix_out.len() > 0 { - print_invalid_suffixes(invalid_suffix_out, out_suffix, verbosity); + print_invalid_suffixes(invalid_suffix_out, out_suffix); } // make sure each has a match @@ -34,8 +35,8 @@ pub fn validate(verbosity: u8, config: util::config::Config) { log!(1, verbosity, "LOG 1:Verifying file matches"); let invalid: Vec<(PathBuf, PathBuf)> = check_mappings(in_to_out.0, in_suffix, out_suffix, verbosity); - print_unmached(in_to_out.1, verbosity); - print_invalid_pairs(invalid, in_suffix, out_suffix, verbosity); + print_unmached(in_to_out.1); + print_invalid_pairs(invalid, in_suffix, out_suffix); } /** @@ -213,10 +214,10 @@ fn get_dir_files(path: &PathBuf, verbosity: u8) -> Result, &'static * @param files: A vector containing the invalid path names * @param exp: The expected suffix */ -fn print_invalid_suffixes(files: Vec, exp: &str, verbosity: u8) { +fn print_invalid_suffixes(files: Vec, exp: &str) { println!("Invalid suffixes detected 😱:" ); println!("Current => Suggested"); - for mut file in files { + for file in files { let initial = match file.to_str() { Some(x) => x, _ => panic!("Failed to load the file"), @@ -235,8 +236,12 @@ fn print_invalid_suffixes(files: Vec, exp: &str, verbosity: u8) { * * @param unmatched: Unmatched files */ -fn print_unmached(unmatched: Vec, verbosity: u8) { +fn print_unmached(unmatched: Vec) { + println!("We were unable to find matches for the following files:"); + for file in unmatched { + println!("{}", file.to_str().expect("Failed to read file name")); + } } /** @@ -244,8 +249,19 @@ fn print_unmached(unmatched: Vec, verbosity: u8) { * * @param invalid: A vector of invalid pairs */ -fn print_invalid_pairs(invalid: Vec<(PathBuf, PathBuf)>, in_suffix: &str, out_suffix: &str, verbosity: u8) { +fn print_invalid_pairs(invalid: Vec<(PathBuf, PathBuf)>, in_suffix: &str, out_suffix: &str) { + println!("The following files have problematic mappings, please validate their suffixes and paths:"); + for pair in invalid { + println!("({} {}): $${}$$ => $${}$$ should be $${}$$ => $${}$$", + pair.0.to_str().expect("Failed to read file name"), + pair.1.to_str().expect("Failed to read file name"), + pair.0.extension().expect("Failed to read file name").to_str().expect("Failed to convert"), + pair.1.extension().expect("Failed to read file name").to_str().expect("Failed to convert"), + in_suffix, + out_suffix, + ); + } } @@ -315,7 +331,7 @@ mod tests { println!("{:?}", invalid); // visual testing for the print formatting - print_invalid_suffixes(invalid.clone(), suffix, 2); + print_invalid_suffixes(invalid.clone(), suffix); assert!(!invalid.contains(&files[0])); assert!(!invalid.contains(&files[1])); @@ -349,7 +365,7 @@ mod tests { let out_suffix = "out"; let invalid: Vec<(PathBuf, PathBuf)> = check_mappings(map_files(in_files.clone(), out_files.clone(), &config, 2).0, in_suffix, out_suffix, 2); - print_invalid_pairs(invalid.clone(), in_suffix, out_suffix, 2); + print_invalid_pairs(invalid.clone(), in_suffix, out_suffix); assert!(&invalid.contains(&(in_files[0].clone(), out_files[0].clone()))); assert!(&invalid.contains(&(in_files[1].clone(), out_files[1].clone()))); assert!(!&invalid.contains(&(in_files[2].clone(), out_files[2].clone())));