diff --git a/src/Entity/Package.php b/src/Entity/Package.php
index 073071c05..c9c667309 100644
--- a/src/Entity/Package.php
+++ b/src/Entity/Package.php
@@ -274,6 +274,30 @@ public function getVendor(): string
return $this->vendor;
}
+ /**
+ * @return array Vendor and package name
+ */
+ public function isGitHub(): array|false
+ {
+ if (Preg::isMatchStrictGroups('{^(?:git://|git@|https?://)github.com[:/]([^/]+)/(.+?)(?:\.git|/)?$}i', $this->getRepository(), $match)) {
+ return $match;
+ }
+
+ return false;
+ }
+
+ /**
+ * @return array Vendor and package name
+ */
+ public function isGitLab(): array|false
+ {
+ if (Preg::isMatchStrictGroups('{^(?:git://|git@|https?://)gitlab.com[:/]([^/]+)/(.+?)(?:\.git|/)?$}i', $this->getRepository(), $match)) {
+ return $match;
+ }
+
+ return false;
+ }
+
/**
* Get package name without vendor
*/
@@ -334,6 +358,18 @@ public function getGitHubStars(): int|null
return $this->gitHubStars;
}
+ public function getGitHubStarsUrl(): string|null
+ {
+ if ($this->isGitHub()) {
+ return $this->getBrowsableRepository() . '/stargazers';
+ }
+ if ($this->isGitLab()) {
+ return $this->getBrowsableRepository() . '/-/starrers';
+ }
+
+ return null;
+ }
+
public function setGitHubWatches(int|null $val): void
{
$this->gitHubWatches = $val;
@@ -354,6 +390,18 @@ public function getGitHubForks(): int|null
return $this->gitHubForks;
}
+ public function getGitHubForksUrl(): string|null
+ {
+ if ($this->isGitHub()) {
+ return $this->getBrowsableRepository() . '/forks';
+ }
+ if ($this->isGitLab()) {
+ return $this->getBrowsableRepository() . '/-/forks';
+ }
+
+ return null;
+ }
+
public function setGitHubOpenIssues(int|null $val): void
{
$this->gitHubOpenIssues = $val;
@@ -467,7 +515,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 }}