diff --git a/Cargo.lock b/Cargo.lock index 06a34742..1ef12819 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3567,6 +3567,7 @@ dependencies = [ "sha1", "sha2", "spdx", + "strum", "tar", "tempfile", "terminal_size 0.4.0", diff --git a/Cargo.toml b/Cargo.toml index fb86f722..bef847c6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -143,6 +143,7 @@ rattler_solve = { version = "1.2.3", default-features = false, features = ["reso rattler_virtual_packages = { version = "1.1.10", default-features = false } rattler_package_streaming = { version = "0.22.13", default-features = false } lazy_static = "1.5.0" +strum = "0.26.3" [dev-dependencies] insta = { version = "1.41.1", features = ["yaml"] } diff --git a/src/recipe/jinja.rs b/src/recipe/jinja.rs index 6745f04c..ca5ba1a1 100644 --- a/src/recipe/jinja.rs +++ b/src/recipe/jinja.rs @@ -399,6 +399,9 @@ fn set_jinja(config: &SelectorConfig) -> minijinja::Environment<'static> { } = config.clone(); let mut env = Environment::empty(); + if !allow_undefined { + env.set_undefined_behavior(minijinja::UndefinedBehavior::Strict); + } default_tests(&mut env); default_filters(&mut env); diff --git a/src/selectors.rs b/src/selectors.rs index f1347b6c..a79cf4b9 100644 --- a/src/selectors.rs +++ b/src/selectors.rs @@ -10,6 +10,7 @@ use crate::{ use minijinja::value::Value; use rattler_conda_types::Platform; +use strum::IntoEnumIterator; /// The selector config is used to render the recipe. #[derive(Clone, Debug)] @@ -45,15 +46,20 @@ impl SelectorConfig { Value::from_safe_string(self.host_platform.to_string()), ); - if let Some(platform) = self.host_platform.only_platform() { - context.insert( - platform.to_string(), - Value::from_safe_string(platform.to_string()), - ); - } - - if let Some(arch) = self.target_platform.arch() { - context.insert(arch.to_string(), Value::from(true)); + for platform in Platform::iter() { + if let Some(only_platform) = platform.only_platform() { + context.insert( + only_platform.to_string(), + Value::from(self.host_platform == platform), + ); + } + + if let Some(arch) = platform.arch() { + context.insert( + arch.to_string(), + Value::from(self.host_platform.arch() == Some(arch)), + ); + } } context.insert( @@ -88,14 +94,22 @@ impl SelectorConfig { /// Create a new selector config from an existing one, replacing the variant pub fn with_variant( - &self, + self, variant: BTreeMap, target_platform: Platform, ) -> Self { Self { variant, target_platform, - ..self.clone() + ..self + } + } + + /// Set allow_undefined for this Jinja context / selector config + pub fn with_allow_undefined(self, allow_undefined: bool) -> Self { + Self { + allow_undefined, + ..self } } } diff --git a/src/variant_render.rs b/src/variant_render.rs index a952a892..7cc8fe0d 100644 --- a/src/variant_render.rs +++ b/src/variant_render.rs @@ -88,8 +88,9 @@ pub(crate) fn stage_0_render( let mut rendered_outputs = Vec::new(); // TODO: figure out if we can pre-compute the `noarch` value. for output in outputs { - let config_with_variant = - selector_config.with_variant(combination.clone(), selector_config.target_platform); + let config_with_variant = selector_config + .clone() + .with_variant(combination.clone(), selector_config.target_platform); let parsed_recipe = Recipe::from_node(output, config_with_variant).map_err(|err| { let errs: ParseErrors = err @@ -381,7 +382,9 @@ pub(crate) fn stage_1_render( for (idx, output) in r.raw_outputs.vec.iter().enumerate() { // use the correct target_platform here? let config_with_variant = selector_config - .with_variant(combination.clone(), selector_config.target_platform); + .clone() + .with_variant(combination.clone(), selector_config.target_platform) + .with_allow_undefined(false); let parsed_recipe = Recipe::from_node(output, config_with_variant.clone()).unwrap();