Source code for craft_platforms._architectures

# This file is part of craft-platforms.
#
# Copyright 2024 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/>.
"""Architecture related utilities."""

from __future__ import annotations

import enum
import platform
from typing import Literal, Optional, Tuple, Union

from typing_extensions import Self

from craft_platforms import _distro


[docs]class DebianArchitecture(str, enum.Enum): """A Debian architecture.""" AMD64 = "amd64" ARM64 = "arm64" ARMHF = "armhf" I386 = "i386" PPC64EL = "ppc64el" RISCV64 = "riscv64" S390X = "s390x" def __str__(self) -> str: return self.value def __repr__(self) -> str: return f"{self.__class__.__name__}({self.value!r})"
[docs] @classmethod def from_machine(cls, arch: str) -> Self: """Get a DebianArchitecture value from the given platform arch. :param arch: a string containing an architecture as returned by platform.machine() :returns: The DebianArchitecture enum value :raises: ValueError if the architecture is not a valid Debian architecture. """ return cls(_ARCH_TRANSLATIONS_PLATFORM_TO_DEB.get(arch.lower(), arch.lower()))
[docs] @classmethod def from_host(cls) -> Self: """Get the DebianArchitecture of the running host.""" return cls.from_machine(platform.machine())
[docs] def to_platform_arch(self) -> str: """Convert this DebianArchitecture to a platform string. :returns: A string matching what platform.machine() or uname -m would return. """ return _ARCH_TRANSLATIONS_DEB_TO_PLATFORM.get(self.value, self.value)
# architecture translations from the platform syntax to the deb/snap syntax _ARCH_TRANSLATIONS_PLATFORM_TO_DEB = { "aarch64": "arm64", "armv7l": "armhf", "i686": "i386", "ppc": "powerpc", "ppc64le": "ppc64el", "x86_64": "amd64", } # architecture translations from the deb/snap syntax to the platform syntax _ARCH_TRANSLATIONS_DEB_TO_PLATFORM = { deb: platform for platform, deb in _ARCH_TRANSLATIONS_PLATFORM_TO_DEB.items() } def parse_base_and_architecture( arch: str, ) -> Tuple[Optional[_distro.DistroBase], Union[DebianArchitecture, Literal["all"]]]: """Get the debian arch and optional base from an architecture entry. The architecture may have an optional base prefixed as '[<base>:]<arch>'. :param arch: The architecture entry. :returns: A tuple of the DistroBase and the architecture. The architecture is either a DebianArchitecture or 'all'. :raises ValueError: If the architecture or base is invalid. """ if ":" in arch: base_str, _, arch_str = arch.partition(":") base = _distro.DistroBase.from_str(base_str) else: base = None arch_str = arch try: return base, DebianArchitecture(arch_str) if arch_str != "all" else "all" except ValueError: raise ValueError(f"{arch_str!r} is not a valid Debian architecture.") from None