Skip to content
Draft
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
23 changes: 23 additions & 0 deletions platformcraft.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: my-platform-thingy
base: ubuntu@25.10
version: "0"

platforms:
mario:
build-on: [amd64, arm64]
build-for: [arm64]
extensions:
- player-1

luigi:
build-on: [amd64, riscv64]
build-for: [riscv64]
extensions:
- player-2


parts:
thing:
plugin: nil
override-build: |
exit 0
21 changes: 21 additions & 0 deletions platformcraft/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# This file is part of craft_application.
#
# Copyright 2025 Canonical Ltd.
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License version 3, as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
# SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
"""Platformcraft.

Platformcraft is a fake craft-application app that enables partitions.

This package contains things that differ between testcraft and platformcraft.
"""
22 changes: 22 additions & 0 deletions platformcraft/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# This file is part of craft_application.
#
# Copyright 2025 Canonical Ltd.
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License version 3, as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
# SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
"""The main entrypoint to testcraft."""

import sys

from platformcraft import cli

sys.exit(cli.create_app().run())
30 changes: 30 additions & 0 deletions platformcraft/application.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# This file is part of craft_application.
#
# Copyright 2025 Canonical Ltd.
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License version 3, as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
# SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
"""Application implementation for partitioncraft."""

import craft_application

from platformcraft.models.project import FancyProject

PLATFORMCRAFT = craft_application.AppMetadata(
name="platformcraft",
summary="A craft for testing custom platform definitions in craft-application.",
docs_url="https://canonical-craft-application.readthedocs-hosted.com",
source_ignore_patterns=["*.platformcraft"],
project_variables=["version"],
mandatory_adoptable_fields=["version"],
ProjectClass=FancyProject,
)
43 changes: 43 additions & 0 deletions platformcraft/cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# This file is part of craft_application.
#
# Copyright 2025 Canonical Ltd.
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License version 3, as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
# SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
"""Main CLI for platformcraft."""

from typing import Any

import craft_application
import craft_cli

from platformcraft.application import PLATFORMCRAFT
from platformcraft.services import register_services


def create_app() -> craft_application.Application:
"""Create the application.

This is used both for running the app and for generating shell completion.
This function is where the app should be configured before running it.
"""
register_services()
services = craft_application.ServiceFactory(app=PLATFORMCRAFT)

return craft_application.Application(PLATFORMCRAFT, services=services)


def get_completion_data() -> tuple[craft_cli.Dispatcher, dict[str, Any]]:
"""Get the app info for use with craft-cli's completion module."""
app = create_app()

return app._create_dispatcher(), app.app_config # noqa: SLF001
1 change: 1 addition & 0 deletions platformcraft/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Models for platformcraft."""
30 changes: 30 additions & 0 deletions platformcraft/models/platform.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# noqa: A005
# This file is part of craft_application.
#
# Copyright 2025 Canonical Ltd.
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License version 3, as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
# SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
"""Model for a FANCY platform. 🎩🧐."""

from craft_application.models import platforms
from craft_application.models.constraints import UniqueList


class FancyPlatform(platforms.Platform):
"""Model for a FANCY platform. 🎩🧐."""

extensions: UniqueList[str]


class FancyPlatformsDict(platforms.GenericPlatformsDict[FancyPlatform]):
"""Model for a FANCY dictionary of platforms! 🎩🧐."""
26 changes: 26 additions & 0 deletions platformcraft/models/project.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# This file is part of craft_application.
#
# Copyright 2025 Canonical Ltd.
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License version 3, as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
# SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
"""Model for a FANCY project. 🎩🧐."""

from craft_application.models import project

from platformcraft.models.platform import FancyPlatformsDict


class FancyProject(project.Project):
"""Model for a FANCY project. 🎩🧐."""

platforms: FancyPlatformsDict
34 changes: 34 additions & 0 deletions platformcraft/services/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# This file is part of craft_application.
#
# Copyright 2025 Canonical Ltd.
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License version 3, as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
# SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
"""Services for platformcraft."""

import craft_application


def register_services() -> None:
"""Register Partitioncraft's services.

This registers with the ServiceFactory all the services that platformcraft
adds or overrides.
"""
craft_application.ServiceFactory.register(
"package", "PackageService", module="platformcraft.services.package"
)
craft_application.ServiceFactory.register(
"project",
"ProjectService",
module="platformcraft.services.project",
)
56 changes: 56 additions & 0 deletions platformcraft/services/package.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# This file is part of craft_application.
#
# Copyright 2025 Canonical Ltd.
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License version 3, as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
# SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
"""Partitioncraft package service."""

import pathlib
import tarfile
from typing import cast

import craft_application
from craft_application.services import package
from testcraft.models.metadata import Metadata

from platformcraft.models.project import FancyProject


class PackageService(package.PackageService):
"""Package service for partitioncraft."""

@property
def metadata(self) -> Metadata:
"""Get the metadata for this model."""
project = self._services.get("project").get()
if project.version is None:
raise ValueError("Unknown version")
return Metadata(
name=project.name,
version=project.version,
craft_application_version=craft_application.__version__,
)

def pack(self, prime_dir: pathlib.Path, dest: pathlib.Path) -> list[pathlib.Path]:
"""Pack a partitioncraft artifact set."""
project = cast(FancyProject, self._services.get("project").get())
platform = self._services.get("build_plan").plan()[0].platform

extension = ".".join(project.platforms[platform].extensions)

tarball_name = (
f"{project.name}-{project.version}-{platform}.{extension}.platformcraft"
)
with tarfile.open(dest / tarball_name, mode="w:xz") as tar:
tar.add(prime_dir, arcname=".")
return [dest / tarball_name]
48 changes: 48 additions & 0 deletions platformcraft/services/project.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# This file is part of craft_application.
#
# Copyright 2025 Canonical Ltd.
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License version 3, as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
# SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
"""Partitioncraft project service.

Needed so we can set partitions.
"""

import craft_platforms
import pydantic
from craft_application.services import project
from typing_extensions import override

from platformcraft.models.platform import FancyPlatformsDict


class ProjectService(project.ProjectService):
"""Package service for testcraft."""

@override
@classmethod
def _preprocess_platforms(
cls, platforms: dict[str, craft_platforms.PlatformDict]
) -> dict[str, craft_platforms.PlatformDict]:
"""Validate that the given platforms value is valid."""
if platforms:
cls._vectorise_platforms(platforms)
platforms_project_adapter = pydantic.TypeAdapter(
FancyPlatformsDict,
)
return platforms_project_adapter.dump_python( # type: ignore[no-any-return]
platforms_project_adapter.validate_python(platforms),
mode="json",
by_alias=True,
exclude_defaults=True,
)
Loading