From ec7b8e5e67de9ddc8707c5ed18d1c1aea4f9298e Mon Sep 17 00:00:00 2001 From: Diego Ongaro Date: Thu, 1 Feb 2024 14:28:44 -0800 Subject: [PATCH 1/3] Switch from insta to lighter/simpler expect-test --- Cargo.lock | 64 +---- Cargo.toml | 10 +- src/bin/system_test/main.rs | 26 +- src/cli.rs | 254 +++++++++--------- src/docker.rs | 16 +- src/packages/manifest.rs | 106 ++++---- src/randname.rs | 14 +- .../cub__cli__tests__usage_completions.snap | 5 - src/snapshots/cub__cli__tests__usage_cub.snap | 5 - .../cub__cli__tests__usage_enter.snap | 5 - .../cub__cli__tests__usage_exec.snap | 5 - .../cub__cli__tests__usage_list.snap | 5 - src/snapshots/cub__cli__tests__usage_new.snap | 5 - .../cub__cli__tests__usage_package list.snap | 5 - ...cub__cli__tests__usage_package update.snap | 5 - .../cub__cli__tests__usage_package.snap | 5 - .../cub__cli__tests__usage_purge.snap | 5 - .../cub__cli__tests__usage_reset.snap | 5 - src/snapshots/cub__cli__tests__usage_tmp.snap | 5 - ...b__cli__tests__write_completions_bash.snap | 5 - ...ub__cli__tests__write_completions_zsh.snap | 5 - .../cubicle__docker__tests__Dockerfile.snap | 5 - src/somehow.rs | 56 ++-- 23 files changed, 250 insertions(+), 371 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4eb5916..df9727e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -249,18 +249,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" -[[package]] -name = "console" -version = "0.15.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" -dependencies = [ - "encode_unicode", - "lazy_static", - "libc", - "windows-sys 0.52.0", -] - [[package]] name = "core-foundation" version = "0.9.4" @@ -304,8 +292,8 @@ dependencies = [ "cap-std", "clap", "clap_complete", + "expect-test", "indoc", - "insta", "lazy_static", "rand", "regex", @@ -333,10 +321,10 @@ dependencies = [ ] [[package]] -name = "encode_unicode" -version = "0.3.6" +name = "dissimilar" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" +checksum = "86e3bdc80eee6e16b2b6b0f87fbc98c04bee3455e35174c0de1a125d0688c632" [[package]] name = "encoding_rs" @@ -363,6 +351,16 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "expect-test" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30d9eafeadd538e68fb28016364c9732d78e420b9ff8853fa5e4058861e9f8d3" +dependencies = [ + "dissimilar", + "once_cell", +] + [[package]] name = "fastrand" version = "2.0.1" @@ -631,19 +629,6 @@ version = "2.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e186cfbae8084e513daff4240b4797e342f988cecda4fb6c939150f96315fd8" -[[package]] -name = "insta" -version = "1.34.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d64600be34b2fcfc267740a243fa7744441bb4947a619ac4e5bb6507f35fbfc" -dependencies = [ - "console", - "lazy_static", - "linked-hash-map", - "similar", - "yaml-rust", -] - [[package]] name = "io-extras" version = "0.18.1" @@ -693,12 +678,6 @@ version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" -[[package]] -name = "linked-hash-map" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" - [[package]] name = "linux-raw-sys" version = "0.4.13" @@ -1142,12 +1121,6 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" -[[package]] -name = "similar" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32fea41aca09ee824cc9724996433064c89f7777e60762749a4170a14abbfa21" - [[package]] name = "slab" version = "0.4.9" @@ -1695,12 +1668,3 @@ dependencies = [ "linux-raw-sys", "rustix", ] - -[[package]] -name = "yaml-rust" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" -dependencies = [ - "linked-hash-map", -] diff --git a/Cargo.toml b/Cargo.toml index 1381847..7bc995d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ clap = { version = "4.4.18", features = ["derive", "wrap_help"] } clap_complete = "4.4.9" indoc = "2.0.4" # this is a dev-dependency but needed in `system_test` bin -insta = "1.34.0" +expect-test = "1.4.1" lazy_static = "1.4.0" rand = "0.8.5" regex = "1.10.3" @@ -41,11 +41,3 @@ toml = "0.8.9" wildmatch = "2.3.0" [dev-dependencies] - -# See https://docs.rs/insta/latest/insta/#optional-faster-runs -[profile.dev.package.insta] -opt-level = 3 - -# See https://docs.rs/insta/latest/insta/#optional-faster-runs -[profile.dev.package.similar] -opt-level = 3 diff --git a/src/bin/system_test/main.rs b/src/bin/system_test/main.rs index b1c8c12..a35651a 100644 --- a/src/bin/system_test/main.rs +++ b/src/bin/system_test/main.rs @@ -15,7 +15,7 @@ use cubicle::{ Cubicle, EnvironmentName, FullPackageName, ListFormat, ListPackagesFormat, Quiet, ShouldPackageUpdate, UpdatePackagesConditions, }; -use insta::assert_snapshot; +use expect_test::expect; use std::collections::BTreeSet; use std::path::{Path, PathBuf}; use std::str::FromStr; @@ -51,10 +51,8 @@ fn test_package_not_found_errors(cub: &Cubicle, test_env: &EnvironmentName) -> R let err = cub .new_environment(test_env, Some(¬_exist)) .expect_err("should not be able to use does-not-exist package in `cub new`"); - assert_snapshot!( - err.debug_without_backtrace(), - @r###"could not find package definition for "does-not-exist""### - ); + expect![[r#"could not find package definition for "does-not-exist""#]] + .assert_eq(&err.debug_without_backtrace()); let envs = cub.get_environment_names()?; assert!( @@ -66,10 +64,8 @@ fn test_package_not_found_errors(cub: &Cubicle, test_env: &EnvironmentName) -> R let err = cub .create_enter_tmp_environment(Some(¬_exist)) .expect_err("should not be able to use does-not-exist package in `cub tmp`"); - assert_snapshot!( - err.debug_without_backtrace(), - @r###"could not find package definition for "does-not-exist""### - ); + expect![[r#"could not find package definition for "does-not-exist""#]] + .assert_eq(&err.debug_without_backtrace()); let new_envs = cub .get_environment_names()? .difference(&envs) @@ -86,10 +82,8 @@ fn test_package_not_found_errors(cub: &Cubicle, test_env: &EnvironmentName) -> R let err = cub .reset_environment(test_env, Some(¬_exist)) .expect_err("should not be able to use does-not-exist package in `cub reset`"); - assert_snapshot!( - err.debug_without_backtrace(), - @r###"could not find package definition for "does-not-exist""### - ); + expect![[r#"could not find package definition for "does-not-exist""#]] + .assert_eq(&err.debug_without_backtrace()); cub.exec_environment(test_env, &[String::from("cat"), String::from("../foo")]) .context("file `../foo` should still exist")?; @@ -104,10 +98,8 @@ fn test_package_not_found_errors(cub: &Cubicle, test_env: &EnvironmentName) -> R }, ) .expect_err("should not be able to use does-not-exist package in `cub tmp`"); - assert_snapshot!( - err.debug_without_backtrace(), - @r###"could not find package definition for "does-not-exist""### - ); + expect![[r#"could not find package definition for "does-not-exist""#]] + .assert_eq(&err.debug_without_backtrace()); Ok(()) } diff --git a/src/cli.rs b/src/cli.rs index aa50d06..db45699 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -582,7 +582,7 @@ where mod tests { use super::*; use clap::CommandFactory; - use insta::{assert_debug_snapshot, assert_display_snapshot, assert_snapshot}; + use expect_test::{expect, expect_file}; #[test] fn sub_home_prefix() { @@ -632,80 +632,82 @@ mod tests { FullPackageName::from_str("foobar").unwrap(), ]) }; - assert_debug_snapshot!(&super::package_set_from_patterns(&[], names()), @r###" - Ok( - {}, - ) - "###); - assert_debug_snapshot!( - &super::package_set_from_patterns( - &[String::from("foo")], - names() - ), - @r###" - Ok( - { - FullPackageName( - Root, - PackageName( - "foo", + + expect![[r#" + Ok( + {}, + ) + "#]] + .assert_debug_eq(&super::package_set_from_patterns(&[], names())); + + expect![[r#" + Ok( + { + FullPackageName( + Root, + PackageName( + "foo", + ), ), - ), - }, - ) - "### - ); - assert_debug_snapshot!( - &super::package_set_from_patterns( - &[String::from("foo*"), String::from("bar*")], - names() - ), - @r###" - Ok( - { - FullPackageName( - Root, - PackageName( - "foo", + }, + ) + "#]] + .assert_debug_eq(&super::package_set_from_patterns( + &[String::from("foo")], + names(), + )); + + expect![[r#" + Ok( + { + FullPackageName( + Root, + PackageName( + "foo", + ), ), - ), - FullPackageName( - Root, - PackageName( - "foobar", + FullPackageName( + Root, + PackageName( + "foobar", + ), ), - ), - }, - ) - "### - ); - assert_debug_snapshot!( - super::package_set_from_patterns(&[String::from("foo*"), String::from("baz")], names()), - @r###" - Ok( - { - FullPackageName( - Root, - PackageName( - "baz", + }, + ) + "#]] + .assert_debug_eq(&super::package_set_from_patterns( + &[String::from("foo*"), String::from("bar*")], + names(), + )); + + expect![[r#" + Ok( + { + FullPackageName( + Root, + PackageName( + "baz", + ), ), - ), - FullPackageName( - Root, - PackageName( - "foo", + FullPackageName( + Root, + PackageName( + "foo", + ), ), - ), - FullPackageName( - Root, - PackageName( - "foobar", + FullPackageName( + Root, + PackageName( + "foobar", + ), ), - ), - }, - ) - "### - ); + }, + ) + "#]] + .assert_debug_eq(&super::package_set_from_patterns( + &[String::from("foo*"), String::from("baz")], + names(), + )); } #[test] @@ -729,8 +731,11 @@ mod tests { .term_width(100) .try_get_matches_from(split_cmd) .unwrap_err(); - let name = format!("usage_{}", if cmd.is_empty() { "cub" } else { cmd }); - assert_display_snapshot!(name, err); + let name = format!( + "snapshots/cub__cli__tests__usage_{}.snap", + if cmd.is_empty() { "cub" } else { cmd } + ); + expect_file![name].assert_eq(&err.to_string()); } } @@ -740,7 +745,10 @@ mod tests { let mut buf: Vec = Vec::new(); super::write_completions(shell, &mut buf).unwrap(); let buf = String::from_utf8(buf).unwrap(); - assert_snapshot!(format!("write_completions_{shell}"), buf); + expect_file![format!( + "snapshots/cub__cli__tests__write_completions_{shell}.snap" + )] + .assert_eq(&buf); } } @@ -794,59 +802,59 @@ mod tests { EnvironmentName::from_str("foobar").unwrap(), ]) }; - assert_debug_snapshot!(&super::matching_environments(&[], names()), @r###" - Ok( - [], - ) - "###); - assert_debug_snapshot!( - &super::matching_environments( - &[EnvironmentPattern::from_str("foo").unwrap()], - names() - ), - @r###" - Ok( - [ - EnvironmentName( - "foo", - ), - ], - ) - "### - ); - assert_debug_snapshot!( - &super::matching_environments( - &[EnvironmentPattern::from_str("bar").unwrap()], - names() - ), - @r###" - Err( - "environment \"bar\" not found", - ) - "### - ); - assert_debug_snapshot!( - &super::matching_environments( - &[ - EnvironmentPattern::from_str("foo*").unwrap(), - EnvironmentPattern::from_str("bar*").unwrap(), - EnvironmentPattern::from_str("*").unwrap(), + + expect![[r#" + Ok( + [], + ) + "#]] + .assert_debug_eq(&super::matching_environments(&[], names())); + + expect![[r#" + Ok( + [ + EnvironmentName( + "foo", + ), ], - names() - ), - @r###" - Ok( - [ - EnvironmentName( - "foo", - ), - EnvironmentName( - "foobar", - ), + ) + "#]] + .assert_debug_eq(&super::matching_environments( + &[EnvironmentPattern::from_str("foo").unwrap()], + names(), + )); + + expect![[r#" + Err( + "environment \"bar\" not found", + ) + "#]] + .assert_debug_eq(&super::matching_environments( + &[EnvironmentPattern::from_str("bar").unwrap()], + names(), + )); + + expect![[r#" + Ok( + [ + EnvironmentName( + "foo", + ), + EnvironmentName( + "foobar", + ), + ], + ) + "#]] + .assert_debug_eq(&super::matching_environments( + &[ + EnvironmentPattern::from_str("foo*").unwrap(), + EnvironmentPattern::from_str("bar*").unwrap(), + EnvironmentPattern::from_str("*").unwrap(), ], - ) - "### - ); + names(), + )); + assert_eq!( super::matching_environments( &[ diff --git a/src/docker.rs b/src/docker.rs index d69a181..08f91b5 100644 --- a/src/docker.rs +++ b/src/docker.rs @@ -1132,18 +1132,18 @@ fn write_dockerfile(w: &mut W, args: DockerfileArgs) -> std::io::R #[cfg(test)] mod tests { use super::*; - use insta::assert_snapshot; + use expect_test::{expect, expect_file}; use std::path::PathBuf; #[test] fn fallback_path() { - assert_snapshot!( - super::fallback_path(&EnvPath::try_from(PathBuf::from("/home/foo")).unwrap()).to_string_lossy(), - @"PATH=/home/foo/bin:/usr/bin:/usr/sbin" + expect!["PATH=/home/foo/bin:/usr/bin:/usr/sbin"].assert_eq( + &super::fallback_path(&EnvPath::try_from(PathBuf::from("/home/foo")).unwrap()) + .to_string_lossy(), ); - assert_snapshot!( - super::fallback_path(&EnvPath::try_from(PathBuf::from("/home/fo:oo")).unwrap()).to_string_lossy(), - @"PATH=/usr/bin:/usr/sbin" + expect!["PATH=/usr/bin:/usr/sbin"].assert_eq( + &super::fallback_path(&EnvPath::try_from(PathBuf::from("/home/fo:oo")).unwrap()) + .to_string_lossy(), ); } @@ -1164,6 +1164,6 @@ mod tests { ) .unwrap(); let dockerfile = String::from_utf8(buf).unwrap(); - assert_snapshot!("Dockerfile", dockerfile); + expect_file!["snapshots/cubicle__docker__tests__Dockerfile.snap"].assert_eq(&dockerfile); } } diff --git a/src/packages/manifest.rs b/src/packages/manifest.rs index 8847f8d..e0f089d 100644 --- a/src/packages/manifest.rs +++ b/src/packages/manifest.rs @@ -114,7 +114,7 @@ fn convert_table(table: BTreeMap) -> Result @@ -21,4 +17,3 @@ Commands: Options: -c, --config Path to configuration file [default: $HOME/.config/cubicle.toml] -h, --help Print help - diff --git a/src/snapshots/cub__cli__tests__usage_enter.snap b/src/snapshots/cub__cli__tests__usage_enter.snap index 27b5a17..e7e8cf9 100644 --- a/src/snapshots/cub__cli__tests__usage_enter.snap +++ b/src/snapshots/cub__cli__tests__usage_enter.snap @@ -1,7 +1,3 @@ ---- -source: src/cli.rs -expression: err ---- Run a shell in an existing environment Usage: cub enter @@ -16,4 +12,3 @@ Arguments: Options: -h, --help Print help (see a summary with '-h') - diff --git a/src/snapshots/cub__cli__tests__usage_exec.snap b/src/snapshots/cub__cli__tests__usage_exec.snap index f3531dd..628f944 100644 --- a/src/snapshots/cub__cli__tests__usage_exec.snap +++ b/src/snapshots/cub__cli__tests__usage_exec.snap @@ -1,7 +1,3 @@ ---- -source: src/cli.rs -expression: err ---- Run a command in an existing environment Usage: cub exec -- ... @@ -19,4 +15,3 @@ Arguments: Options: -h, --help Print help (see a summary with '-h') - diff --git a/src/snapshots/cub__cli__tests__usage_list.snap b/src/snapshots/cub__cli__tests__usage_list.snap index 9ad3d14..9e4a6fd 100644 --- a/src/snapshots/cub__cli__tests__usage_list.snap +++ b/src/snapshots/cub__cli__tests__usage_list.snap @@ -1,7 +1,3 @@ ---- -source: src/cli.rs -expression: err ---- Show existing environments Usage: cub list [OPTIONS] @@ -19,4 +15,3 @@ Options: -h, --help Print help (see a summary with '-h') - diff --git a/src/snapshots/cub__cli__tests__usage_new.snap b/src/snapshots/cub__cli__tests__usage_new.snap index f5b87b2..2325fa0 100644 --- a/src/snapshots/cub__cli__tests__usage_new.snap +++ b/src/snapshots/cub__cli__tests__usage_new.snap @@ -1,7 +1,3 @@ ---- -source: src/cli.rs -expression: err ---- Create a new environment Usage: cub new [OPTIONS] @@ -24,4 +20,3 @@ Options: -h, --help Print help (see a summary with '-h') - diff --git a/src/snapshots/cub__cli__tests__usage_package list.snap b/src/snapshots/cub__cli__tests__usage_package list.snap index b8e2097..9d36dc7 100644 --- a/src/snapshots/cub__cli__tests__usage_package list.snap +++ b/src/snapshots/cub__cli__tests__usage_package list.snap @@ -1,7 +1,3 @@ ---- -source: src/cli.rs -expression: err ---- Show available packages Usage: cub package list [OPTIONS] @@ -19,4 +15,3 @@ Options: -h, --help Print help (see a summary with '-h') - diff --git a/src/snapshots/cub__cli__tests__usage_package update.snap b/src/snapshots/cub__cli__tests__usage_package update.snap index a8685b6..e4bb94c 100644 --- a/src/snapshots/cub__cli__tests__usage_package update.snap +++ b/src/snapshots/cub__cli__tests__usage_package update.snap @@ -1,7 +1,3 @@ ---- -source: src/cli.rs -expression: err ---- (Re-)build one or more packages Usage: cub package update [OPTIONS] ... @@ -28,4 +24,3 @@ Options: -h, --help Print help (see a summary with '-h') - diff --git a/src/snapshots/cub__cli__tests__usage_package.snap b/src/snapshots/cub__cli__tests__usage_package.snap index 04deff8..d4d9c3d 100644 --- a/src/snapshots/cub__cli__tests__usage_package.snap +++ b/src/snapshots/cub__cli__tests__usage_package.snap @@ -1,7 +1,3 @@ ---- -source: src/cli.rs -expression: err ---- View and manage packages Usage: cub package @@ -13,4 +9,3 @@ Commands: Options: -h, --help Print help - diff --git a/src/snapshots/cub__cli__tests__usage_purge.snap b/src/snapshots/cub__cli__tests__usage_purge.snap index f80fd99..9830986 100644 --- a/src/snapshots/cub__cli__tests__usage_purge.snap +++ b/src/snapshots/cub__cli__tests__usage_purge.snap @@ -1,7 +1,3 @@ ---- -source: src/cli.rs -expression: err ---- Delete environment(s) and their work directories Usage: cub purge ... @@ -16,4 +12,3 @@ Arguments: Options: -h, --help Print help (see a summary with '-h') - diff --git a/src/snapshots/cub__cli__tests__usage_reset.snap b/src/snapshots/cub__cli__tests__usage_reset.snap index 7c6b05f..ba5b97c 100644 --- a/src/snapshots/cub__cli__tests__usage_reset.snap +++ b/src/snapshots/cub__cli__tests__usage_reset.snap @@ -1,7 +1,3 @@ ---- -source: src/cli.rs -expression: err ---- Recreate an environment (keeping only its work directory) Usage: cub reset [OPTIONS] ... @@ -25,4 +21,3 @@ Options: -h, --help Print help (see a summary with '-h') - diff --git a/src/snapshots/cub__cli__tests__usage_tmp.snap b/src/snapshots/cub__cli__tests__usage_tmp.snap index 2a59f3a..5339328 100644 --- a/src/snapshots/cub__cli__tests__usage_tmp.snap +++ b/src/snapshots/cub__cli__tests__usage_tmp.snap @@ -1,7 +1,3 @@ ---- -source: src/cli.rs -expression: err ---- Create and enter a new temporary environment Usage: cub tmp [OPTIONS] @@ -17,4 +13,3 @@ Options: -h, --help Print help (see a summary with '-h') - diff --git a/src/snapshots/cub__cli__tests__write_completions_bash.snap b/src/snapshots/cub__cli__tests__write_completions_bash.snap index ba710b0..65c9789 100644 --- a/src/snapshots/cub__cli__tests__write_completions_bash.snap +++ b/src/snapshots/cub__cli__tests__write_completions_bash.snap @@ -1,7 +1,3 @@ ---- -source: src/cli.rs -expression: buf ---- _cub() { local i cur prev opts cmd COMPREPLY=() @@ -554,4 +550,3 @@ if [[ "${BASH_VERSINFO[0]}" -eq 4 && "${BASH_VERSINFO[1]}" -ge 4 || "${BASH_VERS else complete -F _cub -o bashdefault -o default cub fi - diff --git a/src/snapshots/cub__cli__tests__write_completions_zsh.snap b/src/snapshots/cub__cli__tests__write_completions_zsh.snap index 5788208..3a97df9 100644 --- a/src/snapshots/cub__cli__tests__write_completions_zsh.snap +++ b/src/snapshots/cub__cli__tests__write_completions_zsh.snap @@ -1,7 +1,3 @@ ---- -source: src/cli.rs -expression: buf ---- #compdef cub autoload -U is-at-least @@ -434,4 +430,3 @@ if [ "$funcstack[1]" = "_cub" ]; then else compdef _cub cub fi - diff --git a/src/snapshots/cubicle__docker__tests__Dockerfile.snap b/src/snapshots/cubicle__docker__tests__Dockerfile.snap index 57b3d59..b597c07 100644 --- a/src/snapshots/cubicle__docker__tests__Dockerfile.snap +++ b/src/snapshots/cubicle__docker__tests__Dockerfile.snap @@ -1,7 +1,3 @@ ---- -source: src/docker.rs -expression: dockerfile ---- FROM debian:12 RUN echo "Etc/Timez'one" > /etc/timezone && \ ln -fs '/usr/share/zoneinfo/'"Etc/Timez'one" /etc/localtime @@ -20,4 +16,3 @@ RUN apt-get install --no-install-recommends --yes \ RUN apt-file update RUN sh -c 'echo "Defaults umask = 0027" > /etc/sudoers.d/umask' && \ sh -c 'echo "%sudo ALL=(ALL) CWD=* NOPASSWD: ALL" > /etc/sudoers.d/nopasswd' - diff --git a/src/somehow.rs b/src/somehow.rs index 1e0fca4..e86b91d 100644 --- a/src/somehow.rs +++ b/src/somehow.rs @@ -317,24 +317,20 @@ pub fn warn_brief(warning: String) { #[cfg(test)] mod tests { use super::{Context, Error, Result}; - use insta::assert_snapshot; + use expect_test::expect; #[test] fn debug_without_backtrace() { - assert_snapshot!( - somehow!("ants in pants").debug_without_backtrace(), - @"ants in pants" - ); - assert_snapshot!( - somehow!("ants in pants") + expect!["ants in pants"].assert_eq(&somehow!("ants in pants").debug_without_backtrace()); + expect![[r#" + checking for ants + + Caused by: + ants in pants"#]] + .assert_eq( + &somehow!("ants in pants") .context("checking for ants") .debug_without_backtrace(), - @r###" - checking for ants - - Caused by: - ants in pants - "### ); } @@ -355,7 +351,7 @@ mod tests { Err(MyError)? }; let err = make_err().unwrap_err().debug_without_backtrace(); - assert_snapshot!(err, @"MyError"); + assert_eq!("MyError", err); } #[test] @@ -366,14 +362,14 @@ mod tests { Err(std::io::Error::from(std::io::ErrorKind::UnexpectedEof))? }; let err = make_err().unwrap_err().debug_without_backtrace(); - assert_snapshot!(err, @r###" - The cause of this error lacks context. You can set RUST_BACKTRACE=1 for more - info. A pull request or a GitHub issue with this output and the steps to - reproduce it would be welcome. - - Caused by: - unexpected end of file - "###); + expect![[r#" + The cause of this error lacks context. You can set RUST_BACKTRACE=1 for more + info. A pull request or a GitHub issue with this output and the steps to + reproduce it would be welcome. + + Caused by: + unexpected end of file"#]] + .assert_eq(&err); } #[test] @@ -382,13 +378,13 @@ mod tests { Err(std::io::Error::from(std::io::ErrorKind::UnexpectedEof)); let err: Error = err.todo_context().unwrap_err(); let err = err.debug_without_backtrace(); - assert_snapshot!(err, @r###" - The cause of this error lacks context. You can set RUST_BACKTRACE=1 for more - info. A pull request or a GitHub issue with this output and the steps to - reproduce it would be welcome. - - Caused by: - unexpected end of file - "###); + expect![[r#" + The cause of this error lacks context. You can set RUST_BACKTRACE=1 for more + info. A pull request or a GitHub issue with this output and the steps to + reproduce it would be welcome. + + Caused by: + unexpected end of file"#]] + .assert_eq(&err); } } From b28a39382560e6e5b946b9bd8d77efb096035664 Mon Sep 17 00:00:00 2001 From: Diego Ongaro Date: Thu, 1 Feb 2024 14:41:44 -0800 Subject: [PATCH 2/3] Drop `lazy_static` in favor of `std::sync::OnceLock` --- Cargo.lock | 1 - Cargo.toml | 2 +- src/apt.rs | 13 +++++++------ src/config.rs | 25 +++++++++++++------------ src/docker.rs | 17 +++++++++-------- src/os_util.rs | 8 +++----- 6 files changed, 33 insertions(+), 33 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index df9727e..4ad18f1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -294,7 +294,6 @@ dependencies = [ "clap_complete", "expect-test", "indoc", - "lazy_static", "rand", "regex", "reqwest", diff --git a/Cargo.toml b/Cargo.toml index 7bc995d..4d9282c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ repository = "https://github.com/ongardie/cubicle" default-run = "cub" edition = "2021" +rust-version = "1.75" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -25,7 +26,6 @@ clap_complete = "4.4.9" indoc = "2.0.4" # this is a dev-dependency but needed in `system_test` bin expect-test = "1.4.1" -lazy_static = "1.4.0" rand = "0.8.5" regex = "1.10.3" reqwest = { version = "0.11.24", features = ["blocking"] } diff --git a/src/apt.rs b/src/apt.rs index 4a4c128..bb0c5af 100644 --- a/src/apt.rs +++ b/src/apt.rs @@ -1,6 +1,6 @@ -use lazy_static::lazy_static; use regex::{Regex, RegexBuilder}; use std::str::FromStr; +use std::sync::OnceLock; use crate::command_ext::Command; use crate::somehow::{somehow as anyhow, warn, Context, Result}; @@ -54,15 +54,16 @@ pub fn simulate_satisfy(deps: &[&str]) -> Result { let stdout = String::from_utf8(output.stdout) .context("failed to read `apt-get satisfy --dry-run ...` output")?; - lazy_static! { - static ref RE: Regex = RegexBuilder::new( + static RE: OnceLock = OnceLock::new(); + let re = RE.get_or_init(|| + RegexBuilder::new( r#"^([0-9]+) upgraded, ([0-9]+) newly installed, ([0-9]+) to remove and ([0-9]+) not upgraded.$"# ) .multi_line(true) .build() - .unwrap(); - } - match RE.captures(&stdout) { + .unwrap()); + + match re.captures(&stdout) { Some(caps) => { let count = |i| usize::from_str(caps.get(i).unwrap().as_str()).unwrap(); Ok(Summary { diff --git a/src/config.rs b/src/config.rs index c8c8185..be432c1 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,10 +1,10 @@ //! Main Cubicle program configuration. -use lazy_static::lazy_static; use regex::{Regex, RegexBuilder}; use serde::{Deserialize, Deserializer}; use std::path::{Path, PathBuf}; use std::str::FromStr; +use std::sync::OnceLock; use std::time::Duration; use super::os_util::host_home_dir; @@ -72,8 +72,14 @@ where { use serde::de::Error; - lazy_static! { - static ref RE: Regex = RegexBuilder::new( + let s = String::deserialize(deserializer)?; + if s == "never" { + return Ok(None); + } + + static RE: OnceLock = OnceLock::new(); + let re = RE.get_or_init(|| { + RegexBuilder::new( r#"^(?x) # integer or decimal (?P @@ -89,18 +95,13 @@ where h | hr s? | hour s? | d | day s? ) - $"# + $"#, ) .build() - .unwrap(); - } - - let s = String::deserialize(deserializer)?; - if s == "never" { - return Ok(None); - } + .unwrap() + }); - match RE.captures(&s) { + match re.captures(&s) { Some(caps) => { let value = caps.name("value").unwrap().as_str(); let value = f64::from_str(value).unwrap(); diff --git a/src/docker.rs b/src/docker.rs index 08f91b5..6db49da 100644 --- a/src/docker.rs +++ b/src/docker.rs @@ -1,4 +1,3 @@ -use lazy_static::lazy_static; use regex::{Regex, RegexBuilder}; use std::collections::BTreeSet; use std::ffi::{OsStr, OsString}; @@ -7,6 +6,7 @@ use std::path::Path; use std::process::Stdio; use std::rc::Rc; use std::str::FromStr; +use std::sync::OnceLock; use std::time::{Duration, UNIX_EPOCH}; use super::command_ext::Command; @@ -510,13 +510,14 @@ impl Docker { let stdout = String::from_utf8(output.stdout) .context("failed to read `docker run ... -- du ...` output")?; - lazy_static! { - static ref RE: Regex = - RegexBuilder::new(r#"^(?P[0-9]+)\t(?P[0-9]+)\t/v$"#) - .build() - .unwrap(); - } - match RE.captures(stdout.trim_end()) { + static RE: OnceLock = OnceLock::new(); + let re = RE.get_or_init(|| { + RegexBuilder::new(r#"^(?P[0-9]+)\t(?P[0-9]+)\t/v$"#) + .build() + .unwrap() + }); + + match re.captures(stdout.trim_end()) { Some(caps) => { let size = caps.name("size").unwrap().as_str(); let size = u64::from_str(size).unwrap(); diff --git a/src/os_util.rs b/src/os_util.rs index eaf92b3..bb6275b 100644 --- a/src/os_util.rs +++ b/src/os_util.rs @@ -1,7 +1,7 @@ -use lazy_static::lazy_static; use std::ffi::OsStr; use std::fmt::Write; use std::path::Path; +use std::sync::OnceLock; use super::HostPath; use crate::somehow::{somehow as anyhow, warn, Context, Error}; @@ -18,12 +18,10 @@ fn get_home_dir() -> HostPath { } } -lazy_static! { - static ref HOME_DIR: HostPath = get_home_dir(); -} +static HOME_DIR: OnceLock = OnceLock::new(); pub fn host_home_dir() -> &'static HostPath { - &HOME_DIR + HOME_DIR.get_or_init(get_home_dir) } pub struct Uids { From 4b3ee1e1088372b76120d137c86557c64763d438 Mon Sep 17 00:00:00 2001 From: Diego Ongaro Date: Thu, 1 Feb 2024 14:48:47 -0800 Subject: [PATCH 3/3] Switch to clippy lints table in Cargo.toml --- Cargo.toml | 9 ++++ src/bin/gen_github_yaml.rs | 10 ---- src/lib.rs | 9 ---- src/main.rs | 10 ---- tests/file_header.rs | 103 ------------------------------------- 5 files changed, 9 insertions(+), 132 deletions(-) delete mode 100644 tests/file_header.rs diff --git a/Cargo.toml b/Cargo.toml index 4d9282c..9425b62 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,3 +41,12 @@ toml = "0.8.9" wildmatch = "2.3.0" [dev-dependencies] + +[lints.clippy] +explicit_into_iter_loop = "warn" +explicit_iter_loop = "warn" +if_then_some_else_none = "warn" +implicit_clone = "warn" +redundant_else = "warn" +try_err = "warn" +unreadable_literal = "warn" diff --git a/src/bin/gen_github_yaml.rs b/src/bin/gen_github_yaml.rs index ffffc8a..e411ce9 100644 --- a/src/bin/gen_github_yaml.rs +++ b/src/bin/gen_github_yaml.rs @@ -1,13 +1,3 @@ -#![warn( - clippy::explicit_into_iter_loop, - clippy::explicit_iter_loop, - clippy::if_then_some_else_none, - clippy::implicit_clone, - clippy::redundant_else, - clippy::try_err, - clippy::unreadable_literal -)] - //! This program generates `.github/workflows/main.yaml`, used by GitHub //! Actions. This program is a development time utility that is part of the //! Cubicle project. diff --git a/src/lib.rs b/src/lib.rs index 92af493..b9b42a1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,12 +1,3 @@ -#![warn( - clippy::explicit_into_iter_loop, - clippy::explicit_iter_loop, - clippy::if_then_some_else_none, - clippy::implicit_clone, - clippy::redundant_else, - clippy::try_err, - clippy::unreadable_literal -)] #![warn(missing_docs)] //! This crate is the library underneath the Cubicle command-line program. diff --git a/src/main.rs b/src/main.rs index ff89b81..9c72926 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,13 +1,3 @@ -#![warn( - clippy::explicit_into_iter_loop, - clippy::explicit_iter_loop, - clippy::if_then_some_else_none, - clippy::implicit_clone, - clippy::redundant_else, - clippy::try_err, - clippy::unreadable_literal -)] - mod cli; use cubicle::{config::Config, Cubicle, Result}; diff --git a/tests/file_header.rs b/tests/file_header.rs deleted file mode 100644 index 499170e..0000000 --- a/tests/file_header.rs +++ /dev/null @@ -1,103 +0,0 @@ -#![warn( - clippy::explicit_into_iter_loop, - clippy::explicit_iter_loop, - clippy::if_then_some_else_none, - clippy::implicit_clone, - clippy::redundant_else, - clippy::try_err, - clippy::unreadable_literal -)] -// END OF HEADER - -//! This test ensures that each of the files that form crate roots of cargo -//! targets (see ) -//! start with the header at the top of this file. -//! -//! The purpose of this is to ensure the entire project is checked by the same -//! Clippy lints. Currently (2022), Clippy configs must be defined in every -//! crate root or every invocation to `cargo clippy`. -//! -//! There is a vague plan to allow Clippy to be configured globally by Cargo -//! but not much progress yet. See -//! and -//! . -//! -//! The problems with using command-line arguments is that it's easy to forget -//! them, and editors and such need to be reconfigured. - -// Needed for `std::process::Command`, which the library has an internal -// wrapper around. -#![allow(clippy::disallowed_types)] - -use serde::Deserialize; -use std::path::{Path, PathBuf}; -use std::process::Command; - -use cubicle::somehow::{Context, Result}; - -fn targets(manifest_dir: &Path) -> Result> { - #[derive(Debug, Deserialize)] - struct Metadata { - packages: Vec, - } - - #[derive(Debug, Deserialize)] - struct Package { - targets: Vec, - } - - #[derive(Debug, Deserialize)] - struct Target { - src_path: PathBuf, - } - - // This can alternatively be done with the cargo package, but that - // package takes a while to build. - let output = Command::new("cargo") - .arg("metadata") - .arg("--format-version=1") - .arg("--no-deps") - .output() - .todo_context()?; - assert!(output.status.success(), "cargo metadata failed"); - - let metadata: Metadata = - serde_json::from_slice(&output.stdout).context("failed to parse `cargo metadata` JSON")?; - let mut roots = Vec::new(); - for package in metadata.packages { - for target in package.targets { - roots.push(target.src_path); - } - } - - // check some known paths to make sure they're included - for path in [ - "src/lib.rs", - "src/main.rs", - "src/bin/system_test/main.rs", - file!(), - ] { - let path = manifest_dir.join(path); - assert!(&roots.contains(&path)); - } - - Ok(roots) -} - -#[test] -fn roots() -> Result<()> { - let manifest_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")); - - let source = std::fs::read_to_string(manifest_dir.join(file!())).todo_context()?; - let (header, _) = source - .split_once("// END OF HEADER") - .expect("should have END OF HEADER comment"); - - for target in targets(&manifest_dir)? { - let source = std::fs::read_to_string(&target).todo_context()?; - let ok = source.starts_with(header); - assert!(ok, "{target:?} should start with exact header:\n{header}"); - } - - Ok(()) -}