diff options
-rw-r--r-- | tvix/eval/src/builtins/mod.rs | 15 | ||||
-rw-r--r-- | tvix/eval/src/builtins/to_xml.rs | 29 | ||||
-rw-r--r-- | tvix/glue/src/tests/tvix_tests/eval-okay-toxml-context.exp | 1 | ||||
-rw-r--r-- | tvix/glue/src/tests/tvix_tests/eval-okay-toxml-context.nix | 14 |
4 files changed, 53 insertions, 6 deletions
diff --git a/tvix/eval/src/builtins/mod.rs b/tvix/eval/src/builtins/mod.rs index 4a15f944a4b3..2178d9c44f6b 100644 --- a/tvix/eval/src/builtins/mod.rs +++ b/tvix/eval/src/builtins/mod.rs @@ -1504,8 +1504,19 @@ mod pure_builtins { } let mut buf: Vec<u8> = vec![]; - to_xml::value_to_xml(&mut buf, &value)?; - Ok(buf.into()) + let context = to_xml::value_to_xml(&mut buf, &value)?; + + Ok(( + buf, + // FUTUREWORK: We have a distinction between an empty context, and + // no context at all. Fix this. + if !context.is_empty() { + Some(Box::new(context)) + } else { + None + }, + ) + .into()) } #[builtin("placeholder")] diff --git a/tvix/eval/src/builtins/to_xml.rs b/tvix/eval/src/builtins/to_xml.rs index 10a6d8cdb358..093e127fe25e 100644 --- a/tvix/eval/src/builtins/to_xml.rs +++ b/tvix/eval/src/builtins/to_xml.rs @@ -6,11 +6,12 @@ use bstr::ByteSlice; use std::borrow::Cow; use std::{io::Write, rc::Rc}; -use crate::{ErrorKind, Value}; +use crate::{ErrorKind, NixContext, NixContextElement, Value}; /// Recursively serialise a value to XML. The value *must* have been /// deep-forced before being passed to this function. -pub fn value_to_xml<W: Write>(mut writer: W, value: &Value) -> Result<(), ErrorKind> { +/// On success, returns the NixContext. +pub fn value_to_xml<W: Write>(mut writer: W, value: &Value) -> Result<NixContext, ErrorKind> { // Write a literal document declaration, using C++-Nix-style // single quotes. writeln!(writer, "<?xml version='1.0' encoding='utf-8'?>")?; @@ -21,7 +22,7 @@ pub fn value_to_xml<W: Write>(mut writer: W, value: &Value) -> Result<(), ErrorK value_variant_to_xml(&mut emitter, value)?; emitter.write_closing_tag("expr")?; - Ok(()) + Ok(emitter.into_context()) } fn write_typed_value<W: Write, V: ToString>( @@ -45,7 +46,12 @@ fn value_variant_to_xml<W: Write>(w: &mut XmlEmitter<W>, value: &Value) -> Resul Value::Bool(b) => return write_typed_value(w, "bool", b), Value::Integer(i) => return write_typed_value(w, "int", i), Value::Float(f) => return write_typed_value(w, "float", f), - Value::String(s) => return write_typed_value(w, "string", s.to_str()?), + Value::String(s) => { + if let Some(context) = s.context() { + w.extend_context(context.iter().cloned()); + } + return write_typed_value(w, "string", s.to_str()?); + } Value::Path(p) => return write_typed_value(w, "path", p.to_string_lossy()), Value::List(list) => { @@ -137,6 +143,7 @@ struct XmlEmitter<W> { /// The current indentation cur_indent: usize, writer: W, + context: NixContext, } impl<W: Write> XmlEmitter<W> { @@ -144,6 +151,7 @@ impl<W: Write> XmlEmitter<W> { XmlEmitter { cur_indent: 0, writer, + context: Default::default(), } } @@ -245,6 +253,19 @@ impl<W: Write> XmlEmitter<W> { _ => None, } } + + /// Extends the existing context with more context elements. + fn extend_context<T>(&mut self, iter: T) + where + T: IntoIterator<Item = NixContextElement>, + { + self.context.extend(iter) + } + + /// Consumes [Self] and returns the [NixContext] collected. + fn into_context(self) -> NixContext { + self.context + } } #[cfg(test)] diff --git a/tvix/glue/src/tests/tvix_tests/eval-okay-toxml-context.exp b/tvix/glue/src/tests/tvix_tests/eval-okay-toxml-context.exp new file mode 100644 index 000000000000..e9600ecdad7a --- /dev/null +++ b/tvix/glue/src/tests/tvix_tests/eval-okay-toxml-context.exp @@ -0,0 +1 @@ +[ { "/nix/store/y1s2fiq89v2h9vkb38w508ir20dwv6v2-test.drv" = { allOutputs = true; }; } false ] diff --git a/tvix/glue/src/tests/tvix_tests/eval-okay-toxml-context.nix b/tvix/glue/src/tests/tvix_tests/eval-okay-toxml-context.nix new file mode 100644 index 000000000000..933aa46022dd --- /dev/null +++ b/tvix/glue/src/tests/tvix_tests/eval-okay-toxml-context.nix @@ -0,0 +1,14 @@ +[ + # builtins.toXML retains context where there is. + (builtins.getContext (builtins.toXML { + inherit (derivation { + name = "test"; + builder = "/bin/sh"; + system = builtins.currentSystem; + }) drvPath; + })) + + # this should have no context. + (builtins.hasContext + (builtins.toXML { })) +] |