diff --git a/.phive/.gitignore b/.phive/.gitignore new file mode 100644 index 0000000..71d2e19 --- /dev/null +++ b/.phive/.gitignore @@ -0,0 +1,3 @@ +* +!.gitignore +!phars.xml diff --git a/.phive/phars.xml b/.phive/phars.xml new file mode 100644 index 0000000..13cfd4e --- /dev/null +++ b/.phive/phars.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/psalm-baseline.xml b/psalm-baseline.xml new file mode 100644 index 0000000..54e8b20 --- /dev/null +++ b/psalm-baseline.xml @@ -0,0 +1,249 @@ + + + + + + + + + + + getArgument('binary')]]> + getOption('path')]]> + + + + + + + + + pattern]]> + + + + + matchers]]> + + + extensions, $extensions))]]> + + + + + + + + + + + + + + + + + + + + factory]]> + + + + + + + + class()]]> + + + + + + + + self::BSD]]> + + + + + repoConfig->assetPattern]]> + + + + + + + + + + + ($context->onProgress)(]]> + + + + + + + + + + + + + + + + value, + '.' . $stability->getWeight() . '.', + $release->getVersion(), + ), 'v')]]> + + + + + + + + + + + + items, $callback))]]> + items, $filter))]]> + items))]]> + + + + + + + + + + createClient())]]> + + + createClient())]]> + + + + + + config->token]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + client->request('GET', $config)->getContent()]]> + + + + + + + + + + + + assets === null]]> + + + assets === null]]> + + + + + client, $data)]]> + + + + client, $data)]]> + + + + + + + + client]]> + name]]> + releases]]> + + + + + + getName())]]> + + + + + + + + + + + + + + + + + + + + + + uri]]> + + + + + + + + + + + + + + + + diff --git a/src/Module/Archive/ArchiveFactory.php b/src/Module/Archive/ArchiveFactory.php index e53f3d6..d645b2c 100644 --- a/src/Module/Archive/ArchiveFactory.php +++ b/src/Module/Archive/ArchiveFactory.php @@ -14,6 +14,9 @@ */ final class ArchiveFactory { + /** @var list */ + private array $extensions = []; + /** * @var array */ @@ -27,9 +30,13 @@ public function __construct() $this->bootDefaultMatchers(); } - public function extend(\Closure $matcher): void + /** + * @param list $extensions List of supported extensions + */ + public function extend(\Closure $matcher, array $extensions = []): void { \array_unshift($this->matchers, $matcher); + $this->extensions = \array_unique(\array_merge($this->extensions, $extensions)); } public function create(\SplFileInfo $file): Archive @@ -52,22 +59,30 @@ public function create(\SplFileInfo $file): Archive throw new \InvalidArgumentException($error); } + /** + * @return list + */ + public function getSupportedExtensions(): array + { + return $this->extensions; + } + private function bootDefaultMatchers(): void { $this->extend($this->matcher( 'zip', static fn(\SplFileInfo $info): Archive => new ZipPharArchive($info), - )); + ), ['zip']); $this->extend($this->matcher( 'tar.gz', static fn(\SplFileInfo $info): Archive => new TarPharArchive($info), - )); + ), ['tar.gz']); $this->extend($this->matcher( 'phar', static fn(\SplFileInfo $info): Archive => new PharArchive($info), - )); + ), ['phar']); } /** diff --git a/src/Module/Downloader/Downloader.php b/src/Module/Downloader/Downloader.php index 23c3e06..c5e37b4 100644 --- a/src/Module/Downloader/Downloader.php +++ b/src/Module/Downloader/Downloader.php @@ -4,6 +4,7 @@ namespace Internal\DLoad\Module\Downloader; +use Internal\DLoad\Module\Archive\ArchiveFactory; use Internal\DLoad\Module\Common\Architecture; use Internal\DLoad\Module\Common\Config\DownloaderConfig; use Internal\DLoad\Module\Common\Config\Embed\Software; @@ -32,6 +33,7 @@ public function __construct( private readonly Architecture $architecture, private readonly OperatingSystem $operatingSystem, private readonly Stability $stability, + private readonly ArchiveFactory $archiveService, ) {} /** @@ -123,6 +125,7 @@ private function processRelease(DownloadContext $context): \Closure ->whereArchitecture($this->architecture) ->whereOperatingSystem($this->operatingSystem) ->whereNameMatches($context->repoConfig->assetPattern) + ->whereFileExtensions($this->archiveService->getSupportedExtensions()) ->toArray(); $this->logger->debug('%d assets found.', \count($assets)); diff --git a/src/Module/Repository/Internal/AssetsCollection.php b/src/Module/Repository/Collection/AssetsCollection.php similarity index 70% rename from src/Module/Repository/Internal/AssetsCollection.php rename to src/Module/Repository/Collection/AssetsCollection.php index 92c10af..eebaf82 100644 --- a/src/Module/Repository/Internal/AssetsCollection.php +++ b/src/Module/Repository/Collection/AssetsCollection.php @@ -2,16 +2,17 @@ declare(strict_types=1); -namespace Internal\DLoad\Module\Repository\Internal; +namespace Internal\DLoad\Module\Repository\Collection; use Internal\DLoad\Module\Common\Architecture; use Internal\DLoad\Module\Common\OperatingSystem; use Internal\DLoad\Module\Repository\AssetInterface; +use Internal\DLoad\Module\Repository\Internal\Collection; /** * @template-extends Collection * @internal - * @psalm-internal Internal\DLoad\Module\Repository + * @psalm-internal Internal\DLoad\Module */ final class AssetsCollection extends Collection { @@ -37,6 +38,20 @@ public function whereOperatingSystem(OperatingSystem $os): self ); } + /** + * @param list $extensions + */ + public function whereFileExtensions(array $extensions): self + { + return $this->filter( + static fn(AssetInterface $asset): bool => \in_array( + \pathinfo($asset->getName(), \PATHINFO_EXTENSION), + $extensions, + true, + ), + ); + } + /** * Select all the assets with names that match the given pattern. * diff --git a/src/Module/Repository/Internal/ReleasesCollection.php b/src/Module/Repository/Collection/ReleasesCollection.php similarity index 93% rename from src/Module/Repository/Internal/ReleasesCollection.php rename to src/Module/Repository/Collection/ReleasesCollection.php index 2e399c1..c5814a8 100644 --- a/src/Module/Repository/Internal/ReleasesCollection.php +++ b/src/Module/Repository/Collection/ReleasesCollection.php @@ -2,21 +2,21 @@ declare(strict_types=1); -namespace Internal\DLoad\Module\Repository\Internal; +namespace Internal\DLoad\Module\Repository\Collection; use Internal\DLoad\Module\Common\Stability; +use Internal\DLoad\Module\Repository\Internal\Collection; use Internal\DLoad\Module\Repository\ReleaseInterface; /** * @template-extends Collection - * @psalm-import-type StabilityType from Stability * @internal - * @psalm-internal Internal\DLoad\Module\Repository + * @psalm-internal Internal\DLoad\Module */ final class ReleasesCollection extends Collection { /** - * @param string ...$constraints + * @param non-empty-string ...$constraints * @return $this */ public function satisfies(string ...$constraints): self diff --git a/src/Module/Repository/Internal/RepositoriesCollection.php b/src/Module/Repository/Collection/RepositoriesCollection.php similarity index 88% rename from src/Module/Repository/Internal/RepositoriesCollection.php rename to src/Module/Repository/Collection/RepositoriesCollection.php index 602bc40..2bb5c91 100644 --- a/src/Module/Repository/Internal/RepositoriesCollection.php +++ b/src/Module/Repository/Collection/RepositoriesCollection.php @@ -2,13 +2,13 @@ declare(strict_types=1); -namespace Internal\DLoad\Module\Repository\Internal; +namespace Internal\DLoad\Module\Repository\Collection; use Internal\DLoad\Module\Repository\RepositoryInterface; /** * @internal - * @psalm-internal Internal\DLoad\Module\Repository + * @psalm-internal Internal\DLoad\Module */ class RepositoriesCollection implements RepositoryInterface { diff --git a/src/Module/Repository/Internal/GitHub/GitHubRelease.php b/src/Module/Repository/Internal/GitHub/GitHubRelease.php index adbf73c..833b5fa 100644 --- a/src/Module/Repository/Internal/GitHub/GitHubRelease.php +++ b/src/Module/Repository/Internal/GitHub/GitHubRelease.php @@ -5,7 +5,7 @@ namespace Internal\DLoad\Module\Repository\Internal\GitHub; use Composer\Semver\VersionParser; -use Internal\DLoad\Module\Repository\Internal\AssetsCollection; +use Internal\DLoad\Module\Repository\Collection\AssetsCollection; use Internal\DLoad\Module\Repository\Internal\Release; use Internal\DLoad\Service\Destroyable; use Symfony\Contracts\HttpClient\Exception\ExceptionInterface; diff --git a/src/Module/Repository/Internal/GitHub/GitHubRepository.php b/src/Module/Repository/Internal/GitHub/GitHubRepository.php index b66236c..98e296d 100644 --- a/src/Module/Repository/Internal/GitHub/GitHubRepository.php +++ b/src/Module/Repository/Internal/GitHub/GitHubRepository.php @@ -4,7 +4,7 @@ namespace Internal\DLoad\Module\Repository\Internal\GitHub; -use Internal\DLoad\Module\Repository\Internal\ReleasesCollection; +use Internal\DLoad\Module\Repository\Collection\ReleasesCollection; use Internal\DLoad\Module\Repository\RepositoryInterface; use Internal\DLoad\Service\Destroyable; use Symfony\Component\HttpClient\HttpClient; diff --git a/src/Module/Repository/Internal/Release.php b/src/Module/Repository/Internal/Release.php index d4f95ad..854cfa0 100644 --- a/src/Module/Repository/Internal/Release.php +++ b/src/Module/Repository/Internal/Release.php @@ -4,8 +4,10 @@ namespace Internal\DLoad\Module\Repository\Internal; +use Composer\Semver\Semver; use Composer\Semver\VersionParser; use Internal\DLoad\Module\Common\Stability; +use Internal\DLoad\Module\Repository\Collection\AssetsCollection; use Internal\DLoad\Module\Repository\ReleaseInterface; use Internal\DLoad\Module\Repository\RepositoryInterface; @@ -68,6 +70,11 @@ public function getAssets(): AssetsCollection return $this->assets; } + public function satisfies(string $constraint): bool + { + return Semver::satisfies($this->getName(), $constraint); + } + /** * @param non-empty-string $version */ diff --git a/src/Module/Repository/ReleaseInterface.php b/src/Module/Repository/ReleaseInterface.php index 2fc31ca..1c29fe8 100644 --- a/src/Module/Repository/ReleaseInterface.php +++ b/src/Module/Repository/ReleaseInterface.php @@ -5,7 +5,7 @@ namespace Internal\DLoad\Module\Repository; use Internal\DLoad\Module\Common\Stability; -use Internal\DLoad\Module\Repository\Internal\AssetsCollection; +use Internal\DLoad\Module\Repository\Collection\AssetsCollection; interface ReleaseInterface { @@ -30,4 +30,6 @@ public function getVersion(): string; public function getStability(): Stability; public function getAssets(): AssetsCollection; + + public function satisfies(string $constraint): bool; } diff --git a/src/Module/Repository/RepositoryInterface.php b/src/Module/Repository/RepositoryInterface.php index 00ebc2e..7dc0a98 100644 --- a/src/Module/Repository/RepositoryInterface.php +++ b/src/Module/Repository/RepositoryInterface.php @@ -4,7 +4,7 @@ namespace Internal\DLoad\Module\Repository; -use Internal\DLoad\Module\Repository\Internal\ReleasesCollection; +use Internal\DLoad\Module\Repository\Collection\ReleasesCollection; interface RepositoryInterface {