diff options
author | Trevor Gross <tmgross@umich.edu> | 2024-02-11 15:56:04 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-11 20:56:04 +0000 |
commit | dc952f9c43c431eb32ce3796d47eb0d3258a2fc5 (patch) | |
tree | 16a46445b22991fd9aafbc4ee89f6c0c89668023 | |
parent | a2ff42e6c37ba5c429d444f3a18d3633e59f9a34 (diff) |
Add `blake3` and `blake3_file` functions (#1860)
-rw-r--r-- | Cargo.lock | 97 | ||||
-rw-r--r-- | Cargo.toml | 1 | ||||
-rw-r--r-- | README.md | 10 | ||||
-rw-r--r-- | src/function.rs | 23 | ||||
-rw-r--r-- | tests/functions.rs | 24 |
5 files changed, 148 insertions, 7 deletions
@@ -69,6 +69,18 @@ dependencies = [ ] [[package]] +name = "arrayref" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] name = "atty" version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -92,6 +104,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" [[package]] +name = "blake3" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0231f06152bf547e9c2b5194f247cd97aacf6dcd8b15d8e5ec0663f64580da87" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", + "memmap2", + "rayon", +] + +[[package]] name = "block-buffer" version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -118,6 +145,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" [[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] + +[[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -146,6 +182,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] +name = "constant_time_eq" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" + +[[package]] name = "cpufeatures" version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -164,6 +206,31 @@ dependencies = [ ] [[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" + +[[package]] name = "crypto-common" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -389,6 +456,7 @@ version = "1.24.0" dependencies = [ "ansi_term", "atty", + "blake3", "camino", "clap", "cradle", @@ -477,6 +545,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" [[package]] +name = "memmap2" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f49388d20533534cd19360ad3d6a7dadc885944aa802ba3995040c5ec11288c6" +dependencies = [ + "libc", +] + +[[package]] name = "nix" version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -583,6 +660,26 @@ dependencies = [ ] [[package]] +name = "rayon" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7237101a77a10773db45d62004a272517633fbcc3df19d96455ede1122e051" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] name = "redox_syscall" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -20,6 +20,7 @@ members = [".", "bin/ref-type", "bin/generate-book", "bin/update-contributors"] [dependencies] ansi_term = "0.12.0" atty = "0.2.0" +blake3 = { version = "1.5.0", features = ["rayon", "mmap"] } camino = "1.0.4" clap = { version = "2.33.0", features = ["wrap_help"] } ctrlc = { version = "3.1.1", features = ["termination"] } @@ -1456,12 +1456,16 @@ which will halt execution. #### UUID and Hash Generation -- `sha256(string)` - Return the SHA-256 hash of `string` as a hexadecimal +- `blake3(string)`<sup>master</sup> - Return [BLAKE3] hash of `string` as hexadecimal string. +- `blake3_file(path)`<sup>master</sup> - Return [BLAKE3] hash of file at `path` as hexadecimal + string. +- `sha256(string)` - Return the SHA-256 hash of `string` as hexadecimal string. +- `sha256_file(path)` - Return SHA-256 hash of file at `path` as hexadecimal string. -- `sha256_file(path)` - Return the SHA-256 hash of the file at `path` as a - hexadecimal string. - `uuid()` - Generate a random version 4 UUID. +[BLAKE3]: https://github.com/BLAKE3-team/BLAKE3/ + #### Semantic Versions - `semver_matches(version, requirement)`<sup>1.16.0</sup> - Check whether a diff --git a/src/function.rs b/src/function.rs index 1262076b..fee4bfc5 100644 --- a/src/function.rs +++ b/src/function.rs @@ -21,6 +21,8 @@ pub(crate) fn get(name: &str) -> Option<Function> { let function = match name { "absolute_path" => Unary(absolute_path), "arch" => Nullary(arch), + "blake3" => Unary(blake3), + "blake3_file" => Unary(blake3_file), "canonicalize" => Unary(canonicalize), "cache_directory" => Nullary(|_| dir("cache", dirs::cache_dir)), "capitalize" => Unary(capitalize), @@ -107,6 +109,19 @@ fn arch(_context: &FunctionContext) -> Result<String, String> { Ok(target::arch().to_owned()) } +fn blake3(_context: &FunctionContext, s: &str) -> Result<String, String> { + Ok(blake3::hash(s.as_bytes()).to_string()) +} + +fn blake3_file(context: &FunctionContext, path: &str) -> Result<String, String> { + let path = context.search.working_directory.join(path); + let mut hasher = blake3::Hasher::new(); + hasher + .update_mmap_rayon(&path) + .map_err(|err| format!("Failed to hash `{}`: {err}", path.display()))?; + Ok(hasher.finalize().to_string()) +} + fn canonicalize(_context: &FunctionContext, path: &str) -> Result<String, String> { let canonical = std::fs::canonicalize(path).map_err(|err| format!("I/O error canonicalizing path: {err}"))?; @@ -377,12 +392,12 @@ fn sha256(_context: &FunctionContext, s: &str) -> Result<String, String> { fn sha256_file(context: &FunctionContext, path: &str) -> Result<String, String> { use sha2::{Digest, Sha256}; - let justpath = context.search.working_directory.join(path); + let path = context.search.working_directory.join(path); let mut hasher = Sha256::new(); - let mut file = fs::File::open(&justpath) - .map_err(|err| format!("Failed to open file at `{:?}`: {err}", justpath.to_str()))?; + let mut file = + fs::File::open(&path).map_err(|err| format!("Failed to open `{}`: {err}", path.display()))?; std::io::copy(&mut file, &mut hasher) - .map_err(|err| format!("Failed to read file at `{:?}`: {err}", justpath.to_str()))?; + .map_err(|err| format!("Failed to read `{}`: {err}", path.display()))?; let hash = hasher.finalize(); Ok(format!("{hash:x}")) } diff --git a/tests/functions.rs b/tests/functions.rs index c3565242..2c0e8143 100644 --- a/tests/functions.rs +++ b/tests/functions.rs @@ -663,6 +663,30 @@ fn just_pid() { assert_eq!(stdout.parse::<u32>().unwrap(), pid); } +#[test] +fn blake3() { + Test::new() + .justfile("x := blake3('5943ee37-0000-1000-8000-010203040506')") + .args(["--evaluate", "x"]) + .stdout("026c9f740a793ff536ddf05f8915ea4179421f47f0fa9545476076e9ba8f3f2b") + .run(); +} + +#[test] +fn blake3_file() { + Test::new() + .justfile("x := blake3_file('sub/blakefile')") + .tree(tree! { + sub: { + blakefile: "just is great\n", + } + }) + .current_dir("sub") + .args(["--evaluate", "x"]) + .stdout("8379241877190ca4b94076a8c8f89fe5747f95c62f3e4bf41f7408a0088ae16d") + .run(); +} + #[cfg(unix)] #[test] fn canonicalize() { |