From 48bd0632f50d35ad2b75d73f45d332c658b4bb2f Mon Sep 17 00:00:00 2001 From: Callahan Date: Fri, 25 Aug 2023 11:01:04 -0500 Subject: [PATCH] environment: error when build-for arch variable cannot be evaluated (#4332) For core20 snaps, if the project variable `SNAPCRAFT_ARCH_BUILD_FOR` or `SNAPCRAFT_ARCH_TRIPLET_BUILD_FOR` cannot be determined and is used in a snapcraft.yaml file, then an error is raised. Signed-off-by: Callahan Kovacs --- .../pluginhandler/_part_environment.py | 10 +-- .../internal/project_loader/__init__.py | 51 ++++++++++++- .../internal/project_loader/errors.py | 13 +++- .../unit/pluginhandler/test_environment.py | 12 ++-- .../legacy/unit/project_loader/test_errors.py | 13 +++- .../unit/project_loader/test_replace_attr.py | 71 ++++++++++++++++++- .../snap/snapcraft.yaml | 18 +++++ .../snap/snapcraft.yaml | 18 +++++ .../build-for-part-error/snap/snapcraft.yaml | 17 +++++ .../snap/snapcraft.yaml | 17 +++++ .../snap/snapcraft.yaml | 18 +++++ .../snap/snapcraft.yaml | 18 +++++ .../environment-errors/task.yaml | 22 ++++++ .../build-for-multi-arch/expected-env.txt | 2 - .../build-for-multi-arch/snap/snapcraft.yaml | 11 ++- .../build-for-single-arch/snap/snapcraft.yaml | 11 ++- .../build-for-unknown-arch/expected-env.txt | 2 - .../snap/snapcraft.yaml | 11 ++- .../snaps/target-arch/snap/snapcraft.yaml | 11 ++- .../cross-compile/environment/task.yaml | 15 +++- 20 files changed, 327 insertions(+), 34 deletions(-) create mode 100644 tests/spread/cross-compile/environment-errors/snaps/build-for-multi-arch-error/snap/snapcraft.yaml create mode 100644 tests/spread/cross-compile/environment-errors/snaps/build-for-multi-arch-triplet-error/snap/snapcraft.yaml create mode 100644 tests/spread/cross-compile/environment-errors/snaps/build-for-part-error/snap/snapcraft.yaml create mode 100644 tests/spread/cross-compile/environment-errors/snaps/build-for-part-triplet-error/snap/snapcraft.yaml create mode 100644 tests/spread/cross-compile/environment-errors/snaps/build-for-unknown-arch-error/snap/snapcraft.yaml create mode 100644 tests/spread/cross-compile/environment-errors/snaps/build-for-unknown-arch-triplet-error/snap/snapcraft.yaml create mode 100644 tests/spread/cross-compile/environment-errors/task.yaml diff --git a/snapcraft_legacy/internal/pluginhandler/_part_environment.py b/snapcraft_legacy/internal/pluginhandler/_part_environment.py index c044470495..90eab40c05 100644 --- a/snapcraft_legacy/internal/pluginhandler/_part_environment.py +++ b/snapcraft_legacy/internal/pluginhandler/_part_environment.py @@ -71,8 +71,10 @@ def get_snapcraft_global_environment( else: content_dirs_envvar = "" - environment = { + return { + "SNAPCRAFT_ARCH_BUILD_FOR": project.arch_build_for, "SNAPCRAFT_ARCH_BUILD_ON": project.arch_build_on, + "SNAPCRAFT_ARCH_TRIPLET_BUILD_FOR": project.arch_triplet_build_for, "SNAPCRAFT_ARCH_TRIPLET_BUILD_ON": project.arch_triplet_build_on, "SNAPCRAFT_ARCH_TRIPLET": project.arch_triplet, "SNAPCRAFT_EXTENSIONS_DIR": common.get_extensionsdir(), @@ -86,12 +88,6 @@ def get_snapcraft_global_environment( "SNAPCRAFT_TARGET_ARCH": project.target_arch, "SNAPCRAFT_CONTENT_DIRS": content_dirs_envvar, } - # build-for arch is not defined for multi-arch builds or for unknown archs - if project.arch_build_for: - environment["SNAPCRAFT_ARCH_BUILD_FOR"] = project.arch_build_for - if project.arch_triplet_build_for: - environment["SNAPCRAFT_ARCH_TRIPLET_BUILD_FOR"] = project.arch_triplet_build_for - return environment def get_snapcraft_part_directory_environment( diff --git a/snapcraft_legacy/internal/project_loader/__init__.py b/snapcraft_legacy/internal/project_loader/__init__.py index f0b42413a0..9c15fe124c 100644 --- a/snapcraft_legacy/internal/project_loader/__init__.py +++ b/snapcraft_legacy/internal/project_loader/__init__.py @@ -1,6 +1,6 @@ # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*- # -# Copyright (C) 2017 Canonical Ltd +# Copyright (C) 2017, 2023 Canonical Ltd # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License version 3 as @@ -14,7 +14,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from typing import TYPE_CHECKING, Dict, List, Union, cast +from typing import TYPE_CHECKING, Dict, List, Optional, Union, cast from ._env import environment_to_replacements, runtime_env # noqa: F401 from ._extensions import ( # noqa: F401 @@ -23,6 +23,7 @@ supported_extension_names, ) from ._parts_config import PartsConfig # noqa: F401 +from .errors import VariableEvaluationError if TYPE_CHECKING: from snapcraft_legacy.project import Project # noqa: F401 @@ -35,10 +36,18 @@ def load_config(project: "Project"): def replace_attr( - attr: Union[List[str], Dict[str, str], str], replacements: Dict[str, str] + attr: Union[List[str], Dict[str, str], str], replacements: Dict[str, Optional[str]] ) -> Union[List[str], Dict[str, str], str]: + """Recurse through a complex data structure and replace values. + + :param attr: The data to modify, which may contain nested lists, dicts, and strings. + :param replacements: A mapping of replacements to make. + + :returns: The data structure with replaced values. + """ if isinstance(attr, str): for replacement, value in replacements.items(): + _validate_replacement(attr, replacement, value) attr = attr.replace(replacement, str(value)) return attr elif isinstance(attr, list) or isinstance(attr, tuple): @@ -53,3 +62,39 @@ def replace_attr( return result return attr + + +def _validate_replacement(attr: str, variable: str, value: Optional[str]) -> None: + """Validate if a replacement can occur for an attribute. + + Some replacement data cannot be used if it is not defined, such as the build-for + arch and build-for arch triplet. If the value of these replacements is None, then + a validation error is raised. + + :param attr: String that may contain data to replace. + :param variable: Project variable to replace. + :param value: New value for replacement. + + :raises Exception: If a replacement cannot occur. + """ + # return early when there is a replacement value (this is the most common case) + if value is not None: + return + + variables_to_validate = [ + "SNAPCRAFT_ARCH_BUILD_FOR", + "SNAPCRAFT_ARCH_TRIPLET_BUILD_FOR", + ] + + # expand to shell syntax for variables (`$item` and `${item}`) + expanded_variables_to_validate = ( + *(f"${item}" for item in variables_to_validate ), + *(f"${{{item}}}" for item in variables_to_validate), + ) + + if variable in attr and variable in expanded_variables_to_validate: + raise VariableEvaluationError( + variable=variable, + reason="the build-for architecture could not be determined", + docs_url="https://snapcraft.io/docs/architectures", + ) diff --git a/snapcraft_legacy/internal/project_loader/errors.py b/snapcraft_legacy/internal/project_loader/errors.py index 87dfa7df4a..09b187ffab 100644 --- a/snapcraft_legacy/internal/project_loader/errors.py +++ b/snapcraft_legacy/internal/project_loader/errors.py @@ -1,6 +1,6 @@ # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*- # -# Copyright (C) 2017-2018 Canonical Ltd +# Copyright (C) 2017-2018, 2023 Canonical Ltd # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License version 3 as @@ -24,6 +24,17 @@ class ProjectLoaderError(snapcraft_legacy.internal.errors.SnapcraftError): fmt = "" +class VariableEvaluationError(ProjectLoaderError): + + fmt = ( + "Cannot evaluate project variable {variable!r}: {reason}\n" + "For more information, check out: {docs_url}" + ) + + def __init__(self, variable: str, reason: str, docs_url: str) -> None: + super().__init__(variable=variable, reason=reason, docs_url=docs_url) + + class InvalidEpochError(ProjectLoaderError): fmt = "epochs are positive integers followed by an optional asterisk" diff --git a/tests/legacy/unit/pluginhandler/test_environment.py b/tests/legacy/unit/pluginhandler/test_environment.py index 284e281399..ff4cfa2554 100644 --- a/tests/legacy/unit/pluginhandler/test_environment.py +++ b/tests/legacy/unit/pluginhandler/test_environment.py @@ -80,7 +80,7 @@ def test_implicit_build_for_arch(tmp_path): def test_no_build_for_unknown_arch(tmp_path): - """build-for envvars should not be defined for unknown build-for architectures.""" + """build-for envvars should be `None` for unknown build-for architectures.""" snapcraft_yaml = SnapcraftYaml( tmp_path, base="core20", @@ -95,12 +95,12 @@ def test_no_build_for_unknown_arch(tmp_path): assert ( environment["SNAPCRAFT_ARCH_TRIPLET_BUILD_ON"] == project.arch_triplet_build_on ) - assert "SNAPCRAFT_ARCH_BUILD_FOR" not in environment - assert "SNAPCRAFT_ARCH_TRIPLET_BUILD_FOR" not in environment + assert environment["SNAPCRAFT_ARCH_BUILD_FOR"] is None + assert environment["SNAPCRAFT_ARCH_TRIPLET_BUILD_FOR"] is None def test_no_build_for_multi_arch(tmp_path): - """build-for envvars should not be defined for multi-arch builds.""" + """build-for envvars should be `None` for multi-arch builds.""" snapcraft_yaml = SnapcraftYaml( tmp_path, base="core20", @@ -116,5 +116,5 @@ def test_no_build_for_multi_arch(tmp_path): assert ( environment["SNAPCRAFT_ARCH_TRIPLET_BUILD_ON"] == project.arch_triplet_build_on ) - assert "SNAPCRAFT_ARCH_BUILD_FOR" not in environment - assert "SNAPCRAFT_ARCH_TRIPLET_BUILD_FOR" not in environment + assert environment["SNAPCRAFT_ARCH_BUILD_FOR"] is None + assert environment["SNAPCRAFT_ARCH_TRIPLET_BUILD_FOR"] is None diff --git a/tests/legacy/unit/project_loader/test_errors.py b/tests/legacy/unit/project_loader/test_errors.py index 4c5bcbb5b4..d86e66ef2d 100644 --- a/tests/legacy/unit/project_loader/test_errors.py +++ b/tests/legacy/unit/project_loader/test_errors.py @@ -1,6 +1,6 @@ # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*- # -# Copyright (C) 2020 Canonical Ltd +# Copyright (C) 2020, 2023 Canonical Ltd # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License version 3 as @@ -27,3 +27,14 @@ def test_SnapcraftProjectUnusedKeyAssetError(): assert error.get_brief() == "Found unused key asset 'foo'." assert error.get_details() == "All configured key assets must be utilized." assert error.get_resolution() == "Verify key usage and remove all unused keys." + + +def test_variable_evaluation_error(): + error = errors.VariableEvaluationError( + variable="TEST_VARIABLE", reason="reason", docs_url="www.example.com" + ) + + assert str(error) == ( + "Cannot evaluate project variable 'TEST_VARIABLE': reason\n" + "For more information, check out: www.example.com" + ) diff --git a/tests/legacy/unit/project_loader/test_replace_attr.py b/tests/legacy/unit/project_loader/test_replace_attr.py index e3af832387..74c0ed1a44 100644 --- a/tests/legacy/unit/project_loader/test_replace_attr.py +++ b/tests/legacy/unit/project_loader/test_replace_attr.py @@ -1,6 +1,6 @@ # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*- # -# Copyright (C) 2015-2018 Canonical Ltd +# Copyright (C) 2015-2018, 2023 Canonical Ltd # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License version 3 as @@ -14,6 +14,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +import pytest from testtools.matchers import Equals from snapcraft_legacy.internal import project_loader @@ -200,3 +201,71 @@ def test_string_replacement_with_complex_data(self): ), Equals(expected), ) + + +def test_validate_replacements(): + """Verify replacements are successfully validated for SNAPCRAFT_ARCH_BUILD_FOR and + SNAPCRAFT_ARCH_TRIPLET_BUILD_FOR.""" + input_attr = { + "stage": [ + "test/file", + "$EMPTY_VAR", + "$SNAPCRAFT_PROJECT_NAME", + "test/SNAPCRAFT_ARCH_BUILD_FOR/file", + "test/$SNAPCRAFT_ARCH_BUILD_FOR/file", + "test/${SNAPCRAFT_ARCH_BUILD_FOR}/file", + "test/SNAPCRAFT_ARCH_TRIPLET_BUILD_FOR/file", + "test/$SNAPCRAFT_ARCH_TRIPLET_BUILD_FOR/file", + "test/${SNAPCRAFT_ARCH_TRIPLET_BUILD_FOR}/file", + ], + } + expected_attr = { + "stage": [ + "test/file", + "None", + "project_name", + "test/SNAPCRAFT_ARCH_BUILD_FOR/file", + "test/arm64/file", + "test/arm64/file", + "test/SNAPCRAFT_ARCH_TRIPLET_BUILD_FOR/file", + "test/aarch64-linux-gnu/file", + "test/aarch64-linux-gnu/file", + ] + } + replacements = project_loader.environment_to_replacements( + { + "SNAPCRAFT_ARCH_BUILD_FOR": "arm64", + "SNAPCRAFT_ARCH_TRIPLET_BUILD_FOR": "aarch64-linux-gnu", + "SNAPCRAFT_PROJECT_NAME": "project_name", + # this variable will evaluate to 'None' because it is not validated + "EMPTY_VAR": None, + } + ) + + actual_attr = project_loader.replace_attr(input_attr, replacements) + + assert actual_attr == expected_attr + + +@pytest.mark.parametrize( + "data", + [ + "test/$SNAPCRAFT_ARCH_BUILD_FOR/file", + "test/${SNAPCRAFT_ARCH_BUILD_FOR}/file", + "test/$SNAPCRAFT_ARCH_TRIPLET_BUILD_FOR/file", + "test/${SNAPCRAFT_ARCH_TRIPLET_BUILD_FOR}/file", + ], +) +def test_validate_replacements_error(data): + """Raise an error when a replacement fails validation for SNAPCRAFT_ARCH_BUILD_FOR + and SNAPCRAFT_ARCH_TRIPLET_BUILD_FOR.""" + input_attr = {"stage": [data]} + replacements = project_loader.environment_to_replacements( + { + "SNAPCRAFT_ARCH_BUILD_FOR": None, + "SNAPCRAFT_ARCH_TRIPLET_BUILD_FOR": None, + } + ) + + with pytest.raises(project_loader.errors.VariableEvaluationError): + project_loader.replace_attr(input_attr, replacements) diff --git a/tests/spread/cross-compile/environment-errors/snaps/build-for-multi-arch-error/snap/snapcraft.yaml b/tests/spread/cross-compile/environment-errors/snaps/build-for-multi-arch-error/snap/snapcraft.yaml new file mode 100644 index 0000000000..6c9a767e88 --- /dev/null +++ b/tests/spread/cross-compile/environment-errors/snaps/build-for-multi-arch-error/snap/snapcraft.yaml @@ -0,0 +1,18 @@ +name: build-for-multi-arch-error +base: core20 +version: '1.0' +summary: test +description: Using SNAPCRAFT_ARCH_BUILD_FOR should raise an error for multi-arch builds. +grade: stable +confinement: strict + +architectures: + - build-on: amd64 + run-on: [amd64, armhf] + +environment: + SNAPCRAFT_ARCH_BUILD_FOR: ${SNAPCRAFT_ARCH_BUILD_FOR} + +parts: + my-part: + plugin: nil diff --git a/tests/spread/cross-compile/environment-errors/snaps/build-for-multi-arch-triplet-error/snap/snapcraft.yaml b/tests/spread/cross-compile/environment-errors/snaps/build-for-multi-arch-triplet-error/snap/snapcraft.yaml new file mode 100644 index 0000000000..ef888a20e6 --- /dev/null +++ b/tests/spread/cross-compile/environment-errors/snaps/build-for-multi-arch-triplet-error/snap/snapcraft.yaml @@ -0,0 +1,18 @@ +name: build-for-multi-arch-triplet-error +base: core20 +version: '1.0' +summary: test +description: Using SNAPCRAFT_ARCH_TRIPLET_BUILD_FOR should raise an error for multi-arch builds. +grade: stable +confinement: strict + +architectures: + - build-on: amd64 + run-on: [amd64, armhf] + +environment: + SNAPCRAFT_ARCH_TRIPLET_BUILD_FOR: ${SNAPCRAFT_ARCH_TRIPLET_BUILD_FOR} + +parts: + my-part: + plugin: nil diff --git a/tests/spread/cross-compile/environment-errors/snaps/build-for-part-error/snap/snapcraft.yaml b/tests/spread/cross-compile/environment-errors/snaps/build-for-part-error/snap/snapcraft.yaml new file mode 100644 index 0000000000..375f19e60e --- /dev/null +++ b/tests/spread/cross-compile/environment-errors/snaps/build-for-part-error/snap/snapcraft.yaml @@ -0,0 +1,17 @@ +name: build-for-part-error +base: core20 +version: '1.0' +summary: test +description: Using SNAPCRAFT_ARCH_BUILD_FOR inside a part definition should raise an error if the arch cannot be determined. +grade: stable +confinement: strict + +architectures: + - build-on: amd64 + run-on: [amd64, armhf] + +parts: + my-part: + plugin: nil + override-pull: + echo ${SNAPCRAFT_ARCH_BUILD_FOR} diff --git a/tests/spread/cross-compile/environment-errors/snaps/build-for-part-triplet-error/snap/snapcraft.yaml b/tests/spread/cross-compile/environment-errors/snaps/build-for-part-triplet-error/snap/snapcraft.yaml new file mode 100644 index 0000000000..1c16416dd6 --- /dev/null +++ b/tests/spread/cross-compile/environment-errors/snaps/build-for-part-triplet-error/snap/snapcraft.yaml @@ -0,0 +1,17 @@ +name: build-for-part-triplet-error +base: core20 +version: '1.0' +summary: test +description: Using SNAPCRAFT_ARCH_TRIPLET_BUILD_FOR inside a part definition should raise an error if the arch cannot be determined. +grade: stable +confinement: strict + +architectures: + - build-on: amd64 + run-on: [amd64, armhf] + +parts: + my-part: + plugin: nil + override-pull: + echo ${SNAPCRAFT_ARCH_TRIPLET_BUILD_FOR} diff --git a/tests/spread/cross-compile/environment-errors/snaps/build-for-unknown-arch-error/snap/snapcraft.yaml b/tests/spread/cross-compile/environment-errors/snaps/build-for-unknown-arch-error/snap/snapcraft.yaml new file mode 100644 index 0000000000..221105ac0b --- /dev/null +++ b/tests/spread/cross-compile/environment-errors/snaps/build-for-unknown-arch-error/snap/snapcraft.yaml @@ -0,0 +1,18 @@ +name: build-for-unknown-arch-error +base: core20 +version: '1.0' +summary: test +description: Using SNAPCRAFT_ARCH_BUILD_FOR should raise an error when the build-for arch is unknown. +grade: stable +confinement: strict + +architectures: + - build-on: amd64 + run-on: badvalue + +environment: + SNAPCRAFT_ARCH_BUILD_FOR: ${SNAPCRAFT_ARCH_BUILD_FOR} + +parts: + my-part: + plugin: nil diff --git a/tests/spread/cross-compile/environment-errors/snaps/build-for-unknown-arch-triplet-error/snap/snapcraft.yaml b/tests/spread/cross-compile/environment-errors/snaps/build-for-unknown-arch-triplet-error/snap/snapcraft.yaml new file mode 100644 index 0000000000..41bbd28359 --- /dev/null +++ b/tests/spread/cross-compile/environment-errors/snaps/build-for-unknown-arch-triplet-error/snap/snapcraft.yaml @@ -0,0 +1,18 @@ +name: build-for-unknown-arch-triplet-error +base: core20 +version: '1.0' +summary: test +description: Using SNAPCRAFT_ARCH_TRIPLET_BUILD_FOR should raise an error when the build-for arch is unknown. +grade: stable +confinement: strict + +architectures: + - build-on: amd64 + run-on: badvalue + +environment: + SNAPCRAFT_ARCH_TRIPLET_BUILD_FOR: ${SNAPCRAFT_ARCH_TRIPLET_BUILD_FOR} + +parts: + my-part: + plugin: nil diff --git a/tests/spread/cross-compile/environment-errors/task.yaml b/tests/spread/cross-compile/environment-errors/task.yaml new file mode 100644 index 0000000000..21ab257d13 --- /dev/null +++ b/tests/spread/cross-compile/environment-errors/task.yaml @@ -0,0 +1,22 @@ +summary: Test failing scenarios for architecture envvars + +environment: + SNAP/build_for_multi_arch_error: build-for-multi-arch-error + SNAP/build_for_multi_arch_triplet_error: build-for-multi-arch-triplet-error + SNAP/build_for_part_error: build-for-part-error + SNAP/build_for_part_triplet_error: build-for-part-triplet-error + SNAP/build_for_unknown_arch_error: build-for-unknown-arch-error + SNAP/build_for_unknown_arch_triplet_error: build-for-unknown-arch-triplet-error + +restore: | + cd "./snaps/$SNAP" + snapcraft clean --destructive-mode + rm -f ./*.snap + +execute: | + cd "./snaps/$SNAP" + + if snapcraft --destructive-mode; then + echo "snapcraft did not fail but should have" + exit 1 + fi diff --git a/tests/spread/cross-compile/environment/snaps/build-for-multi-arch/expected-env.txt b/tests/spread/cross-compile/environment/snaps/build-for-multi-arch/expected-env.txt index cd3d4b9dd2..724473f940 100644 --- a/tests/spread/cross-compile/environment/snaps/build-for-multi-arch/expected-env.txt +++ b/tests/spread/cross-compile/environment/snaps/build-for-multi-arch/expected-env.txt @@ -1,6 +1,4 @@ SNAPCRAFT_ARCH_TRIPLET: x86_64-linux-gnu -SNAPCRAFT_ARCH_BUILD_FOR: ${SNAPCRAFT_ARCH_BUILD_FOR} -SNAPCRAFT_ARCH_TRIPLET_BUILD_FOR: ${SNAPCRAFT_ARCH_TRIPLET_BUILD_FOR} SNAPCRAFT_ARCH_BUILD_ON: amd64 SNAPCRAFT_ARCH_TRIPLET_BUILD_ON: x86_64-linux-gnu SNAPCRAFT_TARGET_ARCH: amd64 diff --git a/tests/spread/cross-compile/environment/snaps/build-for-multi-arch/snap/snapcraft.yaml b/tests/spread/cross-compile/environment/snaps/build-for-multi-arch/snap/snapcraft.yaml index 8388d38e60..f3fe0bfdcf 100644 --- a/tests/spread/cross-compile/environment/snaps/build-for-multi-arch/snap/snapcraft.yaml +++ b/tests/spread/cross-compile/environment/snaps/build-for-multi-arch/snap/snapcraft.yaml @@ -2,7 +2,7 @@ name: build-for-multi-arch base: core20 version: '1.0' summary: test -description: BUILD_ON envvars should not be evaluated for multi-arch builds. +description: Only BUILD_ON envvars can be evaluated for multi-arch builds. grade: stable confinement: strict @@ -12,8 +12,6 @@ architectures: environment: SNAPCRAFT_ARCH_TRIPLET: ${SNAPCRAFT_ARCH_TRIPLET} - SNAPCRAFT_ARCH_BUILD_FOR: ${SNAPCRAFT_ARCH_BUILD_FOR} - SNAPCRAFT_ARCH_TRIPLET_BUILD_FOR: ${SNAPCRAFT_ARCH_TRIPLET_BUILD_FOR} SNAPCRAFT_ARCH_BUILD_ON: ${SNAPCRAFT_ARCH_BUILD_ON} SNAPCRAFT_ARCH_TRIPLET_BUILD_ON: ${SNAPCRAFT_ARCH_TRIPLET_BUILD_ON} SNAPCRAFT_TARGET_ARCH: ${SNAPCRAFT_TARGET_ARCH} @@ -21,3 +19,10 @@ environment: parts: my-part: plugin: nil + override-build: | + cat << EOF >> $SNAPCRAFT_PART_INSTALL/part-variables.txt + SNAPCRAFT_ARCH_TRIPLET: ${SNAPCRAFT_ARCH_TRIPLET} + SNAPCRAFT_ARCH_BUILD_ON: ${SNAPCRAFT_ARCH_BUILD_ON} + SNAPCRAFT_ARCH_TRIPLET_BUILD_ON: ${SNAPCRAFT_ARCH_TRIPLET_BUILD_ON} + SNAPCRAFT_TARGET_ARCH: ${SNAPCRAFT_TARGET_ARCH} + EOF diff --git a/tests/spread/cross-compile/environment/snaps/build-for-single-arch/snap/snapcraft.yaml b/tests/spread/cross-compile/environment/snaps/build-for-single-arch/snap/snapcraft.yaml index 802a247270..66af3c477c 100644 --- a/tests/spread/cross-compile/environment/snaps/build-for-single-arch/snap/snapcraft.yaml +++ b/tests/spread/cross-compile/environment/snaps/build-for-single-arch/snap/snapcraft.yaml @@ -2,7 +2,7 @@ name: build-for-single-arch base: core20 version: '1.0' summary: test -description: BUILD_ON envvars be evaluated when the build-on arch is a scalar. +description: BUILD_ON and BUILD_FOR envvars should be evaluated when the build-for arch is a scalar. grade: stable confinement: strict @@ -21,3 +21,12 @@ environment: parts: my-part: plugin: nil + override-build: | + cat << EOF >> $SNAPCRAFT_PART_INSTALL/part-variables.txt + SNAPCRAFT_ARCH_TRIPLET: ${SNAPCRAFT_ARCH_TRIPLET} + SNAPCRAFT_ARCH_BUILD_FOR: ${SNAPCRAFT_ARCH_BUILD_FOR} + SNAPCRAFT_ARCH_TRIPLET_BUILD_FOR: ${SNAPCRAFT_ARCH_TRIPLET_BUILD_FOR} + SNAPCRAFT_ARCH_BUILD_ON: ${SNAPCRAFT_ARCH_BUILD_ON} + SNAPCRAFT_ARCH_TRIPLET_BUILD_ON: ${SNAPCRAFT_ARCH_TRIPLET_BUILD_ON} + SNAPCRAFT_TARGET_ARCH: ${SNAPCRAFT_TARGET_ARCH} + EOF diff --git a/tests/spread/cross-compile/environment/snaps/build-for-unknown-arch/expected-env.txt b/tests/spread/cross-compile/environment/snaps/build-for-unknown-arch/expected-env.txt index cd3d4b9dd2..724473f940 100644 --- a/tests/spread/cross-compile/environment/snaps/build-for-unknown-arch/expected-env.txt +++ b/tests/spread/cross-compile/environment/snaps/build-for-unknown-arch/expected-env.txt @@ -1,6 +1,4 @@ SNAPCRAFT_ARCH_TRIPLET: x86_64-linux-gnu -SNAPCRAFT_ARCH_BUILD_FOR: ${SNAPCRAFT_ARCH_BUILD_FOR} -SNAPCRAFT_ARCH_TRIPLET_BUILD_FOR: ${SNAPCRAFT_ARCH_TRIPLET_BUILD_FOR} SNAPCRAFT_ARCH_BUILD_ON: amd64 SNAPCRAFT_ARCH_TRIPLET_BUILD_ON: x86_64-linux-gnu SNAPCRAFT_TARGET_ARCH: amd64 diff --git a/tests/spread/cross-compile/environment/snaps/build-for-unknown-arch/snap/snapcraft.yaml b/tests/spread/cross-compile/environment/snaps/build-for-unknown-arch/snap/snapcraft.yaml index 523197597c..5fa92ed01c 100644 --- a/tests/spread/cross-compile/environment/snaps/build-for-unknown-arch/snap/snapcraft.yaml +++ b/tests/spread/cross-compile/environment/snaps/build-for-unknown-arch/snap/snapcraft.yaml @@ -2,7 +2,7 @@ name: build-for-unknown-arch base: core20 version: '1.0' summary: test -description: BUILD_ON envvars should not be evaluated when the build-on arch is unknown. +description: Only BUILD_ON envvars can be evaluated when the build-for arch is unknown. grade: stable confinement: strict @@ -12,8 +12,6 @@ architectures: environment: SNAPCRAFT_ARCH_TRIPLET: ${SNAPCRAFT_ARCH_TRIPLET} - SNAPCRAFT_ARCH_BUILD_FOR: ${SNAPCRAFT_ARCH_BUILD_FOR} - SNAPCRAFT_ARCH_TRIPLET_BUILD_FOR: ${SNAPCRAFT_ARCH_TRIPLET_BUILD_FOR} SNAPCRAFT_ARCH_BUILD_ON: ${SNAPCRAFT_ARCH_BUILD_ON} SNAPCRAFT_ARCH_TRIPLET_BUILD_ON: ${SNAPCRAFT_ARCH_TRIPLET_BUILD_ON} SNAPCRAFT_TARGET_ARCH: ${SNAPCRAFT_TARGET_ARCH} @@ -21,3 +19,10 @@ environment: parts: my-part: plugin: nil + override-build: | + cat << EOF >> $SNAPCRAFT_PART_INSTALL/part-variables.txt + SNAPCRAFT_ARCH_TRIPLET: ${SNAPCRAFT_ARCH_TRIPLET} + SNAPCRAFT_ARCH_BUILD_ON: ${SNAPCRAFT_ARCH_BUILD_ON} + SNAPCRAFT_ARCH_TRIPLET_BUILD_ON: ${SNAPCRAFT_ARCH_TRIPLET_BUILD_ON} + SNAPCRAFT_TARGET_ARCH: ${SNAPCRAFT_TARGET_ARCH} + EOF diff --git a/tests/spread/cross-compile/environment/snaps/target-arch/snap/snapcraft.yaml b/tests/spread/cross-compile/environment/snaps/target-arch/snap/snapcraft.yaml index f894f65731..5eec02078e 100644 --- a/tests/spread/cross-compile/environment/snaps/target-arch/snap/snapcraft.yaml +++ b/tests/spread/cross-compile/environment/snaps/target-arch/snap/snapcraft.yaml @@ -2,7 +2,7 @@ name: target-arch base: core20 version: '1.0' summary: test -description: use target-arch for build-for +description: BUILD_ON and BUILD_FOR envvars can be evaluated when `--target-arch` is provided grade: stable confinement: strict @@ -21,3 +21,12 @@ environment: parts: my-part: plugin: nil + override-build: | + cat << EOF >> $SNAPCRAFT_PART_INSTALL/part-variables.txt + SNAPCRAFT_ARCH_TRIPLET: ${SNAPCRAFT_ARCH_TRIPLET} + SNAPCRAFT_ARCH_BUILD_FOR: ${SNAPCRAFT_ARCH_BUILD_FOR} + SNAPCRAFT_ARCH_TRIPLET_BUILD_FOR: ${SNAPCRAFT_ARCH_TRIPLET_BUILD_FOR} + SNAPCRAFT_ARCH_BUILD_ON: ${SNAPCRAFT_ARCH_BUILD_ON} + SNAPCRAFT_ARCH_TRIPLET_BUILD_ON: ${SNAPCRAFT_ARCH_TRIPLET_BUILD_ON} + SNAPCRAFT_TARGET_ARCH: ${SNAPCRAFT_TARGET_ARCH} + EOF diff --git a/tests/spread/cross-compile/environment/task.yaml b/tests/spread/cross-compile/environment/task.yaml index 5943f506dd..f72ffab073 100644 --- a/tests/spread/cross-compile/environment/task.yaml +++ b/tests/spread/cross-compile/environment/task.yaml @@ -1,14 +1,14 @@ summary: Test envvars related to architectures environment: - SNAP/build_for_single_arch: build-for-single-arch SNAP/build_for_multi_arch: build-for-multi-arch + SNAP/build_for_single_arch: build-for-single-arch SNAP/build_for_unknown_arch: build-for-unknown-arch SNAP/target_arch: target-arch restore: | cd "./snaps/$SNAP" - snapcraft clean + snapcraft clean --destructive-mode rm -f ./*.snap execute: | @@ -19,10 +19,19 @@ execute: | else snapcraft prime --destructive-mode fi - + + # verify variables were evaluated in the environment in the snap.yaml while read -r expected_envvar; do if ! grep -qF "$expected_envvar" prime/meta/snap.yaml; then echo "Did not find '$expected_envvar' in 'prime/meta/snap.yaml'." exit 1 fi done < expected-env.txt + + # verify variables were evaluated inside a part's override script + while read -r expected_envvar; do + if ! grep -qF "$expected_envvar" prime/part-variables.txt; then + echo "Did not find '$expected_envvar' in 'prime/part-variables.txt'." + exit 1 + fi + done < expected-env.txt