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: use craft-platforms for build plans #5111

Merged
merged 24 commits into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
89985dc
build(deps): update craft-platforms version to latest
mattculler Oct 11, 2024
65cde65
feat(model): naive build planner logic replacement
mattculler Oct 16, 2024
da4ed5f
feat(models): convert c-plat buildinfo to c-prov buildinfo
mattculler Oct 16, 2024
891017a
chore: autoformat
mattculler Oct 16, 2024
244b6bd
fix: types
mattculler Oct 16, 2024
ae935e1
fix: name qualification
mattculler Oct 16, 2024
9feaba5
chore: format
mattculler Oct 16, 2024
e1e7e1a
fix: account for platforms none; undo accidental makefile changes
mattculler Oct 16, 2024
bb49656
fix: invert logic to try to make type checker happy
mattculler Oct 16, 2024
4dd7921
fix: 1/2 type checker issues
mattculler Oct 16, 2024
a332df3
fix: add extra checking to appease type checkers
mattculler Oct 16, 2024
61de255
fix: use in-progress fixed c-plat
mattculler Oct 16, 2024
0d692d7
chore: local unit tests aren't working, add -v to see diffs
mattculler Oct 16, 2024
f9e12b0
chore: need the full diff
mattculler Oct 16, 2024
5903572
feat: bring back some of the original build planner logic
mattculler Oct 17, 2024
d10e0e6
fix: re-use type/base validation logic
mattculler Oct 17, 2024
675fb4c
fix: undo accidental commit of dependencies at local path
mattculler Oct 17, 2024
4221160
fix(tests): remove now-failing test - it shouldn't have ever passed
mattculler Oct 17, 2024
0099bcf
fix: properly convert beteween the two BuildInfo types
mattculler Oct 17, 2024
82335b5
fix: silence type checkers
mattculler Oct 17, 2024
94d68b9
chore: autoformat
mattculler Oct 17, 2024
1072c68
chore(docs): fix commmmmmment
mattculler Oct 17, 2024
b66fca4
feat: switch to fixed c-plat
mattculler Oct 18, 2024
a36792f
Apply suggestions from code review
mattculler Oct 18, 2024
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
2 changes: 1 addition & 1 deletion requirements-devel.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ craft-archives==2.0.0
craft-cli==2.7.0
craft-grammar==2.0.1
craft-parts==2.1.2
craft-platforms==0.1.1
craft-platforms==0.4.0
craft-providers==2.0.4
craft-store==3.0.2
cryptography==43.0.1
Expand Down
2 changes: 1 addition & 1 deletion requirements-docs.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ craft-archives==2.0.0
craft-cli==2.7.0
craft-grammar==2.0.1
craft-parts==2.1.2
craft-platforms==0.1.1
craft-platforms==0.4.0
craft-providers==2.0.4
craft-store==3.0.2
cryptography==43.0.1
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ craft-archives==2.0.0
craft-cli==2.7.0
craft-grammar==2.0.1
craft-parts==2.1.2
craft-platforms==0.1.1
craft-platforms==0.4.0
craft-providers==2.0.4
craft-store==3.0.2
cryptography==43.0.1
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ def recursive_data_files(directory, install_directory):
"craft-cli~=2.6",
"craft-grammar>=2.0.1,<3.0.0",
"craft-parts>=2.1.2,<3.0.0",
"craft-platforms~=0.1",
"craft-platforms~=0.4",
"craft-providers>=2.0.4,<3.0.0",
"craft-store>=3.0.2,<4.0.0",
"docutils<0.20", # Frozen until we can update sphinx dependencies.
Expand Down
59 changes: 38 additions & 21 deletions snapcraft/models/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
)
from craft_cli import emit
from craft_grammar.models import Grammar # type: ignore[import-untyped]
from craft_platforms import Platforms, snap
from craft_providers import bases
from pydantic import ConfigDict, PrivateAttr, StringConstraints
from typing_extensions import Annotated, Self, override
Expand Down Expand Up @@ -277,6 +278,14 @@ def _get_partitions_from_components(
return None


def _validate_mandatory_base(base: str | None, snap_type: str | None) -> None:
"""Validate that the base is specified, if required by the snap_type."""
if (base is not None) ^ (snap_type not in ["base", "kernel", "snapd"]):
raise ValueError(
"Snap base must be declared when type is not base, kernel or snapd"
)


class Socket(models.CraftBaseModel):
"""Snapcraft app socket definition."""

Expand Down Expand Up @@ -714,12 +723,7 @@ def _validate_adoptable_fields(self) -> Self:

@pydantic.model_validator(mode="after")
def _validate_mandatory_base(self):
snap_type = self.type
base = self.base
if (base is not None) ^ (snap_type not in ["base", "kernel", "snapd"]):
raise ValueError(
"Snap base must be declared when type is not base, kernel or snapd"
)
_validate_mandatory_base(self.base, self.type)
return self

@pydantic.field_validator("name")
Expand Down Expand Up @@ -1138,6 +1142,7 @@ class SnapcraftBuildPlanner(models.BuildPlanner):
base: str | None = None
build_base: str | None = None
name: str
type: Literal["app", "base", "gadget", "kernel", "snapd"] | None = None
platforms: dict[str, Platform] | None = None # type: ignore[assignment]
architectures: list[str | Architecture] | None = None
project_type: str | None = pydantic.Field(default=None, alias="type")
Expand Down Expand Up @@ -1192,7 +1197,6 @@ def _validate_all_platforms(

def get_build_plan(self) -> list[BuildInfo]:
"""Get the build plan for this project."""
build_infos: list[BuildInfo] = []
effective_base = SNAPCRAFT_BASE_TO_PROVIDER_BASE[
str(
get_effective_base(
Expand All @@ -1205,8 +1209,6 @@ def get_build_plan(self) -> list[BuildInfo]:
)
].value

base = bases.BaseName("ubuntu", effective_base)

# set default value
if self.platforms is None:
self.platforms = {
Expand All @@ -1221,16 +1223,31 @@ def get_build_plan(self) -> list[BuildInfo]:
Platform.from_architectures(self.architectures)
)

for platform_entry, platform in self.platforms.items():
for build_for in platform.build_for or [SnapArch(platform_entry).value]:
for build_on in platform.build_on or [SnapArch(platform_entry).value]:
build_infos.append(
BuildInfo(
platform=platform_entry,
build_on=build_on,
build_for=build_for,
base=base,
)
)
platforms = cast(
Platforms,
{name: platform.marshal() for name, platform in self.platforms.items()},
)

return build_infos
# In _validate_mandatory_base, we ensure that the possible values of
# 'base' and 'snap_type' are narrowed so they'll always match one of
# the two overloads of get_platforms_snap_build_plan. But, pyright and
# mypy aren't smart enough to realize this, so we need the type checker
# ignores.
_validate_mandatory_base(self.base, self.type)
return [
BuildInfo(
platform=buildinfo.platform,
build_on=str(buildinfo.build_on),
build_for=str(buildinfo.build_for),
base=bases.BaseName(
name=buildinfo.build_base.distribution,
version=buildinfo.build_base.series,
),
)
for buildinfo in snap.get_platforms_snap_build_plan( # pyright: ignore[reportCallIssue]
base=self.base, # type: ignore[arg-type]
build_base=self.build_base,
snap_type=self.type, # type: ignore[arg-type]
platforms=platforms,
)
]
34 changes: 0 additions & 34 deletions tests/unit/models/test_projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -2486,40 +2486,6 @@ def test_platform_default():
]


def test_build_planner_get_build_plan_base(mocker):
"""Test `get_build_plan()` uses the correct base."""
mock_get_effective_base = mocker.patch(
"snapcraft.models.project.get_effective_base", return_value="core24"
)
planner = snapcraft.models.project.SnapcraftBuildPlanner.model_validate(
{
"name": "test-snap",
"base": "test-base",
"build-base": "test-build-base",
"platforms": {"amd64": None},
"project_type": "test-type",
}
)

actual_build_infos = planner.get_build_plan()

assert actual_build_infos == [
BuildInfo(
platform="amd64",
build_on="amd64",
build_for="amd64",
base=BaseName(name="ubuntu", version="24.04"),
)
]
mock_get_effective_base.assert_called_once_with(
base="test-base",
build_base="test-build-base",
project_type="test-type",
name="test-snap",
translate_devel=False,
)


def test_project_platform_error_has_context():
"""Platform validation errors include which platform entry is invalid."""
error = r"build-on\n Field required"
Expand Down
Loading