Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: warn when multiple snaps will be built in the same environment #4839

Merged
merged 5 commits into from
Jun 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 38 additions & 5 deletions snapcraft/parts/lifecycle.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ def run(command_name: str, parsed_args: "argparse.Namespace") -> None:

partitions = _validate_and_get_partitions(yaml_data)

_warn_on_multiple_builds(parsed_args, build_plan)

for build_on, build_for in build_plan:
emit.verbose(f"Running on {build_on} for {build_for}")
yaml_data_for_arch = yaml_utils.apply_yaml(yaml_data, build_on, build_for)
Expand Down Expand Up @@ -141,11 +143,7 @@ def _run_command( # noqa PLR0913 # pylint: disable=too-many-branches, too-many-
permanent=True,
)

if parsed_args.use_lxd or (
not managed_mode
and not parsed_args.destructive_mode
and not os.getenv("SNAPCRAFT_BUILD_ENVIRONMENT") == "host"
):
if _is_manager(parsed_args):
if command_name == "clean" and not part_names:
_clean_provider(project, parsed_args)
else:
Expand Down Expand Up @@ -842,3 +840,38 @@ def _validate_and_get_partitions(yaml_data: Dict[str, Any]) -> Optional[List[str
return project.get_partitions()

return None


def _is_manager(parsed_args: "argparse.Namespace") -> bool:
"""Check if snapcraft is managing build environments.

:param parsed_args: The parsed arguments.

:returns: True if this instance of snapcraft is managing a build environment.
"""
return parsed_args.use_lxd or (
not utils.is_managed_mode()
and not parsed_args.destructive_mode
and not os.getenv("SNAPCRAFT_BUILD_ENVIRONMENT") == "host"
)


def _warn_on_multiple_builds(
parsed_args: "argparse.Namespace", build_plan: List[Tuple[str, str]]
) -> None:
"""Warn if snapcraft will build multiple snaps in the same environment.

:param parsed_args: The parsed arguments.
:param build_plan: The build plan.
"""
# the only acceptable scenario for multiple items in the filtered build plan
# is when snapcraft is managing build environments
if not _is_manager(parsed_args) and len(build_plan) > 1:
emit.message(
"Warning: Snapcraft is building multiple snaps in the same "
"environment which may result in unexpected behavior."
)
emit.message(
"For more information, check out: "
"https://snapcraft.io/docs/explanation-architectures#core22-8"
)
42 changes: 42 additions & 0 deletions tests/unit/parts/test_lifecycle.py
Original file line number Diff line number Diff line change
Expand Up @@ -2311,3 +2311,45 @@ def test_lifecycle_pack_components_with_output(
output_dir=new_dir / "dir",
),
]


@pytest.mark.parametrize(
"cmd", ["pull", "build", "stage", "prime", "pack", "snap", "clean"]
)
def test_lifecycle_warn_on_multiple_builds(
cmd, mocker, snapcraft_yaml, new_dir, emitter
):
"""Warn if multiple snaps will be built in the same environment."""
mocker.patch("snapcraft.parts.lifecycle._is_manager", return_value=False)
mocker.patch(
"snapcraft.parts.lifecycle.get_host_architecture", return_value="arm64"
)
snapcraft_yaml(
base="core22",
architectures=[
{"build-on": "arm64", "build-for": "arm64"},
{"build-on": "arm64", "build-for": "armhf"},
],
)

mocker.patch("snapcraft.parts.lifecycle._run_command")

parts_lifecycle.run(
cmd,
parsed_args=argparse.Namespace(
destructive_mode=False,
use_lxd=False,
provider=None,
ua_token=None,
build_for=None,
),
)

emitter.assert_message(
"Warning: Snapcraft is building multiple snaps in the same "
"environment which may result in unexpected behavior."
)
emitter.assert_message(
"For more information, check out: "
"https://snapcraft.io/docs/explanation-architectures#core22-8"
)
Loading