Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cargo: add support for GitLab #29

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Changes from 2 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
61 changes: 55 additions & 6 deletions pycargoebuild/cargo.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# SPDX-License-Identifier: GPL-2.0-or-later

import dataclasses
import enum
import functools
import sys
import tarfile
Expand Down Expand Up @@ -56,18 +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
yamader marked this conversation as resolved.
Show resolved Hide resolved
def repo_host(self) -> GitHost:
if self.repository.startswith("https://github.com/"):
return GitHost.GITHUB
if self.repository.startswith("https://gitlab.com/"):
return GitHost.GITLAB
if self.repository.startswith("https://gitlab."):
yamader marked this conversation as resolved.
Show resolved Hide resolved
return GitHost.GITLAB_SELFHOSTED
raise RuntimeError("Unsupported git crate source: "
f"{self.repository}")

@property
def repo_name(self) -> str:
return self.repository.rpartition("/")[2]

@property
def repo_ext(self) -> str:
"""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 download_url(self) -> str:
return f"{self.repository}/archive/{self.commit}.tar.gz"
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.repository.rpartition('/')[2]}-{self.commit}.gh.tar.gz"
return f"{self.repo_name}-{self.commit}{self.repo_ext}.tar.gz"

@functools.cache
def get_workspace_toml(self, distdir: Path) -> dict:
Expand Down Expand Up @@ -117,7 +162,10 @@ def get_package_directory(self, distdir: Path) -> PurePath:
def get_git_crate_entry(self, distdir: Path) -> str:
subdir = (str(self.get_package_directory(distdir))
.replace(self.commit, "%commit%"))
return f"{self.repository};{self.commit};{subdir}"
if self.repo_ext:
yamader marked this conversation as resolved.
Show resolved Hide resolved
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
def get_root_directory(self, distdir: Path) -> typing.Optional[PurePath]:
Expand Down Expand Up @@ -186,7 +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/"):
elif (p["source"].startswith("git+")):
yamader marked this conversation as resolved.
Show resolved Hide resolved
parsed_url = urllib.parse.urlsplit(p["source"])
if not parsed_url.fragment:
raise RuntimeError(
Expand All @@ -196,11 +244,12 @@ def get_crates(f: typing.BinaryIO) -> typing.Generator[Crate, None, None]:
if repo.endswith(".git"):
repo = repo[:-4]
if repo.count("/") != 1:
raise RuntimeError(f"Invalid GitHub URL: {p['source']}")
raise RuntimeError("Invalid GitHub/GitLab URL: "
f"{p['source']}")
yield GitCrate(
name=p["name"],
version=p["version"],
repository=f"https://github.com/{repo}",
repository=f"https://{parsed_url.netloc}/{repo}",
commit=parsed_url.fragment)
else:
raise RuntimeError(f"Unsupported crate source: {p['source']}")
Expand Down
Loading