about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFlorian Klink <flokli@flokli.de>2023-01-04T20·59+0100
committerflokli <flokli@flokli.de>2023-01-06T12·25+0000
commitd4603fc0af5f2be27716d4d3c3fc6c514c8ffbe9 (patch)
treecf213db418f8abb6b3f22c7f185e0cfb44ec5e41
parent87c80895cd7eb9fa7c09a343352f16b471f57fce (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.rs45
-rw-r--r--tvix/derivation/src/tests/mod.rs6
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()
+    );
 }