diff --git a/Cargo.lock b/Cargo.lock index 6a2d3a4b18..d43082bbc0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2825,15 +2825,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "keccak" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" -dependencies = [ - "cpufeatures", -] - [[package]] name = "kstring" version = "2.0.2" @@ -3310,7 +3301,6 @@ dependencies = [ "serde_yaml", "sha-1", "sha2", - "sha3", "similar", "simple-counter", "smallvec", @@ -4465,16 +4455,6 @@ dependencies = [ "digest", ] -[[package]] -name = "sha3" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" -dependencies = [ - "digest", - "keccak", -] - [[package]] name = "shell-words" version = "1.1.0" diff --git a/Cargo.toml b/Cargo.toml index e10aef0a8d..1de70035e5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -91,7 +91,6 @@ serde_with = "3.11.0" serde_yaml = "0.9.19" sha-1 = "0.10.0" sha2 = "0.10.6" -sha3 = "0.10.8" similar = "2.2.1" simple-counter = "0.1.0" smallvec = "1.13.2" diff --git a/core/Cargo.toml b/core/Cargo.toml index 7f8c38eca3..335fc073b8 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -32,8 +32,6 @@ benchmark-ci = [] [build-dependencies] lalrpop.workspace = true -regex.workspace = true -sha3.workspace = true cxx-build = { workspace = true, optional = true } pkg-config = { workspace = true, optional = true } diff --git a/core/build.rs b/core/build.rs index 4e34930451..9978819ae7 100644 --- a/core/build.rs +++ b/core/build.rs @@ -1,55 +1,4 @@ -use std::{ - fs::File, - io::{BufRead as _, BufReader}, - path::{Path, PathBuf}, -}; - -use regex::Regex; -use sha3::{Digest, Sha3_256}; - -// Turn a hex-encoded string into a byte array, panicking if it isn't properly -// hex-encoded. -fn decode_hex(s: &str) -> Vec { - let decode_byte = |b: u8| char::from(b).to_digit(16).unwrap() as u8; - s.as_bytes() - .chunks(2) - .map(|hex| decode_byte(hex[0]) * 16 + decode_byte(hex[1])) - .collect() -} - -// Checks if the grammar in the source tree is up-to-date, by comparing -// the hash of the lalrpop source to the hash that lalrpop recorded in -// the generated file. Lalrpop writes a line like "// sha3: adf234..1234" -// into its generated file, where the hash is the SHA3-256 hash of the -// source file it read. -fn grammar_is_up_to_date(path: &Path) -> bool { - let Ok(generated_file) = File::open(path) else { - return false; - }; - - let reader = BufReader::new(generated_file); - let grammar_src_path = Path::new(&concat!( - env!("CARGO_MANIFEST_DIR"), - "/src/parser/grammar.lalrpop" - )); - let sha_regex = Regex::new("sha3: ([a-z0-9]+)").unwrap(); - let mut src_hasher = Sha3_256::new(); - src_hasher.update(std::fs::read_to_string(grammar_src_path).unwrap()); - let src_hash = src_hasher.finalize(); - - // The generated file is really big and we don't want to read the whole thing. - // As of writing this, the "sha3:" line is always the second one. We'll be a - // little bit robust to changes by looking at the first five lines. - for line in reader.lines().take(5) { - if let Some(captures) = sha_regex.captures(&line.unwrap()) { - let hash = captures.get(1).unwrap(); - let hash = decode_hex(hash.as_str()); - eprintln!("src hash {src_hash:?}, saved hash {hash:?}"); - return hash == src_hash[..]; - } - } - false -} +use std::path::{Path, PathBuf}; fn main() { let checked_in_grammar_path = Path::new(&concat!( @@ -57,19 +6,26 @@ fn main() { "/src/parser/grammar.rs" )); - // Running lalrpop can be expensive, so we check in a generated grammar file. - // If that file is up to date, copy it into the output directory instead of - // running lalrpop. - if grammar_is_up_to_date(checked_in_grammar_path) { - let out_dir = PathBuf::from(std::env::var_os("OUT_DIR").expect("missing OUT_DIR variable")); - let out_parser_dir = out_dir.join("parser"); - std::fs::create_dir_all(&out_parser_dir).expect("failed to create $OUT_DIR/parser"); - std::fs::copy(checked_in_grammar_path, out_parser_dir.join("grammar.rs")).unwrap(); - } else { - lalrpop::Configuration::new() - .use_cargo_dir_conventions() - .process_file("src/parser/grammar.lalrpop") - .unwrap(); + let out_dir = PathBuf::from(std::env::var_os("OUT_DIR").expect("missing OUT_DIR variable")); + let out_parser_dir = out_dir.join("parser"); + std::fs::create_dir_all(&out_parser_dir).expect("failed to create $OUT_DIR/parser"); + // Running lalrpop can be expensive. When building from git, we generate the parser + // in this build script, but when publishing the crate we add the generated + // parser to the published crate at `src/parser/grammar.rs`. + // + // In order to have this build script work for both the published crate and the git + // version, we try to copy `src/parser/grammar.rs` into the same location in $OUT_DIR + // that lalrpop would generate the grammar. If that copy fails because `src/parser/grammar.rs` + // doesn't exist, we're probably building from git and so we generate the grammar. + match std::fs::copy(checked_in_grammar_path, out_parser_dir.join("grammar.rs")) { + Ok(_) => {} + Err(e) if e.kind() == std::io::ErrorKind::NotFound => { + lalrpop::Configuration::new() + .use_cargo_dir_conventions() + .process_file("src/parser/grammar.lalrpop") + .unwrap(); + } + Err(e) => panic!("{e}"), } println!("cargo:rerun-if-changed=src/parser/grammar.lalrpop");