diff --git a/Cargo.lock b/Cargo.lock index 2ba00ad..dbf8a49 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -94,6 +94,12 @@ version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +[[package]] +name = "bitflags" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" + [[package]] name = "block-buffer" version = "0.10.4" @@ -289,6 +295,15 @@ dependencies = [ "crypto-common", ] +[[package]] +name = "dir-diff" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7ad16bf5f84253b50d6557681c58c3ab67c47c77d39fed9aeb56e947290bd10" +dependencies = [ + "walkdir", +] + [[package]] name = "doc-comment" version = "0.3.3" @@ -307,6 +322,22 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" +[[package]] +name = "errno" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "fastrand" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" + [[package]] name = "flate2" version = "1.0.28" @@ -395,6 +426,12 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "indoc" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5" + [[package]] name = "inout" version = "0.1.3" @@ -453,6 +490,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "linux-raw-sys" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" + [[package]] name = "log" version = "0.4.21" @@ -652,8 +695,10 @@ dependencies = [ "assert_cmd", "base64", "clap", + "dir-diff", "hex", "indicatif", + "indoc", "itertools", "path-clean", "path-slash", @@ -661,6 +706,7 @@ dependencies = [ "repak", "sha2", "strum", + "tempfile", ] [[package]] @@ -678,6 +724,19 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "rustix" +version = "0.38.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + [[package]] name = "rustls" version = "0.22.4" @@ -715,6 +774,15 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "80af6f9131f277a45a3fba6ce8e2258037bb0477a67e610d3c1fe046ab31de47" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "seq-macro" version = "0.3.5" @@ -825,6 +893,18 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "tempfile" +version = "3.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +dependencies = [ + "cfg-if", + "fastrand", + "rustix", + "windows-sys", +] + [[package]] name = "termtree" version = "0.4.1" @@ -954,6 +1034,16 @@ dependencies = [ "libc", ] +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -985,6 +1075,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +dependencies = [ + "winapi", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" diff --git a/repak_cli/Cargo.toml b/repak_cli/Cargo.toml index 18818bd..95caf5a 100644 --- a/repak_cli/Cargo.toml +++ b/repak_cli/Cargo.toml @@ -37,3 +37,6 @@ itertools = "0.12.0" [dev-dependencies] assert_cmd = "2.0.12" +dir-diff = "0.3.3" +indoc = "2.0.5" +tempfile = "3.10.1" diff --git a/repak_cli/tests/cli.rs b/repak_cli/tests/cli.rs new file mode 100644 index 0000000..e46dcd8 --- /dev/null +++ b/repak_cli/tests/cli.rs @@ -0,0 +1,165 @@ +use assert_cmd::prelude::*; +use indoc::{formatdoc, indoc}; +use std::process::Command; + +const PAK: &str = "../repak/tests/packs/pack_v11.pak"; + +#[test] +fn test_cli_info() { + let assert = Command::cargo_bin("repak") + .unwrap() + .arg("info") + .arg(PAK) + .assert(); + assert.success().stdout(indoc! {" + mount point: ../mount/point/root/ + version: V11 + version major: Fnv64BugFix + encrypted index: false + encrytion guid: Some(00000000000000000000000000000000) + 4 file entries + "}); +} + +#[test] +fn test_cli_list() { + let assert = Command::cargo_bin("repak") + .unwrap() + .arg("list") + .arg("-s") + .arg("") + .arg(PAK) + .assert(); + assert.success().stdout(indoc! {r#" + ../mount/point/root/directory/nested.txt + ../mount/point/root/test.png + ../mount/point/root/test.txt + ../mount/point/root/zeros.bin + "#}); + + let assert = Command::cargo_bin("repak") + .unwrap() + .arg("list") + .arg("-s") + .arg("../mount") + .arg(PAK) + .assert(); + assert.success().stdout(indoc! {r#" + point/root/directory/nested.txt + point/root/test.png + point/root/test.txt + point/root/zeros.bin + "#}); + + let assert = Command::cargo_bin("repak") + .unwrap() + .arg("list") + .arg("-s") + .arg("../mount/root/asdf") + .arg(PAK) + .assert(); + assert.failure().stderr(indoc! {r#" + Error: Prefix "../mount/root/asdf" does not match path "../mount/point/root/directory/nested.txt" + "#}); +} + +#[test] +fn test_cli_get() { + let assert = Command::cargo_bin("repak") + .unwrap() + .arg("get") + .arg("-s") + .arg("../mount/point") + .arg(PAK) + .arg("root/test.txt") + .assert(); + assert.success().stdout(indoc! {r#" + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. + "#}); + + let assert = Command::cargo_bin("repak") + .unwrap() + .arg("get") + .arg("-s") + .arg("../mount/point") + .arg(PAK) + .arg("root/doesnotexist.txt") + .assert(); + assert.failure().stderr(indoc! {r#" + Error: No entry found at doesnotexist.txt + "#}); +} + +#[test] +fn test_cli_pack() { + let dir = tempfile::tempdir().unwrap(); + + let out_pak = dir.path().join("output.pak"); + let out_dir = dir.path().join("output"); + + let assert = Command::cargo_bin("repak") + .unwrap() + .arg("pack") + .arg("../repak/tests/pack/") + .arg("-m") + .arg("../mount/point/root") + .arg("--version") + .arg("V11") + .arg(&out_pak) + .assert(); + assert.success().stdout(formatdoc! {r#" + Packed 4 files to {} + "#, out_pak.to_string_lossy()}); + + // TODO test packing to non-empty file + + let assert = Command::cargo_bin("repak") + .unwrap() + .arg("unpack") + .arg(&out_pak) + .arg("-s") + .arg("../mount/point/root") + .assert(); + assert.success().stdout(formatdoc! {r#" + Unpacked 4 files to {} from {} + "#, out_dir.to_string_lossy(), out_pak.to_string_lossy()}); + assert!(!dir_diff::is_different("../repak/tests/pack/", out_dir).unwrap()); +} + +#[test] +fn test_cli_unpack() { + let dir = tempfile::tempdir().unwrap(); + + let assert = Command::cargo_bin("repak") + .unwrap() + .arg("unpack") + .arg(PAK) + .arg("-s") + .arg("../mount") + .arg("-o") + .arg(dir.path()) + .assert(); + assert.success().stdout(formatdoc! {r#" + Unpacked 4 files to {} from ../repak/tests/packs/pack_v11.pak + "#, &dir.path().to_string_lossy()}); + assert!(!dir_diff::is_different("../repak/tests/pack/", dir.path().join("point")).unwrap()); + + // TODO test unpacking to non-empty directory +} + +#[test] +fn test_cli_hashlist() { + let assert = Command::cargo_bin("repak") + .unwrap() + .arg("hash-list") + .arg(PAK) + .arg("-s") + .arg("../mount") + .assert(); + assert.success().stdout(formatdoc! {r#" + 246c88de650fb20d63abaeb7c1bd8556d0ea260bf4579beafe0b2597e00270a5 point/root/directory/nested.txt + d7d3e1c21a5b98621add61a4244a413abf5ad6413b0d25ba09bfd5536c75e3b1 point/root/test.png + 56293a80e0394d252e995f2debccea8223e4b5b2b150bee212729b3b39ac4d46 point/root/test.txt + e5a00aa9991ac8a5ee3109844d84a55583bd20572ad3ffcd42792f3c36b183ad point/root/zeros.bin + "#}); +}