From 8efb143055012c1e49d85afafd2428f97c45d8d4 Mon Sep 17 00:00:00 2001
From: Roberto Guido
Date: Sat, 23 Dec 2023 23:45:06 +0100
Subject: [PATCH] Improved support for GitLab
---
src/Entity/Package.php | 56 +++++++++++++++++++++++-
src/Package/Updater.php | 33 +++++++++++++-
templates/package/view_package.html.twig | 8 ++--
3 files changed, 91 insertions(+), 6 deletions(-)
diff --git a/src/Entity/Package.php b/src/Entity/Package.php
index 073071c05..59381e494 100644
--- a/src/Entity/Package.php
+++ b/src/Entity/Package.php
@@ -274,6 +274,26 @@ public function getVendor(): string
return $this->vendor;
}
+ public function isGitHub(): array|bool
+ {
+ if (Preg::isMatchStrictGroups('{^(?:git://|git@|https?://)github.com[:/]([^/]+)/(.+?)(?:\.git|/)?$}i', $this->getRepository(), $match)) {
+ return $match;
+ }
+ else {
+ return false;
+ }
+ }
+
+ public function isGitLab(): array|bool
+ {
+ if (Preg::isMatchStrictGroups('{^(?:git://|git@|https?://)gitlab.com[:/]([^/]+)/(.+?)(?:\.git|/)?$}i', $this->getRepository(), $match)) {
+ return $match;
+ }
+ else {
+ return false;
+ }
+ }
+
/**
* Get package name without vendor
*/
@@ -334,6 +354,19 @@ public function getGitHubStars(): int|null
return $this->gitHubStars;
}
+ public function getGitHubStarsUrl(): string|null
+ {
+ if ($this->isGitHub()) {
+ return $this->getBrowsableRepository() . '/stargazers';
+ }
+ else if ($this->isGitLab()) {
+ return $this->getBrowsableRepository() . '/-/starrers';
+ }
+ else {
+ return null;
+ }
+ }
+
public function setGitHubWatches(int|null $val): void
{
$this->gitHubWatches = $val;
@@ -354,6 +387,19 @@ public function getGitHubForks(): int|null
return $this->gitHubForks;
}
+ public function getGitHubForksUrl(): string|null
+ {
+ if ($this->isGitHub()) {
+ return $this->getBrowsableRepository() . '/forks';
+ }
+ else if ($this->isGitLab()) {
+ return $this->getBrowsableRepository() . '/-/forks';
+ }
+ else {
+ return null;
+ }
+ }
+
public function setGitHubOpenIssues(int|null $val): void
{
$this->gitHubOpenIssues = $val;
@@ -467,7 +513,15 @@ public function getBrowsableRepository(): string
return Preg::replace('{^(?:git@|https://|git://)bitbucket.org[:/](.+?)(?:\.git)?$}i', 'https://bitbucket.org/$1', $this->repository);
}
- return Preg::replace('{^(git://github.com/|git@github.com:)}', 'https://github.com/', $this->repository);
+ if (Preg::isMatch('{(://|@)github.com[:/]}i', $this->repository)) {
+ return Preg::replace('{^(git://github.com/|git@github.com:)}', 'https://github.com/', $this->repository);
+ }
+
+ if (Preg::isMatch('{(://|@)gitlab.com[:/]}i', $this->repository)) {
+ return Preg::replace('{^(git://gitlab.com/|git@gitlab.com:)}', 'https://gitlab.com/', $this->repository);
+ }
+
+ return $this->repository;
}
public function addVersion(Version $version): void
diff --git a/src/Package/Updater.php b/src/Package/Updater.php
index 7fa11909e..452442cdd 100644
--- a/src/Package/Updater.php
+++ b/src/Package/Updater.php
@@ -18,6 +18,7 @@
use Composer\Pcre\Preg;
use Composer\Repository\VcsRepository;
use Composer\Repository\Vcs\GitHubDriver;
+use Composer\Repository\Vcs\GitLabDriver;
use Composer\Repository\Vcs\VcsDriverInterface;
use Composer\Repository\InvalidRepositoryException;
use Composer\Util\ErrorHandler;
@@ -241,8 +242,10 @@ public function update(IOInterface $io, Config $config, Package $package, VcsRep
);
}
- if (Preg::isMatchStrictGroups('{^(?:git://|git@|https?://)github.com[:/]([^/]+)/(.+?)(?:\.git|/)?$}i', $package->getRepository(), $match)) {
+ if ($match = $package->isGitHub()) {
$this->updateGitHubInfo($httpDownloader, $package, $match[1], $match[2], $driver);
+ } elseif ($match = $package->isGitLab()) {
+ $this->updateGitLabInfo($httpDownloader, $io, $package, $match[1], $match[2], $driver);
} else {
$this->updateReadme($io, $package, $driver);
}
@@ -604,6 +607,34 @@ private function updateGitHubInfo(HttpDownloader $httpDownloader, Package $packa
}
}
+ private function updateGitLabInfo(HttpDownloader $httpDownloader, IOInterface $io, Package $package, string $owner, string $repo, VcsDriverInterface $driver): void
+ {
+ // GitLab provides a generic URL for the original formatted README,
+ // which requires further elaboration. Here we use the already existing
+ // function to handle it, and back here to populate the other available
+ // metadata
+ $this->updateReadme($io, $package, $driver);
+
+ if (!$driver instanceof GitLabDriver) {
+ return;
+ }
+
+ $repoData = $driver->getRepoData();
+
+ if (isset($repoData['star_count']) && is_numeric($repoData['star_count'])) {
+ $package->setGitHubStars((int) $repoData['star_count']);
+ }
+ if (isset($repoData['forks_count']) && is_numeric($repoData['forks_count'])) {
+ $package->setGitHubForks((int) $repoData['forks_count']);
+ }
+ if (isset($repoData['open_issues_count']) && is_numeric($repoData['open_issues_count'])) {
+ $package->setGitHubOpenIssues((int) $repoData['open_issues_count']);
+ }
+
+ // GitLab does not include a "watch" feature
+ $package->setGitHubWatches(null);
+ }
+
/**
* Prepare the readme by stripping elements and attributes that are not supported .
*/
diff --git a/templates/package/view_package.html.twig b/templates/package/view_package.html.twig
index cff1d035e..ee9eecb9f 100644
--- a/templates/package/view_package.html.twig
+++ b/templates/package/view_package.html.twig
@@ -223,10 +223,10 @@
{{ securityAdvisories|number_format(0, '.', ' ')|raw }}
{% endif %}
- {% if 'github.com' in repoUrl and package.gitHubStars is not null %}
+ {% if package.gitHubStars is not null %}
- Stars:
+ Stars:
{{ package.gitHubStars|number_format(0, '.', ' ')|raw }}
@@ -238,10 +238,10 @@
{{ package.gitHubWatches|number_format(0, '.', ' ')|raw }}
{% endif %}
- {% if 'github.com' in repoUrl and package.gitHubForks is not null %}
+ {% if package.gitHubForks is not null %}
- Forks:
+ Forks:
{{ package.gitHubForks|number_format(0, '.', ' ')|raw }}