refactor(tvix/nix-compat): -derivation::Hash, +NixHash
This stops using our own custom Hash structure, which was mostly only used because we had to parse the JSON representation somehow. Since cl/8217, there's a `NixHash` struct, which is better suited to hold this data. Converting the format requires a bit of serde labor though, but that only really matters when interacting with JSON representations (which we mostly don't). Change-Id: Idc5ee511e36e6726c71f66face8300a441b0bf4c Reviewed-on: https://cl.tvl.fyi/c/depot/+/8304 Autosubmit: flokli <flokli@flokli.de> Tested-by: BuildkiteCI Reviewed-by: tazjin <tazjin@tvl.su>
This commit is contained in:
		
							parent
							
								
									e82385dbe5
								
							
						
					
					
						commit
						b55d1f97ce
					
				
					 8 changed files with 201 additions and 87 deletions
				
			
		| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
use crate::{
 | 
			
		||||
    nixhash::NixHash,
 | 
			
		||||
    nixhash::HashAlgo,
 | 
			
		||||
    store_path::{self, StorePath},
 | 
			
		||||
};
 | 
			
		||||
use serde::{Deserialize, Serialize};
 | 
			
		||||
| 
						 | 
				
			
			@ -17,8 +17,9 @@ mod write;
 | 
			
		|||
mod tests;
 | 
			
		||||
 | 
			
		||||
// Public API of the crate.
 | 
			
		||||
pub use crate::nixhash::{NixHash, NixHashWithMode};
 | 
			
		||||
pub use errors::{DerivationError, OutputError};
 | 
			
		||||
pub use output::{Hash, Output};
 | 
			
		||||
pub use output::Output;
 | 
			
		||||
pub use utils::path_with_references;
 | 
			
		||||
 | 
			
		||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
 | 
			
		||||
| 
						 | 
				
			
			@ -75,23 +76,22 @@ impl Derivation {
 | 
			
		|||
        buffer
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Returns the fixed output path and its hash
 | 
			
		||||
    // (if the Derivation is fixed output),
 | 
			
		||||
    /// or None if there is no fixed output.
 | 
			
		||||
    /// Returns the fixed output path and its [NixHashWithMode]
 | 
			
		||||
    /// (if the Derivation is fixed output), or None if there is no fixed output.
 | 
			
		||||
    /// This takes some shortcuts in case more than one output exists, as this
 | 
			
		||||
    /// can't be a valid fixed-output Derivation.
 | 
			
		||||
    pub fn get_fixed_output(&self) -> Option<(&String, &Hash)> {
 | 
			
		||||
    pub fn get_fixed_output(&self) -> Option<(&String, &NixHashWithMode)> {
 | 
			
		||||
        if self.outputs.len() != 1 {
 | 
			
		||||
            return None;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if let Some(out_output) = self.outputs.get("out") {
 | 
			
		||||
            if let Some(out_output_hash) = &out_output.hash {
 | 
			
		||||
            if let Some(out_output_hash) = &out_output.hash_with_mode {
 | 
			
		||||
                return Some((&out_output.path, out_output_hash));
 | 
			
		||||
            }
 | 
			
		||||
            // There has to be a hash, otherwise it would not be FOD
 | 
			
		||||
        }
 | 
			
		||||
        return None;
 | 
			
		||||
        None
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Returns the drv path of a Derivation struct.
 | 
			
		||||
| 
						 | 
				
			
			@ -160,8 +160,6 @@ impl Derivation {
 | 
			
		|||
    ///    `fixed:out:${algo}:${digest}:${fodPath}` string is hashed instead of
 | 
			
		||||
    ///    the A-Term.
 | 
			
		||||
    ///
 | 
			
		||||
    /// TODO: what's the representation of ${digest}?
 | 
			
		||||
    ///
 | 
			
		||||
    /// If the derivation is not a fixed derivation, it's up to the caller of
 | 
			
		||||
    /// this function to provide a lookup function to lookup these calculation
 | 
			
		||||
    /// results of parent derivations at `fn_get_hash_derivation_modulo` (by
 | 
			
		||||
| 
						 | 
				
			
			@ -175,8 +173,9 @@ impl Derivation {
 | 
			
		|||
            // Fixed-output derivations return a fixed hash
 | 
			
		||||
            Some((fixed_output_path, fixed_output_hash)) => {
 | 
			
		||||
                hasher.update(format!(
 | 
			
		||||
                    "fixed:out:{}:{}:{}",
 | 
			
		||||
                    &fixed_output_hash.algo, &fixed_output_hash.digest, fixed_output_path,
 | 
			
		||||
                    "fixed:out:{}:{}",
 | 
			
		||||
                    fixed_output_hash.to_nix_hash_string(),
 | 
			
		||||
                    fixed_output_path
 | 
			
		||||
                ));
 | 
			
		||||
                hasher.finalize()
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -196,7 +195,7 @@ impl Derivation {
 | 
			
		|||
                for (drv_path, output_names) in &self.input_derivations {
 | 
			
		||||
                    replaced_input_derivations.insert(
 | 
			
		||||
                        data_encoding::HEXLOWER
 | 
			
		||||
                            .encode(&fn_get_derivation_or_fod_hash(&drv_path).digest),
 | 
			
		||||
                            .encode(&fn_get_derivation_or_fod_hash(drv_path).digest),
 | 
			
		||||
                        output_names.clone(),
 | 
			
		||||
                    );
 | 
			
		||||
                }
 | 
			
		||||
| 
						 | 
				
			
			@ -255,7 +254,7 @@ impl Derivation {
 | 
			
		|||
                        output_path_name.push_str(output_name);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    let s = &format!(
 | 
			
		||||
                    let fp = &format!(
 | 
			
		||||
                        "output:{}:{}:{}:{}",
 | 
			
		||||
                        output_name,
 | 
			
		||||
                        derivation_or_fod_hash.to_nix_hash_string(),
 | 
			
		||||
| 
						 | 
				
			
			@ -264,7 +263,7 @@ impl Derivation {
 | 
			
		|||
                    );
 | 
			
		||||
 | 
			
		||||
                    let abs_store_path =
 | 
			
		||||
                        utils::build_store_path(false, s, &output_path_name)?.to_absolute_path();
 | 
			
		||||
                        utils::build_store_path(false, fp, &output_path_name)?.to_absolute_path();
 | 
			
		||||
 | 
			
		||||
                    output.path = abs_store_path.clone();
 | 
			
		||||
                    self.environment
 | 
			
		||||
| 
						 | 
				
			
			@ -277,33 +276,41 @@ impl Derivation {
 | 
			
		|||
                // footgun prevention mechanism.
 | 
			
		||||
                assert!(fixed_output_path.is_empty());
 | 
			
		||||
 | 
			
		||||
                let s = {
 | 
			
		||||
                    let mut s = String::new();
 | 
			
		||||
                let fp = {
 | 
			
		||||
                    let mut fp = String::new();
 | 
			
		||||
                    // Fixed-output derivation.
 | 
			
		||||
                    // There's two different hashing strategies in place, depending on the value of hash.algo.
 | 
			
		||||
                    // There's two different hashing strategies in place,
 | 
			
		||||
                    // depending on whether the hash is recursive AND sha256 or anything else.
 | 
			
		||||
                    // This code is _weird_ but it is what Nix is doing. See:
 | 
			
		||||
                    // https://github.com/NixOS/nix/blob/1385b2007804c8a0370f2a6555045a00e34b07c7/src/libstore/store-api.cc#L178-L196
 | 
			
		||||
                    if fixed_output_hash.algo == "r:sha256" {
 | 
			
		||||
                        s.push_str(&format!(
 | 
			
		||||
                            "source:sha256:{}",
 | 
			
		||||
                            fixed_output_hash.digest, // lowerhex
 | 
			
		||||
                        ));
 | 
			
		||||
                    if let NixHashWithMode::Recursive(recursive_hash) = fixed_output_hash {
 | 
			
		||||
                        if recursive_hash.algo == HashAlgo::Sha256 {
 | 
			
		||||
                            fp.push_str(&format!("source:{}", recursive_hash.to_nix_hash_string()));
 | 
			
		||||
                        } else {
 | 
			
		||||
                            // This is similar to the FOD case, with an empty fixed_output_path.
 | 
			
		||||
                            fp.push_str(&format!(
 | 
			
		||||
                                "output:out:{}",
 | 
			
		||||
                                derivation_or_fod_hash.to_nix_hash_string(),
 | 
			
		||||
                            ));
 | 
			
		||||
                        }
 | 
			
		||||
                    } else {
 | 
			
		||||
                        s.push_str("output:out:");
 | 
			
		||||
                        // This is drv_replacement for FOD, with an empty fixed_output_path.
 | 
			
		||||
                        s.push_str(&derivation_or_fod_hash.to_nix_hash_string());
 | 
			
		||||
                        // This is similar to the FOD case, with an empty fixed_output_path.
 | 
			
		||||
                        fp.push_str(&format!(
 | 
			
		||||
                            "output:out:{}",
 | 
			
		||||
                            derivation_or_fod_hash.to_nix_hash_string(),
 | 
			
		||||
                        ));
 | 
			
		||||
                    }
 | 
			
		||||
                    s.push_str(&format!(":{}:{}", store_path::STORE_DIR, name));
 | 
			
		||||
                    s
 | 
			
		||||
                    fp.push_str(&format!(":{}:{}", store_path::STORE_DIR, name));
 | 
			
		||||
                    fp
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                let abs_store_path = utils::build_store_path(false, &s, name)?.to_absolute_path();
 | 
			
		||||
                let abs_store_path = utils::build_store_path(false, &fp, name)?.to_absolute_path();
 | 
			
		||||
 | 
			
		||||
                self.outputs.insert(
 | 
			
		||||
                    "out".to_string(),
 | 
			
		||||
                    Output {
 | 
			
		||||
                        path: abs_store_path.clone(),
 | 
			
		||||
                        hash: Some(fixed_output_hash.clone()),
 | 
			
		||||
                        hash_with_mode: Some(fixed_output_hash.clone()),
 | 
			
		||||
                    },
 | 
			
		||||
                );
 | 
			
		||||
                self.environment.insert("out".to_string(), abs_store_path);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue