feat(tvix/derivation): add path_with_references
This allows the calculation of a store path for a plain string that potentially contains references. These paths are used for `builtins.toFile` (and potentially other features of C++ Nix). Change-Id: Ic507c7f264f362b5e6e628255869e5a4fbe4d788 Reviewed-on: https://cl.tvl.fyi/c/depot/+/7906 Tested-by: BuildkiteCI Reviewed-by: flokli <flokli@flokli.de>
This commit is contained in:
parent
be7f64ac87
commit
5d856ac2e9
3 changed files with 63 additions and 1 deletions
|
@ -75,6 +75,32 @@ fn build_store_path(
|
|||
// invalid, so map errors to a [DerivationError::InvalidOutputName].
|
||||
}
|
||||
|
||||
/// Build a store path for a literal text file in the store that may
|
||||
/// contain references.
|
||||
pub fn path_with_references<'a, I: IntoIterator<Item = &'a str>, C: AsRef<[u8]>>(
|
||||
name: &str,
|
||||
content: C,
|
||||
references: I,
|
||||
) -> Result<StorePath, DerivationError> {
|
||||
let mut hasher = Sha256::new();
|
||||
hasher.update(content);
|
||||
let content_hash = hasher.finalize_reset();
|
||||
|
||||
hasher.update("text");
|
||||
for reference in references {
|
||||
hasher.update(":");
|
||||
hasher.update(reference);
|
||||
}
|
||||
|
||||
hasher.update(&format!(":sha256:{:x}:", content_hash));
|
||||
hasher.update(STORE_DIR);
|
||||
hasher.update(&format!(":{}", name));
|
||||
|
||||
let digest = hasher.finalize();
|
||||
|
||||
build_store_path(false, &digest, name)
|
||||
}
|
||||
|
||||
impl Derivation {
|
||||
pub fn serialize(&self, writer: &mut impl Write) -> Result<(), fmt::Error> {
|
||||
writer.write_str(write::DERIVATION_PREFIX)?;
|
||||
|
|
|
@ -10,6 +10,6 @@ mod tests;
|
|||
|
||||
// Public API of the crate.
|
||||
|
||||
pub use derivation::Derivation;
|
||||
pub use derivation::{path_with_references, Derivation};
|
||||
pub use errors::{DerivationError, OutputError};
|
||||
pub use output::{Hash, Output};
|
||||
|
|
|
@ -305,3 +305,39 @@ fn output_path_construction() {
|
|||
.expect("must succeed")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn path_with_zero_references() {
|
||||
// This hash should match `builtins.toFile`, e.g.:
|
||||
//
|
||||
// nix-repl> builtins.toFile "foo" "bar"
|
||||
// "/nix/store/vxjiwkjkn7x4079qvh1jkl5pn05j2aw0-foo"
|
||||
|
||||
let store_path = crate::path_with_references("foo", "bar", vec![])
|
||||
.expect("path_with_references() should succeed");
|
||||
|
||||
assert_eq!(
|
||||
store_path.to_absolute_path().as_str(),
|
||||
"/nix/store/vxjiwkjkn7x4079qvh1jkl5pn05j2aw0-foo"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn path_with_non_zero_references() {
|
||||
// This hash should match:
|
||||
//
|
||||
// nix-repl> builtins.toFile "baz" "${builtins.toFile "foo" "bar"}"
|
||||
// "/nix/store/5xd714cbfnkz02h2vbsj4fm03x3f15nf-baz"
|
||||
|
||||
let inner = crate::path_with_references("foo", "bar", vec![])
|
||||
.expect("path_with_references() should succeed");
|
||||
let inner_path = inner.to_absolute_path();
|
||||
|
||||
let outer = crate::path_with_references("baz", &inner_path, vec![inner_path.as_str()])
|
||||
.expect("path_with_references() should succeed");
|
||||
|
||||
assert_eq!(
|
||||
outer.to_absolute_path().as_str(),
|
||||
"/nix/store/5xd714cbfnkz02h2vbsj4fm03x3f15nf-baz"
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue