From f688ff1351263646eebb22af73c7e498f612b644 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 14 Feb 2026 22:11:46 -0500 Subject: [PATCH] Use shared repo directories to avoid duplicate checkouts. --- Cargo.lock | 72 ++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/config/root.rs | 1 + src/config/target.rs | 39 +++++++++++++++++++++--- 4 files changed, 109 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0ea7ce1..b6639b5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -141,6 +141,15 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + [[package]] name = "bumpalo" version = "3.19.1" @@ -204,6 +213,15 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + [[package]] name = "crossbeam-channel" version = "0.5.15" @@ -219,6 +237,26 @@ version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +[[package]] +name = "crypto-common" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + [[package]] name = "displaydoc" version = "0.2.5" @@ -321,6 +359,16 @@ dependencies = [ "slab", ] +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + [[package]] name = "getrandom" version = "0.2.17" @@ -664,6 +712,7 @@ dependencies = [ "opentelemetry-semantic-conventions", "serde", "serde_json", + "sha2", "tokio", "toml", "tracing", @@ -1014,6 +1063,17 @@ dependencies = [ "serde_core", ] +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "sharded-slab" version = "0.1.7" @@ -1400,6 +1460,12 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" +[[package]] +name = "typenum" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" + [[package]] name = "unicode-ident" version = "1.0.22" @@ -1442,6 +1508,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + [[package]] name = "want" version = "0.3.1" diff --git a/Cargo.toml b/Cargo.toml index b3ff8a3..3b3b156 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,7 @@ opentelemetry-otlp = { version = "0.13.0", optional = true } opentelemetry-semantic-conventions = { version = "0.12.0", optional = true } serde = { version = "1.0.228", default-features = false, features = ["std", "derive"] } serde_json = { version = "1.0.149", default-features = false, features = ["std"] } +sha2 = { version = "0.10.9", default-features = false, features = ["std"] } tokio = { version = "1.49.0", default-features = false, features = ["rt", "rt-multi-thread", "fs", "io-util", "process"] } toml = { version = "0.9.11", default-features = false, features = ["display", "parse", "serde", "std"] } tracing = { version = "0.1.37", optional = true } diff --git a/src/config/root.rs b/src/config/root.rs index 0b19f29..1879307 100644 --- a/src/config/root.rs +++ b/src/config/root.rs @@ -63,6 +63,7 @@ impl Config { Ok(target_config) } + /// The root directory where all the output is stored. pub(crate) fn get_output_directory(&self) -> Result, CustomError> { let maybe_repo_directory = self.output_directory.as_deref().map(Cow::Borrowed); if let Some(work_dir) = maybe_repo_directory { diff --git a/src/config/target.rs b/src/config/target.rs index 44cd348..d737f35 100644 --- a/src/config/target.rs +++ b/src/config/target.rs @@ -3,6 +3,8 @@ use std::path::Path; use serde::Deserialize; use serde::Serialize; +use sha2::Digest; +use sha2::Sha256; use crate::error::CustomError; @@ -34,13 +36,31 @@ pub(crate) struct TargetConfig { } impl TargetConfig { + /// The folder that contains the folders for the build targets. + pub(crate) fn get_target_root_directory<'target, 'root>( + &'target self, + config_root: &'root Config, + ) -> Result, CustomError> { + let output_directory = config_root.get_output_directory()?; + Ok(Cow::Owned(output_directory.join("target"))) + } + /// The root directory for this specific build target. pub(crate) fn get_target_directory<'target, 'root>( &'target self, config_root: &'root Config, ) -> Result, CustomError> { - let repo_directory = config_root.get_output_directory()?; - Ok(Cow::Owned(repo_directory.join(&self.name))) + let target_root = self.get_target_root_directory(config_root)?; + Ok(Cow::Owned(target_root.join(&self.name))) + } + + /// The folder that contains the folders containing the checkouts of the git repositories. + pub(crate) fn get_repo_root_directory<'target, 'root>( + &'target self, + config_root: &'root Config, + ) -> Result, CustomError> { + let output_directory = config_root.get_output_directory()?; + Ok(Cow::Owned(output_directory.join("repo"))) } /// The root of the checkout of the git repository. @@ -48,8 +68,11 @@ impl TargetConfig { &'target self, config_root: &'root Config, ) -> Result, CustomError> { - let target_directory = self.get_target_directory(config_root)?; - Ok(Cow::Owned(target_directory.join("repo"))) + let hashed_repo = Sha256::digest(&self.repo); + let hashed_repo = hex_string(&hashed_repo); + + let repo_root = self.get_repo_root_directory(config_root)?; + Ok(Cow::Owned(repo_root.join(hashed_repo))) } /// The directory that contains flake.nix. @@ -99,3 +122,11 @@ impl TargetConfig { Ok(&self.attr) } } + +fn hex_string(data: &[u8]) -> String { + let mut out = String::with_capacity(data.len() * 2); + for byte in data { + out.push_str(format!("{:02x}", byte).as_str()); + } + out +}