Skip to content

Commit

Permalink
Merge pull request #95 from koterpillar/architectures
Browse files Browse the repository at this point in the history
Architecture support
  • Loading branch information
koterpillar authored Dec 21, 2023
2 parents ccc1898 + 7f6efb1 commit 7848aca
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 18 deletions.
7 changes: 4 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@ jobs:
- os: ubuntu-latest
docker: debian
python-version: "3.11"
- os: ubuntu-latest
docker: ubuntu
python-version: "3.11"
# https://github.com/pypa/pipx/issues/1142
# - os: ubuntu-latest
# docker: ubuntu
# python-version: "3.11"
- os: ubuntu-latest
docker: fedora
python-version: "3.11"
Expand Down
18 changes: 16 additions & 2 deletions mybox/driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ def switch_(self, *, linux: Callable[["Linux"], T], macos: T) -> T:
return macos


Architecture = Literal["x86_64", "arm64"]


@dataclass
class RunResult:
ok: bool
Expand Down Expand Up @@ -220,7 +223,18 @@ async def os(self) -> OS:
elif os_type == "Darwin":
return MacOS()
else:
raise ValueError(f"Unsupported OS type {os_type}.")
raise ValueError(f"Unsupported OS type {os_type}.") # pragma: no cover

@async_cached
async def architecture(self) -> Architecture:
result = await self.with_root(False).run_output("uname", "-m")
if result == "x86_64":
return "x86_64"
elif result == "arm64":
# No ARM runners on CI
return "arm64" # pragma: no cover
else:
raise ValueError(f"Unsupported architecture {result}.") # pragma: no cover


class SubprocessDriver(Driver, metaclass=ABCMeta):
Expand All @@ -239,7 +253,7 @@ async def run_(
if capture_output and show_output:
raise ValueError(
"Cannot use capture_output and show_output at the same time."
)
) # pragma: no cover

command = self.prepare_command(args)

Expand Down
41 changes: 33 additions & 8 deletions mybox/package/github.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import requests

from ..driver import OS
from ..driver import OS, Architecture
from ..filters import Filters, choose
from ..utils import async_cached, async_cached_lock, run_output
from .archive import ArchivePackage
Expand Down Expand Up @@ -52,6 +52,15 @@ class GitHubRelease:
assets: list[GitHubReleaseArtifact]


ARCHITECTURE_FILTERS: dict[str, list[str]] = {
"x86_64": ["amd64", "x64"],
"arm64": ["aarch64", "arm"],
"i386": ["i686", "x86"],
"powerpc64": ["ppc64"],
"s390x": [],
}


class GitHubPackage(ArchivePackage, Filters):
repo: str

Expand All @@ -70,11 +79,14 @@ async def latest_release(self) -> GitHubRelease:
)

@classmethod
def environment_filters(cls, target_os: OS) -> Iterator[Callable[[str], bool]]:
def environment_filters(
cls, *, target_os: OS, target_arch: Architecture
) -> Iterator[Callable[[str], bool]]:
for hint in [".tar.gz"]:
yield cls.includes_(hint)
for signature_hint in [".asc", ".sig", "sha256", "sha512", ".yml"]:
yield cls.excludes_(signature_hint)

for other_os_hint in [".exe", ".dmg"]:
yield cls.excludes_(other_os_hint)
for os_hint in target_os.switch(
Expand All @@ -86,13 +98,19 @@ def environment_filters(cls, target_os: OS) -> Iterator[Callable[[str], bool]]:
macos=[cls.includes_(hint) for hint in ["macos", "darwin", "osx"]],
):
yield os_hint
arch_hints = ["x86_64", "amd64"]
for hint in arch_hints:
yield cls.includes_(hint)

def all_filters(self, target_os: OS) -> Iterator[Callable[[str], bool]]:
for arch, synonyms in ARCHITECTURE_FILTERS.items():
method = cls.includes_ if arch == target_arch else cls.excludes_
for synonym in [arch, *synonyms]:
yield method(synonym)

def all_filters(
self, *, target_os: OS, target_arch: Architecture
) -> Iterator[Callable[[str], bool]]:
yield from self.filters()
yield from self.environment_filters(target_os)
yield from self.environment_filters(
target_os=target_os, target_arch=target_arch
)

async def artifact(self) -> GitHubReleaseArtifact:
candidates = (await self.latest_release()).assets
Expand All @@ -103,7 +121,14 @@ def candidate_filter(
return lambda candidate: name_filter(candidate.name)

target_os = await self.driver.os()
return choose(candidates, map(candidate_filter, self.all_filters(target_os)))
target_arch = await self.driver.architecture()
return choose(
candidates,
map(
candidate_filter,
self.all_filters(target_os=target_os, target_arch=target_arch),
),
)

async def archive_url(self) -> str:
return (await self.artifact()).url
Expand Down
2 changes: 1 addition & 1 deletion tests/package/test_github.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ async def check_installed(self):

async def ignored_paths(self) -> set[Path]:
return await super().ignored_paths() | {
await self.check_driver.home() / ".local" / "state" / "nvim"
await self.check_driver.local() / "state" / "nvim"
}


Expand Down
7 changes: 3 additions & 4 deletions tests/package/test_pip.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,8 @@ async def check_applicable(self) -> None:

async def ignored_paths(self) -> set[Path]:
return await super().ignored_paths() | {
await self.check_driver.home() / ".pipx",
await self.check_driver.home() / ".local" / "pipx" / ".cache",
await self.check_driver.home() / ".local" / "pipx" / "shared",
await self.check_driver.home() / ".local" / "pipx" / "logs",
await self.check_driver.home() / ".shiv",
await self.check_driver.local() / "share" / "pipx" / "shared",
await self.check_driver.local() / "share" / "pipx" / "venvs",
await self.check_driver.local() / "state" / "pipx" / "log",
}

0 comments on commit 7848aca

Please sign in to comment.