From d491963be0e2a3ef137c6d1861d856424768a863 Mon Sep 17 00:00:00 2001 From: Lars Eggert Date: Thu, 6 Nov 2025 16:03:13 -0500 Subject: [PATCH] Remove `uuid` dependency `uuid` pulls in a bunch of WASM dependencies, even when Codspeed is pulled in with `default-features = false`. For some projects, that means vetting a lot of extra code. This PR replaces the `uuid` dependency and uses `getrandom` to generate an UUIDv4-style string. (I'm not sure if anything depends on things being named with UUIDs; if not, this PR would be even simpler.) --- Cargo.lock | 12 +----------- crates/cargo-codspeed/Cargo.toml | 1 - crates/cargo-codspeed/tests/helpers.rs | 4 ++-- crates/codspeed/Cargo.toml | 2 +- crates/codspeed/src/utils.rs | 23 +++++++++++++++++++++++ crates/codspeed/src/walltime_results.rs | 4 +++- 6 files changed, 30 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3000e12d..c0ae0fcb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -460,7 +460,6 @@ dependencies = [ "serde_json", "termcolor", "toml", - "uuid", ] [[package]] @@ -589,6 +588,7 @@ dependencies = [ "anyhow", "cc", "colored", + "getrandom", "glob", "libc", "nix", @@ -596,7 +596,6 @@ dependencies = [ "serde_json", "statrs", "tempfile", - "uuid", ] [[package]] @@ -1914,15 +1913,6 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" -[[package]] -name = "uuid" -version = "1.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3758f5e68192bb96cc8f9b7e2c2cfdabb435499a28499a42f8f984092adad4b" -dependencies = [ - "getrandom", -] - [[package]] name = "value-bag" version = "1.9.0" diff --git a/crates/cargo-codspeed/Cargo.toml b/crates/cargo-codspeed/Cargo.toml index 6e0ad634..cc082174 100644 --- a/crates/cargo-codspeed/Cargo.toml +++ b/crates/cargo-codspeed/Cargo.toml @@ -34,7 +34,6 @@ codspeed = { path = "../codspeed", version = "=4.0.5" } assert_cmd = "2.0.15" fs_extra = "1.3.0" predicates = "3.1.2" -uuid = { version = "1.10.0", features = ["v4"] } [features] vendored-openssl = [] diff --git a/crates/cargo-codspeed/tests/helpers.rs b/crates/cargo-codspeed/tests/helpers.rs index 1bc93c47..74e85cae 100644 --- a/crates/cargo-codspeed/tests/helpers.rs +++ b/crates/cargo-codspeed/tests/helpers.rs @@ -7,7 +7,6 @@ use assert_cmd::Command; use fs_extra::dir::copy; use fs_extra::dir::create; use fs_extra::dir::remove; -use uuid::Uuid; fn replace_in_file(path: &str, from: &str, to: &str) { let mut contents = std::fs::read_to_string(path).unwrap(); @@ -27,7 +26,8 @@ pub enum Project { pub fn setup(dir: &str, project: Project) -> String { //Create a new unique named temp directory - let tmp_dir = temp_dir().join(format!("cargo-codspeed-test-{}", Uuid::new_v4())); + let unique_id = codspeed::utils::generate_unique_id(); + let tmp_dir = temp_dir().join(format!("cargo-codspeed-test-{unique_id}")); create(&tmp_dir, false).unwrap(); let mut copy_opts = fs_extra::dir::CopyOptions::new(); copy_opts.content_only = true; diff --git a/crates/codspeed/Cargo.toml b/crates/codspeed/Cargo.toml index dd3eeda8..67644c1a 100644 --- a/crates/codspeed/Cargo.toml +++ b/crates/codspeed/Cargo.toml @@ -23,10 +23,10 @@ colored = "2.0.0" glob = "0.3.2" libc = "^0.2" nix = { version = "0.30.1", features = ["time"] } +getrandom = "0.2" serde = { workspace = true } serde_json = { workspace = true } statrs = { version = "0.18.0", default-features = false } -uuid = { version = "1.12.1", features = ["v4"] } [[bench]] name = "native" diff --git a/crates/codspeed/src/utils.rs b/crates/codspeed/src/utils.rs index ffbfb6d3..472c1f84 100644 --- a/crates/codspeed/src/utils.rs +++ b/crates/codspeed/src/utils.rs @@ -46,6 +46,29 @@ pub fn is_perf_enabled() -> bool { std::env::var("CODSPEED_PERF_ENABLED").is_ok() } +/// Generate a statistically unique ID in a format resembling UUID v4. +pub fn generate_unique_id() -> String { + // Generate random bytes for UUID v4 + let mut bytes = [0u8; 16]; + getrandom::getrandom(&mut bytes).expect("Failed to generate random bytes"); + + // Extract values from bytes + let r1 = u32::from_be_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]); + let r2 = u16::from_be_bytes([bytes[4], bytes[5]]); + let r3 = u16::from_be_bytes([bytes[6], bytes[7]]); + let r4 = u16::from_be_bytes([bytes[8], bytes[9]]); + let r5 = u32::from_be_bytes([bytes[10], bytes[11], bytes[12], bytes[13]]); + let r6 = u16::from_be_bytes([bytes[14], bytes[15]]); + + // Set version (4) and variant bits according to UUID v4 spec + let r3_v4 = (r3 & 0x0fff) | 0x4000; // Version 4 + let r4_variant = (r4 & 0x3fff) | 0x8000; // Variant 10 + + // Format as standard UUID: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx + // where y is one of 8, 9, A, or B + format!("{r1:08x}-{r2:04x}-{r3_v4:04x}-{r4_variant:04x}-{r5:08x}{r6:04x}") +} + #[cfg(test)] mod tests { use super::*; diff --git a/crates/codspeed/src/walltime_results.rs b/crates/codspeed/src/walltime_results.rs index b7f0c491..dc67de84 100644 --- a/crates/codspeed/src/walltime_results.rs +++ b/crates/codspeed/src/walltime_results.rs @@ -7,6 +7,8 @@ use std::{ use serde::{Deserialize, Serialize}; use statrs::statistics::{Data, Distribution, Max, Min, OrderStatistics}; +use crate::utils::generate_unique_id; + const IQR_OUTLIER_FACTOR: f64 = 1.5; const STDEV_OUTLIER_FACTOR: f64 = 3.0; @@ -191,7 +193,7 @@ impl WalltimeBenchmark { fn dump_to_results(&self, workspace_root: &Path, scope: &str) { let output_dir = result_dir_from_workspace_root(workspace_root).join(scope); std::fs::create_dir_all(&output_dir).unwrap(); - let bench_id = uuid::Uuid::new_v4().to_string(); + let bench_id = generate_unique_id(); let output_path = output_dir.join(format!("{bench_id}.json")); let mut writer = std::fs::File::create(&output_path).expect("Failed to create the file"); serde_json::to_writer_pretty(&mut writer, self).expect("Failed to write the data");