refactor(nix-compat): derivation_or_fod_hash -> hash_derivation_modulo
There's no need for us to come up with our own names for this. Also update the comments/docstrings a bit, and inline the intermediate hash_derivation_modulo calculation. Change-Id: I09dab8ffe1ebfb6601841e98119eee4ff25d8f39 Reviewed-on: https://cl.tvl.fyi/c/depot/+/11578 Reviewed-by: edef <edef@edef.eu> Autosubmit: flokli <flokli@flokli.de> Tested-by: BuildkiteCI
This commit is contained in:
parent
3a9432f4d8
commit
c0d5439362
4 changed files with 57 additions and 48 deletions
|
@ -457,18 +457,24 @@ pub(crate) mod derivation_builtins {
|
||||||
drv.validate(false)
|
drv.validate(false)
|
||||||
.map_err(DerivationError::InvalidDerivation)?;
|
.map_err(DerivationError::InvalidDerivation)?;
|
||||||
|
|
||||||
// Calculate the derivation_or_fod_hash for the current derivation.
|
// Calculate the hash_derivation_modulo for the current derivation..
|
||||||
// This one is still intermediate (so not added to known_paths)
|
debug_assert!(
|
||||||
let derivation_or_fod_hash_tmp = drv.derivation_or_fod_hash(|drv_path| {
|
drv.outputs.values().all(|output| { output.path.is_none() }),
|
||||||
known_paths
|
"outputs should still be unset"
|
||||||
.get_hash_derivation_modulo(&drv_path.to_owned())
|
);
|
||||||
.unwrap_or_else(|| panic!("{} not found", drv_path))
|
|
||||||
.to_owned()
|
|
||||||
});
|
|
||||||
|
|
||||||
// Mutate the Derivation struct and set output paths
|
// Mutate the Derivation struct and set output paths
|
||||||
drv.calculate_output_paths(name, &derivation_or_fod_hash_tmp)
|
drv.calculate_output_paths(
|
||||||
.map_err(DerivationError::InvalidDerivation)?;
|
name,
|
||||||
|
// This one is still intermediate (so not added to known_paths),
|
||||||
|
// as the outputs are still unset.
|
||||||
|
&drv.hash_derivation_modulo(|drv_path| {
|
||||||
|
*known_paths
|
||||||
|
.get_hash_derivation_modulo(&drv_path.to_owned())
|
||||||
|
.unwrap_or_else(|| panic!("{} not found", drv_path))
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.map_err(DerivationError::InvalidDerivation)?;
|
||||||
|
|
||||||
let drv_path = drv
|
let drv_path = drv
|
||||||
.calculate_derivation_path(name)
|
.calculate_derivation_path(name)
|
||||||
|
|
|
@ -73,7 +73,7 @@ impl KnownPaths {
|
||||||
}
|
}
|
||||||
|
|
||||||
// compute the hash derivation modulo
|
// compute the hash derivation modulo
|
||||||
let hash_derivation_modulo = drv.derivation_or_fod_hash(|drv_path| {
|
let hash_derivation_modulo = drv.hash_derivation_modulo(|drv_path| {
|
||||||
self.get_hash_derivation_modulo(&drv_path.to_owned())
|
self.get_hash_derivation_modulo(&drv_path.to_owned())
|
||||||
.unwrap_or_else(|| panic!("{} not found", drv_path))
|
.unwrap_or_else(|| panic!("{} not found", drv_path))
|
||||||
.to_owned()
|
.to_owned()
|
||||||
|
|
|
@ -188,11 +188,12 @@ impl Derivation {
|
||||||
/// `fixed:out:${algo}:${digest}:${fodPath}` string is hashed instead of
|
/// `fixed:out:${algo}:${digest}:${fodPath}` string is hashed instead of
|
||||||
/// the A-Term.
|
/// the A-Term.
|
||||||
///
|
///
|
||||||
/// If the derivation is not a fixed derivation, it's up to the caller of
|
/// It's up to the caller of this function to provide a (infallible) lookup
|
||||||
/// this function to provide a lookup function to lookup these calculation
|
/// function to query [hash_derivation_modulo] of direct input derivations,
|
||||||
/// results of parent derivations at `fn_get_derivation_or_fod_hash` (by
|
/// by their [StorePathRef].
|
||||||
/// drv path).
|
/// It will only be called in case the derivation is not a fixed-output
|
||||||
pub fn derivation_or_fod_hash<F>(&self, fn_get_derivation_or_fod_hash: F) -> [u8; 32]
|
/// derivation.
|
||||||
|
pub fn hash_derivation_modulo<F>(&self, fn_lookup_hash_derivation_modulo: F) -> [u8; 32]
|
||||||
where
|
where
|
||||||
F: Fn(&StorePathRef) -> [u8; 32],
|
F: Fn(&StorePathRef) -> [u8; 32],
|
||||||
{
|
{
|
||||||
|
@ -200,16 +201,16 @@ impl Derivation {
|
||||||
// Non-Fixed-output derivations return the sha256 digest of the ATerm
|
// Non-Fixed-output derivations return the sha256 digest of the ATerm
|
||||||
// notation, but with all input_derivation paths replaced by a recursive
|
// notation, but with all input_derivation paths replaced by a recursive
|
||||||
// call to this function.
|
// call to this function.
|
||||||
// We use fn_get_derivation_or_fod_hash here, so callers can precompute this.
|
// We call [fn_lookup_hash_derivation_modulo] rather than recursing
|
||||||
|
// ourselves, so callers can precompute this.
|
||||||
self.fod_digest().unwrap_or({
|
self.fod_digest().unwrap_or({
|
||||||
// For each input_derivation, look up the
|
// For each input_derivation, look up the hash derivation modulo,
|
||||||
// derivation_or_fod_hash, and replace the derivation path with
|
// and replace the derivation path in the aterm with it's HEXLOWER digest.
|
||||||
// it's HEXLOWER digest.
|
|
||||||
let aterm_bytes = self.to_aterm_bytes_with_replacements(&BTreeMap::from_iter(
|
let aterm_bytes = self.to_aterm_bytes_with_replacements(&BTreeMap::from_iter(
|
||||||
self.input_derivations
|
self.input_derivations
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(drv_path, output_names)| {
|
.map(|(drv_path, output_names)| {
|
||||||
let hash = fn_get_derivation_or_fod_hash(&drv_path.into());
|
let hash = fn_lookup_hash_derivation_modulo(&drv_path.into());
|
||||||
|
|
||||||
(hash, output_names.to_owned())
|
(hash, output_names.to_owned())
|
||||||
}),
|
}),
|
||||||
|
@ -226,20 +227,22 @@ impl Derivation {
|
||||||
/// and self.environment[$outputName] needs to be an empty string.
|
/// and self.environment[$outputName] needs to be an empty string.
|
||||||
///
|
///
|
||||||
/// Output path calculation requires knowledge of the
|
/// Output path calculation requires knowledge of the
|
||||||
/// derivation_or_fod_hash [NixHash], which (in case of non-fixed-output
|
/// [hash_derivation_modulo], which (in case of non-fixed-output
|
||||||
/// derivations) also requires knowledge of other hash_derivation_modulo
|
/// derivations) also requires knowledge of the [hash_derivation_modulo] of
|
||||||
/// [NixHash]es.
|
/// input derivations (recursively).
|
||||||
///
|
///
|
||||||
/// We solve this by asking the caller of this function to provide the
|
/// To avoid recursing and doing unnecessary calculation, we simply
|
||||||
/// hash_derivation_modulo of the current Derivation.
|
/// ask the caller of this function to provide the result of the
|
||||||
|
/// [hash_derivation_modulo] call of the current [Derivation],
|
||||||
|
/// and leave it up to them to calculate it when needed.
|
||||||
///
|
///
|
||||||
/// On completion, self.environment[$outputName] and
|
/// On completion, `self.environment[$outputName]` and
|
||||||
/// self.outputs[$outputName].path are set to the calculated output path for all
|
/// `self.outputs[$outputName].path` are set to the calculated output path for all
|
||||||
/// outputs.
|
/// outputs.
|
||||||
pub fn calculate_output_paths(
|
pub fn calculate_output_paths(
|
||||||
&mut self,
|
&mut self,
|
||||||
name: &str,
|
name: &str,
|
||||||
derivation_or_fod_hash: &[u8; 32],
|
hash_derivation_modulo: &[u8; 32],
|
||||||
) -> Result<(), DerivationError> {
|
) -> Result<(), DerivationError> {
|
||||||
// The fingerprint and hash differs per output
|
// The fingerprint and hash differs per output
|
||||||
for (output_name, output) in self.outputs.iter_mut() {
|
for (output_name, output) in self.outputs.iter_mut() {
|
||||||
|
@ -250,14 +253,14 @@ impl Derivation {
|
||||||
|
|
||||||
let path_name = output_path_name(name, output_name);
|
let path_name = output_path_name(name, output_name);
|
||||||
|
|
||||||
// For fixed output derivation we use the per-output info, otherwise we use the
|
// For fixed output derivation we use [build_ca_path], otherwise we
|
||||||
// derivation hash.
|
// use [build_output_path] with [hash_derivation_modulo].
|
||||||
let abs_store_path = if let Some(ref hwm) = output.ca_hash {
|
let abs_store_path = if let Some(ref hwm) = output.ca_hash {
|
||||||
build_ca_path(&path_name, hwm, Vec::<String>::new(), false).map_err(|e| {
|
build_ca_path(&path_name, hwm, Vec::<String>::new(), false).map_err(|e| {
|
||||||
DerivationError::InvalidOutputDerivationPath(output_name.to_string(), e)
|
DerivationError::InvalidOutputDerivationPath(output_name.to_string(), e)
|
||||||
})?
|
})?
|
||||||
} else {
|
} else {
|
||||||
build_output_path(derivation_or_fod_hash, output_name, &path_name).map_err(|e| {
|
build_output_path(hash_derivation_modulo, output_name, &path_name).map_err(|e| {
|
||||||
DerivationError::InvalidOutputDerivationPath(
|
DerivationError::InvalidOutputDerivationPath(
|
||||||
output_name.to_string(),
|
output_name.to_string(),
|
||||||
store_path::BuildStorePathError::InvalidStorePath(e),
|
store_path::BuildStorePathError::InvalidStorePath(e),
|
||||||
|
|
|
@ -164,7 +164,7 @@ fn derivation_path(#[case] name: &str, #[case] expected_path: &str) {
|
||||||
|
|
||||||
/// This trims all output paths from a Derivation struct,
|
/// This trims all output paths from a Derivation struct,
|
||||||
/// by setting outputs[$outputName].path and environment[$outputName] to the empty string.
|
/// by setting outputs[$outputName].path and environment[$outputName] to the empty string.
|
||||||
fn derivation_with_trimmed_output_paths(derivation: &Derivation) -> Derivation {
|
fn derivation_without_output_paths(derivation: &Derivation) -> Derivation {
|
||||||
let mut trimmed_env = derivation.environment.clone();
|
let mut trimmed_env = derivation.environment.clone();
|
||||||
let mut trimmed_outputs = derivation.outputs.clone();
|
let mut trimmed_outputs = derivation.outputs.clone();
|
||||||
|
|
||||||
|
@ -191,13 +191,13 @@ fn derivation_with_trimmed_output_paths(derivation: &Derivation) -> Derivation {
|
||||||
#[rstest]
|
#[rstest]
|
||||||
#[case::fixed_sha256("0hm2f1psjpcwg8fijsmr4wwxrx59s092-bar.drv", hex!("724f3e3634fce4cbbbd3483287b8798588e80280660b9a63fd13a1bc90485b33"))]
|
#[case::fixed_sha256("0hm2f1psjpcwg8fijsmr4wwxrx59s092-bar.drv", hex!("724f3e3634fce4cbbbd3483287b8798588e80280660b9a63fd13a1bc90485b33"))]
|
||||||
#[case::fixed_sha1("ss2p4wmxijn652haqyd7dckxwl4c7hxx-bar.drv", hex!("c79aebd0ce3269393d4a1fde2cbd1d975d879b40f0bf40a48f550edc107fd5df"))]
|
#[case::fixed_sha1("ss2p4wmxijn652haqyd7dckxwl4c7hxx-bar.drv", hex!("c79aebd0ce3269393d4a1fde2cbd1d975d879b40f0bf40a48f550edc107fd5df"))]
|
||||||
fn derivation_or_fod_hash(#[case] drv_path: &str, #[case] expected_digest: [u8; 32]) {
|
fn hash_derivation_modulo_fixed(#[case] drv_path: &str, #[case] expected_digest: [u8; 32]) {
|
||||||
// read in the fixture
|
// read in the fixture
|
||||||
let json_bytes =
|
let json_bytes =
|
||||||
fs::read(format!("{}/ok/{}.json", RESOURCES_PATHS, drv_path)).expect("unable to read JSON");
|
fs::read(format!("{}/ok/{}.json", RESOURCES_PATHS, drv_path)).expect("unable to read JSON");
|
||||||
let drv: Derivation = serde_json::from_slice(&json_bytes).expect("must deserialize");
|
let drv: Derivation = serde_json::from_slice(&json_bytes).expect("must deserialize");
|
||||||
|
|
||||||
let actual = drv.derivation_or_fod_hash(|_| panic!("must not be called"));
|
let actual = drv.hash_derivation_modulo(|_| panic!("must not be called"));
|
||||||
assert_eq!(expected_digest, actual);
|
assert_eq!(expected_digest, actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,13 +224,13 @@ fn output_paths(#[case] name: &str, #[case] drv_path_str: &str) {
|
||||||
)
|
)
|
||||||
.expect("must succeed");
|
.expect("must succeed");
|
||||||
|
|
||||||
// create a version with trimmed output paths, simulating we constructed
|
// create a version without output paths, simulating we constructed the
|
||||||
// the struct.
|
// struct.
|
||||||
let mut derivation = derivation_with_trimmed_output_paths(&expected_derivation);
|
let mut derivation = derivation_without_output_paths(&expected_derivation);
|
||||||
|
|
||||||
// calculate the derivation_or_fod_hash of derivation
|
// calculate the hash_derivation_modulo of Derivation
|
||||||
// We don't expect the lookup function to be called for most derivations.
|
// We don't expect the lookup function to be called for most derivations.
|
||||||
let calculated_derivation_or_fod_hash = derivation.derivation_or_fod_hash(|parent_drv_path| {
|
let actual_hash_derivation_modulo = derivation.hash_derivation_modulo(|parent_drv_path| {
|
||||||
// 4wvvbi4jwn0prsdxb7vs673qa5h9gr7x-foo.drv may lookup /nix/store/0hm2f1psjpcwg8fijsmr4wwxrx59s092-bar.drv
|
// 4wvvbi4jwn0prsdxb7vs673qa5h9gr7x-foo.drv may lookup /nix/store/0hm2f1psjpcwg8fijsmr4wwxrx59s092-bar.drv
|
||||||
// ch49594n9avinrf8ip0aslidkc4lxkqv-foo.drv may lookup /nix/store/ss2p4wmxijn652haqyd7dckxwl4c7hxx-bar.drv
|
// ch49594n9avinrf8ip0aslidkc4lxkqv-foo.drv may lookup /nix/store/ss2p4wmxijn652haqyd7dckxwl4c7hxx-bar.drv
|
||||||
if name == "foo"
|
if name == "foo"
|
||||||
|
@ -255,9 +255,9 @@ fn output_paths(#[case] name: &str, #[case] drv_path_str: &str) {
|
||||||
|
|
||||||
let drv: Derivation = serde_json::from_slice(&json_bytes).expect("must deserialize");
|
let drv: Derivation = serde_json::from_slice(&json_bytes).expect("must deserialize");
|
||||||
|
|
||||||
// calculate derivation_or_fod_hash for each parent.
|
// calculate hash_derivation_modulo for each parent.
|
||||||
// This may not trigger subsequent requests, as both parents are FOD.
|
// This may not trigger subsequent requests, as both parents are FOD.
|
||||||
drv.derivation_or_fod_hash(|_| panic!("must not lookup"))
|
drv.hash_derivation_modulo(|_| panic!("must not lookup"))
|
||||||
} else {
|
} else {
|
||||||
// we only expect this to be called in the "foo" testcase, for the "bar derivations"
|
// we only expect this to be called in the "foo" testcase, for the "bar derivations"
|
||||||
panic!("may only be called for foo testcase on bar derivations");
|
panic!("may only be called for foo testcase on bar derivations");
|
||||||
|
@ -265,7 +265,7 @@ fn output_paths(#[case] name: &str, #[case] drv_path_str: &str) {
|
||||||
});
|
});
|
||||||
|
|
||||||
derivation
|
derivation
|
||||||
.calculate_output_paths(name, &calculated_derivation_or_fod_hash)
|
.calculate_output_paths(name, &actual_hash_derivation_modulo)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// The derivation should now look like it was before
|
// The derivation should now look like it was before
|
||||||
|
@ -343,7 +343,7 @@ fn output_path_construction() {
|
||||||
// calculate bar output paths
|
// calculate bar output paths
|
||||||
let bar_calc_result = bar_drv.calculate_output_paths(
|
let bar_calc_result = bar_drv.calculate_output_paths(
|
||||||
"bar",
|
"bar",
|
||||||
&bar_drv.derivation_or_fod_hash(|_| panic!("is FOD, should not lookup")),
|
&bar_drv.hash_derivation_modulo(|_| panic!("is FOD, should not lookup")),
|
||||||
);
|
);
|
||||||
assert!(bar_calc_result.is_ok());
|
assert!(bar_calc_result.is_ok());
|
||||||
|
|
||||||
|
@ -360,8 +360,8 @@ fn output_path_construction() {
|
||||||
// now construct foo, which requires bar_drv
|
// now construct foo, which requires bar_drv
|
||||||
// Note how we refer to the output path, drv name and replacement_str (with calculated output paths) of bar.
|
// Note how we refer to the output path, drv name and replacement_str (with calculated output paths) of bar.
|
||||||
let bar_output_path = &bar_drv.outputs.get("out").expect("must exist").path;
|
let bar_output_path = &bar_drv.outputs.get("out").expect("must exist").path;
|
||||||
let bar_drv_derivation_or_fod_hash =
|
let bar_drv_hash_derivation_modulo =
|
||||||
bar_drv.derivation_or_fod_hash(|_| panic!("is FOD, should not lookup"));
|
bar_drv.hash_derivation_modulo(|_| panic!("is FOD, should not lookup"));
|
||||||
|
|
||||||
let bar_drv_path = bar_drv
|
let bar_drv_path = bar_drv
|
||||||
.calculate_derivation_path("bar")
|
.calculate_derivation_path("bar")
|
||||||
|
@ -408,11 +408,11 @@ fn output_path_construction() {
|
||||||
// calculate foo output paths
|
// calculate foo output paths
|
||||||
let foo_calc_result = foo_drv.calculate_output_paths(
|
let foo_calc_result = foo_drv.calculate_output_paths(
|
||||||
"foo",
|
"foo",
|
||||||
&foo_drv.derivation_or_fod_hash(|drv_path| {
|
&foo_drv.hash_derivation_modulo(|drv_path| {
|
||||||
if drv_path.to_string() != "0hm2f1psjpcwg8fijsmr4wwxrx59s092-bar.drv" {
|
if drv_path.to_string() != "0hm2f1psjpcwg8fijsmr4wwxrx59s092-bar.drv" {
|
||||||
panic!("lookup called with unexpected drv_path: {}", drv_path);
|
panic!("lookup called with unexpected drv_path: {}", drv_path);
|
||||||
}
|
}
|
||||||
bar_drv_derivation_or_fod_hash
|
bar_drv_hash_derivation_modulo
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
assert!(foo_calc_result.is_ok());
|
assert!(foo_calc_result.is_ok());
|
||||||
|
|
Loading…
Reference in a new issue