about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Kolloch <info@eigenvalue.net>2024-02-21T07·07+0700
committerclbot <clbot@tvl.fyi>2024-02-21T11·34+0000
commit035f617b7f11f2ec4a9e08e3a31a175e71a6544b (patch)
tree67bf2b777167dbfa1c7a885ed333a1f723dd994e
parentc06fb01b3b7a752e0c04ba21a02cdc3f431055e1 (diff)
feat(tvix/nix-compat): input_sources as StorePath r/7584
https: //b.tvl.fyi/issues/264
Change-Id: I7a235734dc1f8e93e387a04ba369f3b702c6d5b6
Reviewed-on: https://cl.tvl.fyi/c/depot/+/10992
Autosubmit: Peter Kolloch <info@eigenvalue.net>
Reviewed-by: flokli <flokli@flokli.de>
Reviewed-by: Peter Kolloch <info@eigenvalue.net>
Tested-by: BuildkiteCI
-rw-r--r--tvix/glue/src/builtins/derivation.rs7
-rw-r--r--tvix/nix-compat/src/derivation/mod.rs18
-rw-r--r--tvix/nix-compat/src/derivation/parse_error.rs7
-rw-r--r--tvix/nix-compat/src/derivation/parser.rs26
-rw-r--r--tvix/nix-compat/src/derivation/validate.rs12
-rw-r--r--tvix/nix-compat/src/derivation/write.rs14
6 files changed, 53 insertions, 31 deletions
diff --git a/tvix/glue/src/builtins/derivation.rs b/tvix/glue/src/builtins/derivation.rs
index 1208ca94de04..87ae8bb946bd 100644
--- a/tvix/glue/src/builtins/derivation.rs
+++ b/tvix/glue/src/builtins/derivation.rs
@@ -4,7 +4,7 @@ use crate::tvix_store_io::TvixStoreIO;
 use bstr::BString;
 use nix_compat::derivation::{Derivation, Output};
 use nix_compat::nixhash;
-use nix_compat::store_path::StorePath;
+use nix_compat::store_path::{StorePath, StorePathRef};
 use std::collections::{btree_map, BTreeSet};
 use std::rc::Rc;
 use tvix_eval::builtin_macros::builtins;
@@ -24,7 +24,10 @@ fn populate_inputs(drv: &mut Derivation, full_context: NixContext) {
     for element in full_context.iter() {
         match element {
             NixContextElement::Plain(source) => {
-                drv.input_sources.insert(source.clone());
+                let sp = StorePathRef::from_absolute_path(source.as_bytes())
+                    .expect("invalid store path")
+                    .to_owned();
+                drv.input_sources.insert(sp);
             }
 
             NixContextElement::Single {
diff --git a/tvix/nix-compat/src/derivation/mod.rs b/tvix/nix-compat/src/derivation/mod.rs
index 3cf9a5ba7f22..2e4178b872f6 100644
--- a/tvix/nix-compat/src/derivation/mod.rs
+++ b/tvix/nix-compat/src/derivation/mod.rs
@@ -40,7 +40,7 @@ pub struct Derivation {
 
     /// Plain store paths of additional inputs.
     #[serde(rename = "inputSrcs")]
-    pub input_sources: BTreeSet<String>,
+    pub input_sources: BTreeSet<StorePath>,
 
     /// Maps output names to Output.
     pub outputs: BTreeMap<String, Output>,
@@ -131,16 +131,12 @@ impl Derivation {
 
         // collect the list of paths from input_sources and input_derivations
         // into a (sorted, guaranteed by BTreeSet) list of references
-        let references: BTreeSet<String> = {
-            let mut inputs = self.input_sources.clone();
-            let input_derivation_keys: Vec<String> = self
-                .input_derivations
-                .keys()
-                .map(|k| k.to_absolute_path())
-                .collect();
-            inputs.extend(input_derivation_keys);
-            inputs
-        };
+        let references: BTreeSet<String> = self
+            .input_sources
+            .iter()
+            .chain(self.input_derivations.keys())
+            .map(StorePath::to_absolute_path)
+            .collect();
 
         build_text_path(name, self.to_aterm_bytes(), references)
             .map(|s| s.to_owned())
diff --git a/tvix/nix-compat/src/derivation/parse_error.rs b/tvix/nix-compat/src/derivation/parse_error.rs
index 68228b07c4bc..fc97f1a9883b 100644
--- a/tvix/nix-compat/src/derivation/parse_error.rs
+++ b/tvix/nix-compat/src/derivation/parse_error.rs
@@ -2,7 +2,10 @@
 //! Derivations from ATerm.
 use nom::IResult;
 
-use crate::{nixhash, store_path};
+use crate::{
+    nixhash,
+    store_path::{self, StorePath},
+};
 
 pub type NomResult<I, O> = IResult<I, O, NomError<I>>;
 
@@ -17,7 +20,7 @@ pub enum ErrorKind {
     DuplicateInputDerivationOutputName(String, String),
 
     #[error("duplicate input source: {0}")]
-    DuplicateInputSource(String),
+    DuplicateInputSource(StorePath),
 
     #[error("nix hash error: {0}")]
     NixHashError(nixhash::Error),
diff --git a/tvix/nix-compat/src/derivation/parser.rs b/tvix/nix-compat/src/derivation/parser.rs
index 2cfcf2eae377..9f5a5f090bf9 100644
--- a/tvix/nix-compat/src/derivation/parser.rs
+++ b/tvix/nix-compat/src/derivation/parser.rs
@@ -186,11 +186,19 @@ fn parse_input_derivations(i: &[u8]) -> NomResult<&[u8], BTreeMap<StorePath, BTr
     Ok((i, input_derivations))
 }
 
-fn parse_input_sources(i: &[u8]) -> NomResult<&[u8], BTreeSet<String>> {
+fn parse_input_sources(i: &[u8]) -> NomResult<&[u8], BTreeSet<StorePath>> {
     let (i, input_sources_lst) = aterm::parse_str_list(i).map_err(into_nomerror)?;
 
     let mut input_sources: BTreeSet<_> = BTreeSet::new();
     for input_source in input_sources_lst.into_iter() {
+        let input_source: StorePath = StorePathRef::from_absolute_path(input_source.as_bytes())
+            .map_err(|e: store_path::Error| {
+                nom::Err::Failure(NomError {
+                    input: i,
+                    code: e.into(),
+                })
+            })?
+            .to_owned();
         if input_sources.contains(&input_source) {
             return Err(nom::Err::Failure(NomError {
                 input: i,
@@ -312,6 +320,7 @@ where
 
 #[cfg(test)]
 mod tests {
+    use crate::store_path::StorePathRef;
     use std::collections::{BTreeMap, BTreeSet};
 
     use crate::{
@@ -460,7 +469,14 @@ mod tests {
     fn parse_input_sources(input: &'static [u8], expected: &BTreeSet<String>) {
         let (rest, parsed) = super::parse_input_sources(input).expect("must parse");
 
-        assert_eq!(expected, &parsed, "parsed mismatch");
+        assert_eq!(
+            expected,
+            &parsed
+                .iter()
+                .map(StorePath::to_absolute_path)
+                .collect::<BTreeSet<_>>(),
+            "parsed mismatch"
+        );
         assert!(rest.is_empty(), "rest must be empty");
     }
 
@@ -474,7 +490,11 @@ mod tests {
             nom::Err::Failure(e) => {
                 assert_eq!(
                     ErrorKind::DuplicateInputSource(
-                        "/nix/store/55lwldka5nyxa08wnvlizyqw02ihy8ic-foo".to_string()
+                        StorePathRef::from_absolute_path(
+                            "/nix/store/55lwldka5nyxa08wnvlizyqw02ihy8ic-foo".as_bytes()
+                        )
+                        .unwrap()
+                        .to_owned()
                     ),
                     e.code
                 );
diff --git a/tvix/nix-compat/src/derivation/validate.rs b/tvix/nix-compat/src/derivation/validate.rs
index 757326816c63..af7dff2fdc6c 100644
--- a/tvix/nix-compat/src/derivation/validate.rs
+++ b/tvix/nix-compat/src/derivation/validate.rs
@@ -1,5 +1,5 @@
 use crate::derivation::{Derivation, DerivationError};
-use crate::store_path::{self, StorePathRef};
+use crate::store_path;
 
 impl Derivation {
     /// validate ensures a Derivation struct is properly populated,
@@ -87,16 +87,6 @@ impl Derivation {
             }
         }
 
-        // Validate all input_sources
-        for input_source in self.input_sources.iter() {
-            if let Err(e) = StorePathRef::from_absolute_path(input_source.as_bytes()) {
-                return Err(DerivationError::InvalidInputSourcesPath(
-                    input_source.to_string(),
-                    e,
-                ));
-            }
-        }
-
         // validate platform
         if self.system.is_empty() {
             return Err(DerivationError::InvalidPlatform(self.system.to_string()));
diff --git a/tvix/nix-compat/src/derivation/write.rs b/tvix/nix-compat/src/derivation/write.rs
index 83106cd9e60b..04810e736af6 100644
--- a/tvix/nix-compat/src/derivation/write.rs
+++ b/tvix/nix-compat/src/derivation/write.rs
@@ -33,6 +33,13 @@ pub const QUOTE: char = '"';
 /// the context a lot.
 pub(crate) trait AtermWriteable: Display {
     fn aterm_write(&self, writer: &mut impl Write) -> std::io::Result<()>;
+
+    fn aterm_bytes(&self) -> Vec<u8> {
+        let mut bytes = Vec::new();
+        self.aterm_write(&mut bytes)
+            .expect("unexpected write errors to Vec");
+        bytes
+    }
 }
 
 impl AtermWriteable for StorePathRef<'_> {
@@ -182,12 +189,15 @@ pub(crate) fn write_input_derivations(
 
 pub(crate) fn write_input_sources(
     writer: &mut impl Write,
-    input_sources: &BTreeSet<String>,
+    input_sources: &BTreeSet<StorePath>,
 ) -> Result<(), io::Error> {
     write_char(writer, BRACKET_OPEN)?;
     write_array_elements(
         writer,
-        &input_sources.iter().map(String::from).collect::<Vec<_>>(),
+        &input_sources
+            .iter()
+            .map(StorePath::to_absolute_path)
+            .collect::<Vec<_>>(),
     )?;
     write_char(writer, BRACKET_CLOSE)?;