diff options
author | Florian Klink <flokli@flokli.de> | 2023-01-04T20·59+0100 |
---|---|---|
committer | flokli <flokli@flokli.de> | 2023-01-06T12·25+0000 |
commit | d4603fc0af5f2be27716d4d3c3fc6c514c8ffbe9 (patch) | |
tree | cf213db418f8abb6b3f22c7f185e0cfb44ec5e41 | |
parent | 87c80895cd7eb9fa7c09a343352f16b471f57fce (diff) |
refactor(derivation): return NixPath in calculate_derivation_path r/5608
This moves all the hash compression logic into a common helper function. Also update the docstring, which said "path" here, which could have been confused with output paths. Change-Id: Iedfb59aeb24f7638afac669dcd18d57b6cfaece2 Reviewed-on: https://cl.tvl.fyi/c/depot/+/7759 Reviewed-by: tazjin <tazjin@tvl.su> Tested-by: BuildkiteCI
-rw-r--r-- | tvix/derivation/src/derivation.rs | 45 | ||||
-rw-r--r-- | tvix/derivation/src/tests/mod.rs | 6 |
2 files changed, 34 insertions, 17 deletions
diff --git a/tvix/derivation/src/derivation.rs b/tvix/derivation/src/derivation.rs index a9ae4191b2de..a5ea56fbbf89 100644 --- a/tvix/derivation/src/derivation.rs +++ b/tvix/derivation/src/derivation.rs @@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize}; use sha2::{Digest, Sha256}; use std::{collections::BTreeMap, fmt, fmt::Write, iter::FromIterator}; use tvix_store::nixbase32::NIXBASE32; -use tvix_store::nixpath::STORE_DIR; +use tvix_store::nixpath::{NixPath, ParseNixPathError, STORE_DIR}; #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] pub struct Derivation { @@ -28,6 +28,29 @@ pub struct Derivation { pub system: String, } +/// This returns a store path, either of a derivation or a regular output. +/// The path_hash is compressed to 20 bytes, and nixbase32-encoded (32 characters) +fn build_store_path( + is_derivation: bool, + path_hash: &[u8], + name: &str, +) -> Result<NixPath, ParseNixPathError> { + let compressed = nix_hash::compress_hash(path_hash, 20); + if is_derivation { + NixPath::from_string( + format!( + "{}-{}{}", + NIXBASE32.encode(&compressed), + name, + write::DOT_FILE_EXT, + ) + .as_str(), + ) + } else { + NixPath::from_string(format!("{}-{}", NIXBASE32.encode(&compressed), name,).as_str()) + } +} + impl Derivation { pub fn serialize(&self, writer: &mut impl Write) -> Result<(), fmt::Error> { writer.write_str(write::DERIVATION_PREFIX)?; @@ -46,9 +69,9 @@ impl Derivation { Ok(()) } - /// Returns the path of a Derivation struct. + /// Returns the drv path of a Derivation struct. /// - /// The path is calculated like this: + /// The drv path is calculated like this: /// - Write the fingerprint of the Derivation to the sha256 hash function. /// This is: `text:`, /// all d.InputDerivations and d.InputSources (sorted, separated by a `:`), @@ -61,8 +84,8 @@ impl Derivation { /// - Write the .drv A-Term contents to a hash function /// - Take the digest, run hash.CompressHash(digest, 20) on it. /// - Encode it with nixbase32 - /// - Construct the full path $storeDir/$nixbase32EncodedCompressedHash-$name.drv - pub fn calculate_derivation_path(&self, name: &str) -> String { + /// - Use it (and the name) to construct a NixPath. + pub fn calculate_derivation_path(&self, name: &str) -> Result<NixPath, ParseNixPathError> { let mut hasher = Sha256::new(); // collect the list of paths from input_sources and input_derivations @@ -101,17 +124,7 @@ impl Derivation { hasher.update(name); hasher.update(write::DOT_FILE_EXT); - let compressed = { - let aterm_digest = Vec::from_iter(hasher.finalize()); - nix_hash::compress_hash(&aterm_digest, 20) - }; - - format!( - "{}-{}{}", - NIXBASE32.encode(&compressed), - name, - write::DOT_FILE_EXT - ) + build_store_path(true, &hasher.finalize(), name) } } diff --git a/tvix/derivation/src/tests/mod.rs b/tvix/derivation/src/tests/mod.rs index 1b55c6e3e751..623cc4e5b13a 100644 --- a/tvix/derivation/src/tests/mod.rs +++ b/tvix/derivation/src/tests/mod.rs @@ -4,6 +4,7 @@ use std::io::Read; use std::path::Path; use test_case::test_case; use test_generator::test_resources; +use tvix_store::nixpath::NixPath; const RESOURCES_PATHS: &str = "src/tests/derivation_tests"; @@ -61,5 +62,8 @@ fn derivation_path(name: &str, expected_path: &str) { let data = read_file(&format!("{}/{}.json", RESOURCES_PATHS, expected_path)); let derivation: Derivation = serde_json::from_str(&data).expect("JSON was not well-formatted"); - assert_eq!(derivation.calculate_derivation_path(name), expected_path); + assert_eq!( + derivation.calculate_derivation_path(name).unwrap(), + NixPath::from_string(expected_path).unwrap() + ); } |