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 }}