From 3d7c371e2208c6171a70c0b0485fcd7e6ea6d47b Mon Sep 17 00:00:00 2001 From: Vincent Ambo Date: Mon, 23 Jan 2023 01:38:36 +0300 Subject: feat(tvix/cli): add helper for handling special drv parameters Adds a helper function which handles special parameters to `builtins.derivation` that are not just blindly passed through to the builder environment, but populate other specific fields of the derivation (outside of the ones handled by other, more complex helpers from previous commits). Change-Id: I82d1edf9af714fc4591e9071c0b83ece83be7eee Reviewed-on: https://cl.tvl.fyi/c/depot/+/7901 Reviewed-by: flokli Tested-by: BuildkiteCI --- tvix/cli/src/derivation.rs | 106 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) (limited to 'tvix/cli') diff --git a/tvix/cli/src/derivation.rs b/tvix/cli/src/derivation.rs index 5b696ec18e..6047117991 100644 --- a/tvix/cli/src/derivation.rs +++ b/tvix/cli/src/derivation.rs @@ -7,6 +7,9 @@ use tvix_eval::{AddContext, CoercionKind, ErrorKind, NixList, Value, VM}; use crate::errors::Error; use crate::known_paths::{KnownPaths, PathType}; +// Constants used for strangely named fields in derivation inputs. +const IGNORE_NULLS: &str = "__ignoreNulls"; + /// Helper function for populating the `drv.outputs` field from a /// manually specified set of outputs, instead of the default /// `outputs`. @@ -131,6 +134,60 @@ fn populate_output_configuration( Ok(()) } +/// Handles derivation parameters which are not just forwarded to +/// the environment. The return value indicates whether the +/// parameter should be included in the environment. +fn handle_derivation_parameters( + drv: &mut Derivation, + vm: &mut VM, + name: &str, + value: &Value, + val_str: &str, +) -> Result { + match name { + IGNORE_NULLS => return Ok(false), + + // Command line arguments to the builder. + "args" => { + let args = value.to_list()?; + for arg in args { + drv.arguments.push( + arg.force(vm)? + .coerce_to_string(CoercionKind::Strong, vm) + .context("handling command-line builder arguments")? + .as_str() + .to_string(), + ); + } + + // The arguments do not appear in the environment. + return Ok(false); + } + + // Explicitly specified drv outputs (instead of default [ "out" ]) + "outputs" => { + let outputs = value + .to_list() + .context("looking at the `outputs` parameter of the derivation")?; + + drv.outputs.clear(); + populate_outputs(vm, drv, outputs)?; + } + + "builder" => { + drv.builder = val_str.to_string(); + } + + "system" => { + drv.system = val_str.to_string(); + } + + _ => {} + } + + Ok(true) +} + #[cfg(test)] mod tests { use super::*; @@ -291,4 +348,53 @@ mod tests { assert_eq!(drv.outputs["out"].hash, Some(expected)); } + + #[test] + fn handle_outputs_parameter() { + let mut vm = fake_vm(); + let mut drv = Derivation::default(); + drv.outputs.insert("out".to_string(), Default::default()); + + let outputs = Value::List(NixList::construct( + 2, + vec![Value::String("foo".into()), Value::String("bar".into())], + )); + let outputs_str = outputs + .coerce_to_string(CoercionKind::Strong, &mut vm) + .unwrap(); + + handle_derivation_parameters(&mut drv, &mut vm, "outputs", &outputs, outputs_str.as_str()) + .expect("handling 'outputs' parameter should succeed"); + + assert_eq!(drv.outputs.len(), 2); + assert!(drv.outputs.contains_key("bar")); + assert!(drv.outputs.contains_key("foo")); + } + + #[test] + fn handle_args_parameter() { + let mut vm = fake_vm(); + let mut drv = Derivation::default(); + + let args = Value::List(NixList::construct( + 3, + vec![ + Value::String("--foo".into()), + Value::String("42".into()), + Value::String("--bar".into()), + ], + )); + + let args_str = args + .coerce_to_string(CoercionKind::Strong, &mut vm) + .unwrap(); + + handle_derivation_parameters(&mut drv, &mut vm, "args", &args, args_str.as_str()) + .expect("handling 'args' parameter should succeed"); + + assert_eq!( + drv.arguments, + vec!["--foo".to_string(), "42".to_string(), "--bar".to_string()] + ); + } } -- cgit 1.4.1