diff --git a/src/lib.rs b/src/lib.rs index 4ea79a976..0ffb6949c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -164,6 +164,7 @@ pub async fn get_build_output( let selector_config = SelectorConfig { // We ignore noarch here target_platform: args.target_platform, + host_platform: args.target_platform, hash: None, build_platform: args.build_platform, variant: BTreeMap::new(), @@ -213,6 +214,7 @@ pub async fn get_build_output( variant: discovered_output.used_vars.clone(), hash: Some(hash.clone()), target_platform: selector_config.target_platform, + host_platform: selector_config.host_platform, build_platform: selector_config.build_platform, experimental: args.common.experimental, }; diff --git a/src/recipe/jinja.rs b/src/recipe/jinja.rs index f623ff478..13b120286 100644 --- a/src/recipe/jinja.rs +++ b/src/recipe/jinja.rs @@ -721,6 +721,7 @@ mod tests { fn eval() { let options = SelectorConfig { target_platform: Platform::Linux64, + host_platform: Platform::Linux64, build_platform: Platform::Linux64, ..Default::default() }; @@ -745,6 +746,7 @@ mod tests { fn eval2() { let options = SelectorConfig { target_platform: Platform::Linux64, + host_platform: Platform::Linux64, build_platform: Platform::Linux64, ..Default::default() }; @@ -759,6 +761,7 @@ mod tests { let variant = BTreeMap::new(); let options = SelectorConfig { target_platform: Platform::Linux64, + host_platform: Platform::Linux64, build_platform: Platform::Linux64, variant, ..Default::default() @@ -788,6 +791,7 @@ mod tests { let variant = BTreeMap::new(); let options = SelectorConfig { target_platform: Platform::Linux32, + host_platform: Platform::Linux32, build_platform: Platform::Linux32, variant, ..Default::default() @@ -817,6 +821,7 @@ mod tests { let variant = BTreeMap::new(); let options = SelectorConfig { target_platform: Platform::LinuxAarch64, + host_platform: Platform::LinuxAarch64, build_platform: Platform::LinuxAarch64, variant, ..Default::default() @@ -846,6 +851,7 @@ mod tests { let variant = BTreeMap::new(); let options = SelectorConfig { target_platform: Platform::LinuxArmV6l, + host_platform: Platform::LinuxArmV6l, build_platform: Platform::LinuxArmV6l, variant, ..Default::default() diff --git a/src/recipe/parser.rs b/src/recipe/parser.rs index be9be2fc6..937c134cf 100644 --- a/src/recipe/parser.rs +++ b/src/recipe/parser.rs @@ -314,6 +314,7 @@ mod tests { let selector_config_unix = SelectorConfig { target_platform: Platform::Linux64, + host_platform: Platform::Linux64, ..SelectorConfig::default() }; @@ -328,6 +329,7 @@ mod tests { let selector_config_win = SelectorConfig { target_platform: Platform::Win64, + host_platform: Platform::Win64, ..SelectorConfig::default() }; diff --git a/src/selectors.rs b/src/selectors.rs index 23e989d2a..8da2b9e2e 100644 --- a/src/selectors.rs +++ b/src/selectors.rs @@ -12,6 +12,8 @@ use rattler_conda_types::Platform; pub struct SelectorConfig { /// The target platform to render for pub target_platform: Platform, + /// The host platform (relevant for `noarch`) + pub host_platform: Platform, /// The build platform to render for pub build_platform: Platform, /// The hash, if available @@ -32,7 +34,7 @@ impl SelectorConfig { Value::from_safe_string(self.target_platform.to_string()), ); - if let Some(platform) = self.target_platform.only_platform() { + if let Some(platform) = self.host_platform.only_platform() { context.insert( platform.to_string(), Value::from_safe_string(platform.to_string()), @@ -45,7 +47,7 @@ impl SelectorConfig { context.insert( "unix".to_string(), - Value::from(self.target_platform.is_unix()), + Value::from(self.host_platform.is_unix()), ); context.insert( @@ -91,6 +93,7 @@ impl Default for SelectorConfig { fn default() -> Self { Self { target_platform: Platform::current(), + host_platform: Platform::current(), build_platform: Platform::current(), hash: None, variant: Default::default(), diff --git a/src/variant_config.rs b/src/variant_config.rs index 8b8d31c53..52d472051 100644 --- a/src/variant_config.rs +++ b/src/variant_config.rs @@ -910,6 +910,7 @@ mod tests { let selector_config = SelectorConfig { target_platform: Platform::Linux64, + host_platform: Platform::Linux64, build_platform: Platform::Linux64, variant: Default::default(), hash: None, @@ -923,6 +924,7 @@ mod tests { let selector_config = SelectorConfig { target_platform: Platform::Win64, + host_platform: Platform::Win64, build_platform: Platform::Win64, ..Default::default() }; @@ -939,6 +941,7 @@ mod tests { let yaml_file = test_data_dir.join("variant_files/variant_config_1.yaml"); let selector_config = SelectorConfig { target_platform: Platform::Linux64, + host_platform: Platform::Linux64, build_platform: Platform::Linux64, ..Default::default() }; @@ -954,6 +957,7 @@ mod tests { let yaml_file = test_data_dir.join("recipes/variants/variant_config.yaml"); let selector_config = SelectorConfig { target_platform: Platform::Linux64, + host_platform: Platform::Linux64, build_platform: Platform::Linux64, ..Default::default() }; @@ -1022,6 +1026,7 @@ mod tests { let test_data_dir = std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("test-data"); let selector_config = SelectorConfig { target_platform: Platform::Linux64, + host_platform: Platform::Linux64, build_platform: Platform::Linux64, ..Default::default() }; @@ -1053,6 +1058,7 @@ mod tests { let yaml_file = test_data_dir.join("recipes/variants/python_variant.yaml"); let selector_config = SelectorConfig { target_platform: Platform::NoArch, + host_platform: Platform::Linux64, build_platform: Platform::Linux64, ..Default::default() }; diff --git a/test-data/recipes/noarch_variant/recipe.yaml b/test-data/recipes/noarch_variant/recipe.yaml new file mode 100644 index 000000000..f428d8034 --- /dev/null +++ b/test-data/recipes/noarch_variant/recipe.yaml @@ -0,0 +1,29 @@ +context: + name: rattler-build-demo + version: 1 + build_variant: ${{ 'unix' if unix else 'win' }} + build_number: 0 + +outputs: + - package: + name: ${{ name }} + version: ${{ version }} + build: + noarch: generic + number: ${{ build_number }} + string: ${{ build_variant }}_${{ hash }}_${{ build_number }} + requirements: + run: + - ${{ "__unix" if unix }} + - ${{ "__win" if win }} + + - package: + name: ${{ name }}-subpackage + version: ${{ version }} + build: + noarch: generic + number: ${{ build_number }} + string: ${{ build_variant }}_${{ hash }}_${{ build_number }} + requirements: + run: + - ${{ pin_subpackage('rattler-build-demo', exact=True) }} diff --git a/test/end-to-end/test_simple.py b/test/end-to-end/test_simple.py index 743d7605d..8b972bf36 100644 --- a/test/end-to-end/test_simple.py +++ b/test/end-to-end/test_simple.py @@ -3,7 +3,7 @@ import os import platform from pathlib import Path -from subprocess import STDOUT, CalledProcessError, check_output +from subprocess import DEVNULL, STDOUT, CalledProcessError, check_output from typing import Any, Optional import pytest @@ -712,3 +712,65 @@ def test_read_only_removal(rattler_build: RattlerBuild, recipes: Path, tmp_path: pkg = get_extracted_package(tmp_path, "read-only-build-files") assert (pkg / "info/index.json").exists() + + +def test_noarch_variants(rattler_build: RattlerBuild, recipes: Path, tmp_path: Path): + path_to_recipe = recipes / "noarch_variant" + args = rattler_build.build_args( + path_to_recipe, + tmp_path, + ) + + output = rattler_build( + *args, "--target-platform=linux-64", "--render-only", stderr=DEVNULL + ) + + # parse as json + rendered = json.loads(output) + assert len(rendered) == 2 + + assert rendered[0]["recipe"]["requirements"]["run"] == ["__unix"] + assert rendered[0]["recipe"]["requirements"]["run"] == ["__unix"] + assert rendered[0]["recipe"]["build"]["string"] == "unix_4616a5c_0" + + pin = { + "pin_subpackage": { + "name": "rattler-build-demo", + "max_pin": None, + "min_pin": None, + "exact": True, + } + } + assert rendered[1]["recipe"]["build"]["string"] == "unix_2233755_0" + assert rendered[1]["recipe"]["build"]["noarch"] == "generic" + assert rendered[1]["recipe"]["requirements"]["run"] == [pin] + assert rendered[1]["build_configuration"]["variant"] == { + "rattler-build-demo": "1 unix_4616a5c_0", + "target_platform": "noarch", + } + + output = rattler_build( + *args, "--target-platform=win-64", "--render-only", stderr=DEVNULL + ) + rendered = json.loads(output) + assert len(rendered) == 2 + + assert rendered[0]["recipe"]["requirements"]["run"] == ["__win"] + assert rendered[0]["recipe"]["requirements"]["run"] == ["__win"] + assert rendered[0]["recipe"]["build"]["string"] == "win_4616a5c_0" + + pin = { + "pin_subpackage": { + "name": "rattler-build-demo", + "max_pin": None, + "min_pin": None, + "exact": True, + } + } + assert rendered[1]["recipe"]["build"]["string"] == "win_b28fc4d_0" + assert rendered[1]["recipe"]["build"]["noarch"] == "generic" + assert rendered[1]["recipe"]["requirements"]["run"] == [pin] + assert rendered[1]["build_configuration"]["variant"] == { + "rattler-build-demo": "1 win_4616a5c_0", + "target_platform": "noarch", + }