From 037a7b89895f4bcbf983706fb4de9b7d90be455a Mon Sep 17 00:00:00 2001 From: Daichi Yamamoto Date: Mon, 4 Nov 2024 12:57:00 +0900 Subject: [PATCH] cargo: refactor GitLab support based on reviews Signed-off-by: Daichi Yamamoto --- pycargoebuild/cargo.py | 63 +++++++++++++++++++++++++++++------------- 1 file changed, 44 insertions(+), 19 deletions(-) diff --git a/pycargoebuild/cargo.py b/pycargoebuild/cargo.py index 9aa8752..a37bf2f 100644 --- a/pycargoebuild/cargo.py +++ b/pycargoebuild/cargo.py @@ -3,6 +3,7 @@ # SPDX-License-Identifier: GPL-2.0-or-later import dataclasses +import enum import functools import sys import tarfile @@ -56,36 +57,62 @@ def crate_entry(self) -> str: return f"{self.name}@{self.version}" +class GitHost(enum.Enum): + GITHUB = enum.auto() + GITLAB = enum.auto() + GITLAB_SELFHOSTED = enum.auto() + + @dataclasses.dataclass(frozen=True) class GitCrate(Crate): repository: str commit: str + def __post_init__(self) -> None: + self.repo_host # check for supported git hosts + @property - def download_url(self) -> str: + def repo_host(self) -> GitHost: if self.repository.startswith("https://github.com/"): - return f"{self.repository}/archive/{self.commit}.tar.gz" + return GitHost.GITHUB + if self.repository.startswith("https://gitlab.com/"): + return GitHost.GITLAB if self.repository.startswith("https://gitlab."): - return (f"{self.repository}/-/archive/{self.commit}/" - f"{self.repo_name}-{self.commit}.tar.gz") - raise RuntimeError(f"Unsupported git crate source: " + return GitHost.GITLAB_SELFHOSTED + raise RuntimeError("Unsupported git crate source: " f"{self.repository}") @property - def filename(self) -> str: - return f"{self.repo_name}-{self.commit}{self.repo_ext}.tar.gz" + def repo_name(self) -> str: + return self.repository.rpartition("/")[2] @property def repo_ext(self) -> str: - if self.repository.startswith("https://github.com/"): - return ".gh" - if self.repository.startswith("https://gitlab.com/"): - return ".gl" - return "" + """Used by cargo.eclass to abbreviate crate URI""" + match self.repo_host: + case GitHost.GITHUB: + return ".gh" + case GitHost.GITLAB: + return ".gl" + case GitHost.GITLAB_SELFHOSTED: + return "" + case _ as host: + typing.assert_never(host) @property - def repo_name(self) -> str: - return self.repository.rpartition("/")[2] + def download_url(self) -> str: + match self.repo_host: + case GitHost.GITHUB: + return f"{self.repository}/archive/{self.commit}.tar.gz" + case GitHost.GITLAB | GitHost.GITLAB_SELFHOSTED: + return (f"{self.repository}/-/archive/{self.commit}/" + f"{self.repo_name}-{self.commit}.tar.gz") + case _ as host: + typing.assert_never(host) + + @property + def filename(self) -> str: + return f"{self.repo_name}-{self.commit}{self.repo_ext}.tar.gz" @functools.cache def get_workspace_toml(self, distdir: Path) -> dict: @@ -136,9 +163,8 @@ def get_git_crate_entry(self, distdir: Path) -> str: subdir = (str(self.get_package_directory(distdir)) .replace(self.commit, "%commit%")) if self.repo_ext: - crate_uri = self.repository - else: - crate_uri = self.download_url.replace(self.commit, "%commit%") + return f"{self.repository};{self.commit};{subdir}" + crate_uri = self.download_url.replace(self.commit, "%commit%") return f"{crate_uri};{self.commit};{subdir}" @functools.cache @@ -208,8 +234,7 @@ def get_crates(f: typing.BinaryIO) -> typing.Generator[Crate, None, None]: yield FileCrate(name=p["name"], version=p["version"], checksum=p["checksum"]) - elif (p["source"].startswith("git+https://github.com/") or - p["source"].startswith("git+https://gitlab.")): + elif (p["source"].startswith("git+")): parsed_url = urllib.parse.urlsplit(p["source"]) if not parsed_url.fragment: raise RuntimeError(