Skip to content

Commit

Permalink
chore: fix wheel builds
Browse files Browse the repository at this point in the history
This commit introduces a few fixes were uncovered by the previous
commit. Specifically:

- Explicitly test the FFI
- Cleanup the hatch build script and created a new
  `UnsupportedPlatformError` exception.
- Update the wheel inclusions.

Signed-off-by: JP-Ellis <[email protected]>
  • Loading branch information
JP-Ellis committed Oct 30, 2023
1 parent 948eb04 commit 5af4735
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 40 deletions.
5 changes: 3 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ env:
CIBW_TEST_COMMAND: >
python -c
"from pact import EachLike;
assert EachLike(1).generate() == {'json_class': 'Pact::ArrayLike', 'contents': 1, 'min': 1}
"
assert EachLike(1).generate() == {'json_class': 'Pact::ArrayLike', 'contents': 1, 'min': 1};
import pact.v3.ffi;
assert isinstance(pact.v3.ffi.version(), str))"
jobs:
build-x86_64:
Expand Down
75 changes: 46 additions & 29 deletions hatch_build.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,20 @@
PACT_LIB_URL = "https://github.com/pact-foundation/pact-reference/releases/download/libpact_ffi-v{version}/{prefix}pact_ffi-{os}-{machine}.{ext}"


class UnsupportedPlatformError(RuntimeError):
"""Raised when the current platform is not supported."""

def __init__(self, platform: str) -> None:
"""
Initialize the exception.
Args:
platform: The unsupported platform.
"""
self.platform = platform
super().__init__(f"Unsupported platform {platform}")


class PactBuildHook(BuildHookInterface[Any]):
"""Custom hook to download Pact binaries."""

Expand Down Expand Up @@ -66,8 +80,24 @@ def initialize(
build_data["infer_tag"] = True
build_data["pure_python"] = False

self.pact_bin_install(PACT_BIN_VERSION)
self.pact_lib_install(PACT_LIB_VERSION)
binaries_included = False
try:
self.pact_bin_install(PACT_BIN_VERSION)
binaries_included = True
except UnsupportedPlatformError as err:
msg = f"Pact binaries on not available for {err.platform}."
warnings.warn(msg, RuntimeWarning, stacklevel=2)

try:
self.pact_lib_install(PACT_LIB_VERSION)
binaries_included = True
except UnsupportedPlatformError as err:
msg = f"Pact library is not available for {err.platform}"
warnings.warn(msg, RuntimeWarning, stacklevel=2)

if not binaries_included:
msg = "Wheel does not include any binaries. Aborting."
raise UnsupportedPlatformError(msg)

def pact_bin_install(self, version: str) -> None:
"""
Expand All @@ -84,7 +114,7 @@ def pact_bin_install(self, version: str) -> None:
artifact = self._download(url)
self._pact_bin_extract(artifact)

def _pact_bin_url(self, version: str) -> str | None: # noqa: PLR0911
def _pact_bin_url(self, version: str) -> str | None:
"""
Generate the download URL for the Pact binaries.
Expand All @@ -109,9 +139,7 @@ def _pact_bin_url(self, version: str) -> str | None: # noqa: PLR0911
elif platform.endswith("x86_64"):
machine = "x86_64"
else:
msg = f"Unknown macOS machine {platform}"
warnings.warn(msg, RuntimeWarning, stacklevel=2)
return None
raise UnsupportedPlatformError(platform)
return PACT_BIN_URL.format(
version=version,
os=os,
Expand All @@ -127,36 +155,30 @@ def _pact_bin_url(self, version: str) -> str | None: # noqa: PLR0911
elif platform.endswith(("x86", "win32")):
machine = "x86"
else:
msg = f"Unknown Windows machine {platform}"
warnings.warn(msg, RuntimeWarning, stacklevel=2)
return None
raise UnsupportedPlatformError(platform)
return PACT_BIN_URL.format(
version=version,
os=os,
machine=machine,
ext="zip",
)

if "linux" in platform and "musl" not in platform:
if "manylinux" in platform:
os = "linux"
if platform.endswith("x86_64"):
machine = "x86_64"
elif platform.endswith("aarch64"):
machine = "arm64"
else:
msg = f"Unknown Linux machine {platform}"
warnings.warn(msg, RuntimeWarning, stacklevel=2)
return None
raise UnsupportedPlatformError(platform)
return PACT_BIN_URL.format(
version=version,
os=os,
machine=machine,
ext="tar.gz",
)

msg = f"Unknown platform {platform}"
warnings.warn(msg, RuntimeWarning, stacklevel=2)
return None
raise UnsupportedPlatformError(platform)

def _pact_bin_extract(self, artifact: Path) -> None:
"""
Expand Down Expand Up @@ -224,8 +246,7 @@ def _pact_lib_url(self, version: str) -> str: # noqa: C901, PLR0912
elif platform.endswith("x86_64"):
machine = "x86_64"
else:
msg = f"Unknown macOS machine {platform}"
raise ValueError(msg)
raise UnsupportedPlatformError(platform)
return PACT_LIB_URL.format(
prefix="lib",
version=version,
Expand All @@ -240,8 +261,7 @@ def _pact_lib_url(self, version: str) -> str: # noqa: C901, PLR0912
if platform.endswith("amd64"):
machine = "x86_64"
else:
msg = f"Unknown Windows machine {platform}"
raise ValueError(msg)
raise UnsupportedPlatformError(platform)
return PACT_LIB_URL.format(
prefix="",
version=version,
Expand All @@ -250,13 +270,12 @@ def _pact_lib_url(self, version: str) -> str: # noqa: C901, PLR0912
ext="lib.gz",
)

if "linux" in platform and "musl" in platform:
if "musllinux" in platform:
os = "linux"
if platform.endswith("x86_64"):
machine = "x86_64-musl"
else:
msg = f"Unknown MUSL Linux machine {platform}"
raise ValueError(msg)
raise UnsupportedPlatformError(platform)
return PACT_LIB_URL.format(
prefix="lib",
version=version,
Expand All @@ -265,15 +284,14 @@ def _pact_lib_url(self, version: str) -> str: # noqa: C901, PLR0912
ext="a.gz",
)

if "linux" in platform:
if "manylinux" in platform:
os = "linux"
if platform.endswith("x86_64"):
machine = "x86_64"
elif platform.endswith("aarch64"):
machine = "aarch64"
else:
msg = f"Unknown Linux machine {platform}"
raise ValueError(msg)
raise UnsupportedPlatformError(platform)

return PACT_LIB_URL.format(
prefix="lib",
Expand All @@ -283,8 +301,7 @@ def _pact_lib_url(self, version: str) -> str: # noqa: C901, PLR0912
ext="a.gz",
)

msg = f"Unknown platform {platform}"
raise ValueError(msg)
raise UnsupportedPlatformError(platform)

def _pact_lib_extract(self, artifact: Path) -> None:
"""
Expand Down Expand Up @@ -387,7 +404,7 @@ def _pact_lib_cffi(self, includes: list[str]) -> None:
libraries=["pact_ffi", *extra_libs],
library_dirs=[str(self.tmpdir)],
)
output = ffibuilder.compile(verbose=True, tmpdir=str(self.tmpdir))
output = Path(ffibuilder.compile(verbose=True, tmpdir=str(self.tmpdir)))
shutil.copy(output, ROOT_DIR / "pact" / "v3")

def _download(self, url: str) -> Path:
Expand Down
15 changes: 6 additions & 9 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,12 @@ build-backend = "hatchling.build"
path = "pact/__version__.py"

[tool.hatch.build]
include = ["pact/**/*.py", "*.md", "LICENSE"]
include = ["**/py.typed", "**/*.md", "LICENSE", "pact/**/*.py", "pact/**/*.pyi"]

[tool.hatch.build.targets.wheel]
# Ignore the data files in the wheel as their contents are already included
# in the package.
artifacts = ["pact/bin/*", "pact/lib/*"]
artifacts = ["pact/bin/*", "pact/lib/*", "pact/v3/_ffi.*"]

[tool.hatch.build.targets.wheel.hooks.custom]

Expand Down Expand Up @@ -155,9 +155,9 @@ filterwarnings = [
[tool.coverage.report]
exclude_lines = [
"if __name__ == .__main__.:", # Ignore non-runnable code
"if TYPE_CHECKING:", # Ignore typing
"raise NotImplementedError", # Ignore defensive assertions
"@(abc\\.)?abstractmethod", # Ignore abstract methods
"if TYPE_CHECKING:", # Ignore typing
"raise NotImplementedError", # Ignore defensive assertions
"@(abc\\.)?abstractmethod", # Ignore abstract methods
]

################################################################################
Expand All @@ -176,10 +176,7 @@ ignore = [
"ANN102", # `cls` must be typed
]

extend-exclude = [
"tests/*.py",
"pact/*.py",
]
extend-exclude = ["tests/*.py", "pact/*.py"]

[tool.ruff.pyupgrade]
keep-runtime-typing = true
Expand Down

0 comments on commit 5af4735

Please sign in to comment.