diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c39e374..955a7de 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -6,6 +6,7 @@ image: "rust:latest" variables: CARGO_HOME: $CI_PROJECT_DIR/.cargo PACKAGE_REGISTRY_URL: "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/fif" + RUSTFLAGS: "-C debuginfo=0" cache: paths: @@ -37,7 +38,7 @@ stages: script: - cargo install cargo-sweep - cargo sweep -i - - git -C $CI_PROJECT_DIR/.cargo/registry/index/github.com-1ecc6299db9ec823/ gc || true + - git -C $CI_PROJECT_DIR/.cargo/registry/index/github.com-1ecc6299db9ec823/ gc --aggressive || true # this builds a "base" version of fif with default features enabled. this is done separately from the main build step # for the purposes of caching - by building once *before* executing the parallel cargo-build step, we ensure that diff --git a/CHANGELOG.md b/CHANGELOG.md index 8385131..9cf868e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,10 +7,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## Unreleased ### Changed - Updated [`new_mime_guess`] to 4.0.0 +- `--version` output now handles missing Git commit hashes, and specifies the target operating system ### Fixed - Disabled [`smartstring`] test on unsupported architectures ### Other - Use [`parking_lot`]'s `RwLock` instead of the built-in one for a slight performance increase +- Added more command line argument tests ## v0.4.0 - 2021-10-14 ### Added diff --git a/Cargo.lock b/Cargo.lock index 9bd0eae..c24cf83 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,12 +2,35 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "aho-corasick" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +dependencies = [ + "memchr", +] + [[package]] name = "arrayvec" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" +[[package]] +name = "assert_cmd" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e996dc7940838b7ef1096b882e29ec30a3149a3a443cdc8dba19ed382eca1fe2" +dependencies = [ + "bstr", + "doc-comment", + "predicates", + "predicates-core", + "predicates-tree", + "wait-timeout", +] + [[package]] name = "atty" version = "0.2.14" @@ -31,6 +54,17 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bstr" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" +dependencies = [ + "lazy_static", + "memchr", + "regex-automata", +] + [[package]] name = "byteorder" version = "1.4.3" @@ -129,6 +163,12 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "difflib" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8" + [[package]] name = "dirs-next" version = "2.0.0" @@ -150,6 +190,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "doc-comment" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" + [[package]] name = "either" version = "1.6.1" @@ -177,6 +223,7 @@ checksum = "de853764b47027c2e862a995c34978ffa63c1501f2e15f987ba11bd4f9bba193" name = "fif" version = "0.4.0" dependencies = [ + "assert_cmd", "cfg-if", "clap", "clap_derive", @@ -193,6 +240,7 @@ dependencies = [ "parking_lot", "rand", "rayon", + "regex", "serde", "serde_json", "smartstring", @@ -471,6 +519,33 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" +[[package]] +name = "predicates" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95e5a7689e456ab905c22c2b48225bb921aba7c8dfa58440d68ba13f6222a715" +dependencies = [ + "difflib", + "itertools", + "predicates-core", +] + +[[package]] +name = "predicates-core" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57e35a3326b75e49aa85f5dc6ec15b41108cf5aee58eabb1f274dd18b73c2451" + +[[package]] +name = "predicates-tree" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "338c7be2905b732ae3984a2f40032b5e94fd8f52505b186c7d4d68d193445df7" +dependencies = [ + "predicates-core", + "termtree", +] + [[package]] name = "proc-macro-error" version = "1.0.4" @@ -597,6 +672,29 @@ dependencies = [ "redox_syscall", ] +[[package]] +name = "regex" +version = "1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" + +[[package]] +name = "regex-syntax" +version = "0.6.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" + [[package]] name = "remove_dir_all" version = "0.5.3" @@ -739,6 +837,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "termtree" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13a4ec180a2de59b57434704ccfad967f789b12737738798fa08798cd5824c16" + [[package]] name = "textwrap" version = "0.12.1" @@ -820,6 +924,15 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "wait-timeout" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +dependencies = [ + "libc", +] + [[package]] name = "walkdir" version = "2.3.2" diff --git a/Cargo.toml b/Cargo.toml index 2ba2e3b..a155ca1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -78,6 +78,8 @@ features = ["termcolor", "atty"] [dev-dependencies] tempfile = "3.2.0" rand = "0.8.3" +assert_cmd = "2.0.2" +regex = "1.5.4" [profile.release] lto = "thin" diff --git a/src/tests/mod.rs b/src/tests/mod.rs index 3b77b09..5e624e8 100644 --- a/src/tests/mod.rs +++ b/src/tests/mod.rs @@ -294,6 +294,7 @@ fn exclude_set_overrides_include_set() { #[test] /// Ensure that badly formed command line arguments are rejected. fn rejects_bad_args() { + use assert_cmd::Command; let tests = [ // Non-existent flags: vec!["fif", "-abcdefghijklmnopqrstuvwxyz"], @@ -314,10 +315,67 @@ fn rejects_bad_args() { ]; for test in &tests { + // first, try testing the flags against the Parameters struct... assert!(Parameters::try_parse_from(test).is_err(), "Failed to reject {:?}", test); + // ...then, make sure it actually works against the binary + let mut cmd = Command::cargo_bin("fif").unwrap(); + cmd.args(test).assert().failure(); } } +#[test] +/// Ensure that a few simple, well-formed command line argument cases pass +fn accepts_good_args() { + use assert_cmd::Command; + + // all of these commands pass either the version or help flag, ensuring that they won't fail for reasons relating + // to filesystem access + let tests = [ + vec!["-V"], + vec!["--version"], + vec!["-E", "images", "--version"], + vec!["-h"], + vec!["--help"], + vec!["dir_name", "--version"], + ]; + + for test in &tests { + let mut cmd = Command::cargo_bin("fif").unwrap(); + cmd.args(test).assert().success(); + } +} + +#[test] +/// Ensures that output from the `-V` and `--version` flags is formatted properly. +fn check_version_output() { + use std::string::String; + use assert_cmd::Command; + use regex::Regex; + + // test `-V` matches the format of "fif x.y.z" + let mut cmd = Command::cargo_bin("fif").unwrap(); + let output = cmd.arg("-V").ok().unwrap().stdout; + let output = String::from_utf8(output).unwrap(); + assert!( + Regex::new(r#"fif v(\d\.){2}\d"#).unwrap().is_match(&output.trim()), + "\"{}\" does not match the expected `-v` format!", + output + ); + + + // test `--version` matches the format of "fif x.y.z (OS, example backend, commit #1234abc)" + let mut cmd = Command::cargo_bin("fif").unwrap(); + let output = cmd.arg("--version").ok().unwrap().stdout; + let output = String::from_utf8(output).unwrap(); + assert!( + Regex::new(r#"fif v(\d\.){2}\d \(.+, .+ backend, (unknown commit|commit #[\da-f]{7})\)"#) + .unwrap() + .is_match(&output.trim()), + "\"{}\" does not match the expected `--version` format!", + output.trim() + ); +} + #[test] /// Generate random series of bytes and try to identify them. This test makes no assertions and can only fail if the /// mime database somehow panics or hangs. diff --git a/src/utils.rs b/src/utils.rs index 51ad095..4477889 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -36,7 +36,7 @@ pub static CLAP_LONG_VERSION: Lazy = Lazy::new(|| { _ => String::from("unknown commit"), }; - format!("v{} ({} backend, {})", VERSION.unwrap_or("???"), BACKEND, commit).into() + format!("v{} ({}, {} backend, {})", VERSION.unwrap_or("???"), os_name(), BACKEND, commit).into() }); /// A [`Mime`] representing the "application/zip" MIME type.