Skip to content

Commit

Permalink
feat(lifecycle): break out _get_build_for method (#414)
Browse files Browse the repository at this point in the history
Fixes #394
  • Loading branch information
lengau authored Aug 13, 2024
1 parent a00bf9b commit 947e1b4
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 10 deletions.
27 changes: 18 additions & 9 deletions craft_application/services/lifecycle.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,23 @@ def setup(self) -> None:
self._lcm = self._init_lifecycle_manager()
callbacks.register_post_step(self.post_prime, step_list=[Step.PRIME])

def _get_build_for(self) -> str:
"""Get the ``build_for`` architecture for craft-parts.
The default behaviour is as follows:
1. If the build plan's ``build_for`` is ``all``, use the host architecture.
2. If it's anything else, use that.
3. If it's undefined, use the host architecture.
"""
# Note: we fallback to the host's architecture here if the build plan
# is empty just to be able to create the LifecycleManager; this will
# correctly fail later on when run() is called (but not necessarily when
# something else like clean() is called).
# We also use the host arch if the build-for is 'all'
if self._build_plan and self._build_plan[0].build_for != "all":
return self._build_plan[0].build_for
return util.get_host_architecture()

def _init_lifecycle_manager(self) -> LifecycleManager:
"""Create and return the Lifecycle manager.
Expand All @@ -160,15 +177,7 @@ def _init_lifecycle_manager(self) -> LifecycleManager:
emit.debug(f"Initialising lifecycle manager in {self._work_dir}")
emit.trace(f"Lifecycle: {repr(self)}")

# Note: we fallback to the host's architecture here if the build plan
# is empty just to be able to create the LifecycleManager; this will
# correctly fail later on when run() is called (but not necessarily when
# something else like clean() is called).
# We also use the host arch if the build-for is 'all'
if self._build_plan and self._build_plan[0].build_for != "all":
build_for = self._build_plan[0].build_for
else:
build_for = util.get_host_architecture()
build_for = self._get_build_for()

if self._project.package_repositories:
self._manager_kwargs["package_repositories"] = (
Expand Down
8 changes: 7 additions & 1 deletion tests/unit/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,13 @@
from unittest import mock

import pytest
from craft_application import services
from craft_application import services, util


@pytest.fixture(params=["amd64", "arm64", "riscv64"])
def fake_host_architecture(monkeypatch, request) -> str:
monkeypatch.setattr(util, "get_host_architecture", lambda: request.param)
return request.param


@pytest.fixture()
Expand Down
66 changes: 66 additions & 0 deletions tests/unit/services/test_lifecycle.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import pytest_check
from craft_application import errors, models, util
from craft_application.errors import InvalidParameterError, PartsLifecycleError
from craft_application.models.project import BuildInfo
from craft_application.services import lifecycle
from craft_application.util import repositories
from craft_parts import (
Expand Down Expand Up @@ -351,6 +352,71 @@ def test_get_primed_stage_packages(lifecycle_service):
assert pkgs == ["pkg1", "pkg2"]


@pytest.mark.parametrize(
("build_plan", "expected"),
[
([], None),
(
[
BuildInfo(
"my-platform",
build_on="any",
build_for="all",
base=bases.BaseName("ubuntu", "24.04"),
)
],
None,
),
(
[
BuildInfo(
"my-platform",
build_on="any",
build_for="amd64",
base=bases.BaseName("ubuntu", "24.04"),
)
],
"amd64",
),
(
[
BuildInfo(
"my-platform",
build_on="any",
build_for="arm64",
base=bases.BaseName("ubuntu", "24.04"),
)
],
"arm64",
),
(
[
BuildInfo(
"my-platform",
build_on="any",
build_for="riscv64",
base=bases.BaseName("ubuntu", "24.04"),
)
],
"riscv64",
),
],
)
def test_get_build_for(
fake_host_architecture,
fake_parts_lifecycle: lifecycle.LifecycleService,
build_plan: list[BuildInfo],
expected: str | None,
):
if expected is None:
expected = fake_host_architecture
fake_parts_lifecycle._build_plan = build_plan

actual = fake_parts_lifecycle._get_build_for()

assert actual == expected


@pytest.mark.parametrize(
"actions",
[
Expand Down

0 comments on commit 947e1b4

Please sign in to comment.