Skip to content

Commit

Permalink
Filter assets with unsupported archive format; add psalm baseline
Browse files Browse the repository at this point in the history
  • Loading branch information
roxblnfk committed Jul 18, 2024
1 parent 352430b commit 9f560d3
Show file tree
Hide file tree
Showing 13 changed files with 316 additions and 16 deletions.
3 changes: 3 additions & 0 deletions .phive/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*
!.gitignore
!phars.xml
6 changes: 6 additions & 0 deletions .phive/phars.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<phive xmlns="https://phar.io/phive">
<phar name="composer-normalize" version="^2.42.0" installed="2.42.0" location="./.phive/composer-normalize" copy="false"/>
<phar name="composer-require-checker" version="^4.10.0" installed="4.10.0" location="./.phive/composer-require-checker" copy="false"/>
<phar name="box-project/box" version="^4.6.1" installed="4.6.1" location="./.phive/box" copy="false"/>
</phive>
249 changes: 249 additions & 0 deletions psalm-baseline.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,249 @@
<?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="5.25.0@01a8eb06b9e9cc6cfb6a320bf9fb14331919d505">
<file src="src/Command/Get.php">
<MixedArgument>
<code><![CDATA[$binary]]></code>
</MixedArgument>
<MixedAssignment>
<code><![CDATA[$binary]]></code>
</MixedAssignment>
<MixedOperand>
<code><![CDATA[$input->getArgument('binary')]]></code>
<code><![CDATA[$input->getOption('path')]]></code>
</MixedOperand>
<PropertyNotSetInConstructor>
<code><![CDATA[$container]]></code>
<code><![CDATA[$logger]]></code>
</PropertyNotSetInConstructor>
</file>
<file src="src/DLoad.php">
<ArgumentTypeCoercion>
<code><![CDATA[$conf->pattern]]></code>
</ArgumentTypeCoercion>
</file>
<file src="src/Module/Archive/ArchiveFactory.php">
<MixedPropertyTypeCoercion>
<code><![CDATA[$this->matchers]]></code>
</MixedPropertyTypeCoercion>
<PropertyTypeCoercion>
<code><![CDATA[\array_unique(\array_merge($this->extensions, $extensions))]]></code>
</PropertyTypeCoercion>
</file>
<file src="src/Module/Archive/Internal/PharAwareArchive.php">
<MoreSpecificReturnType>
<code><![CDATA[\Generator]]></code>
</MoreSpecificReturnType>
</file>
<file src="src/Module/Common/Config/Embed/Repository.php">
<MissingConstructor>
<code><![CDATA[$uri]]></code>
</MissingConstructor>
</file>
<file src="src/Module/Common/Config/Embed/Software.php">
<MissingConstructor>
<code><![CDATA[$name]]></code>
</MissingConstructor>
</file>
<file src="src/Module/Common/Internal/Container.php">
<MixedPropertyTypeCoercion>
<code><![CDATA[$this->factory]]></code>
</MixedPropertyTypeCoercion>
<UndefinedMethod>
<code><![CDATA[$id::create(...)]]></code>
</UndefinedMethod>
</file>
<file src="src/Module/Common/Internal/Injection/ConfigLoader.php">
<MixedMethodCall>
<code><![CDATA[new $attribute->class()]]></code>
</MixedMethodCall>
<RedundantCondition>
<code><![CDATA[\assert($xml instanceof \SimpleXMLElement)]]></code>
</RedundantCondition>
</file>
<file src="src/Module/Common/OperatingSystem.php">
<DocblockTypeContradiction>
<code><![CDATA['bSD' => self::BSD]]></code>
</DocblockTypeContradiction>
</file>
<file src="src/Module/Downloader/Downloader.php">
<ArgumentTypeCoercion>
<code><![CDATA[$context->repoConfig->assetPattern]]></code>
</ArgumentTypeCoercion>
<InternalMethod>
<code><![CDATA[toArray]]></code>
<code><![CDATA[toArray]]></code>
</InternalMethod>
<InvalidNullableReturnType>
<code><![CDATA[AssetInterface]]></code>
<code><![CDATA[ReleaseInterface]]></code>
</InvalidNullableReturnType>
<MissingClosureReturnType>
<code><![CDATA[static fn(int $dlNow, int $dlSize, array $info) => ($context->onProgress)(]]></code>
</MissingClosureReturnType>
<TooManyArguments>
<code><![CDATA[download]]></code>
</TooManyArguments>
</file>
<file src="src/Module/Downloader/Internal/DownloadContext.php">
<PropertyNotSetInConstructor>
<code><![CDATA[$asset]]></code>
<code><![CDATA[$file]]></code>
<code><![CDATA[$release]]></code>
<code><![CDATA[$repoConfig]]></code>
</PropertyNotSetInConstructor>
</file>
<file src="src/Module/Repository/Collection/ReleasesCollection.php">
<LessSpecificReturnStatement>
<code><![CDATA[\ltrim(\str_replace(
'-' . $stability->value,
'.' . $stability->getWeight() . '.',
$release->getVersion(),
), 'v')]]></code>
</LessSpecificReturnStatement>
<MoreSpecificReturnType>
<code><![CDATA[non-empty-string]]></code>
</MoreSpecificReturnType>
</file>
<file src="src/Module/Repository/Internal/Collection.php">
<MixedArgument>
<code><![CDATA[$generator()]]></code>
</MixedArgument>
<UnsafeGenericInstantiation>
<code><![CDATA[new static($items)]]></code>
<code><![CDATA[new static(\array_filter($this->items, $callback))]]></code>
<code><![CDATA[new static(\array_filter($this->items, $filter))]]></code>
<code><![CDATA[new static(\array_map($map, $this->items))]]></code>
<code><![CDATA[new static(\iterator_to_array($items))]]></code>
</UnsafeGenericInstantiation>
</file>
<file src="src/Module/Repository/Internal/GitHub/Factory.php">
<ArgumentTypeCoercion>
<code><![CDATA[$org]]></code>
<code><![CDATA[$repo]]></code>
</ArgumentTypeCoercion>
<InternalClass>
<code><![CDATA[new GitHubRepository($org, $repo, $this->createClient())]]></code>
</InternalClass>
<InternalMethod>
<code><![CDATA[new GitHubRepository($org, $repo, $this->createClient())]]></code>
</InternalMethod>
<PossiblyUndefinedArrayOffset>
<code><![CDATA[$org]]></code>
</PossiblyUndefinedArrayOffset>
<RiskyTruthyFalsyComparison>
<code><![CDATA[$this->config->token]]></code>
</RiskyTruthyFalsyComparison>
</file>
<file src="src/Module/Repository/Internal/GitHub/GitHubAsset.php">
<InternalClass>
<code><![CDATA[new self($client, $release, $data['name'], $data['browser_download_url'])]]></code>
</InternalClass>
<InternalMethod>
<code><![CDATA[new self($client, $release, $data['name'], $data['browser_download_url'])]]></code>
</InternalMethod>
<LessSpecificImplementedReturnType>
<code><![CDATA[\Traversable]]></code>
</LessSpecificImplementedReturnType>
</file>
<file src="src/Module/Repository/Internal/GitHub/GitHubRelease.php">
<ArgumentTypeCoercion>
<code><![CDATA[$name]]></code>
</ArgumentTypeCoercion>
<InternalClass>
<code><![CDATA[GitHubAsset::fromApiResponse($client, $result, $item)]]></code>
<code><![CDATA[new self($client, $repository, $name, $version)]]></code>
<code><![CDATA[self::getTagName($data)]]></code>
</InternalClass>
<InternalMethod>
<code><![CDATA[GitHubAsset::fromApiResponse($client, $result, $item)]]></code>
<code><![CDATA[new self($client, $repository, $name, $version)]]></code>
<code><![CDATA[self::getTagName($data)]]></code>
</InternalMethod>
<InvalidArgument>
<code><![CDATA[$data]]></code>
</InvalidArgument>
<InvalidArrayOffset>
<code><![CDATA[$data['tag_name']]]></code>
</InvalidArrayOffset>
<LessSpecificReturnStatement>
<code><![CDATA[$this->client->request('GET', $config)->getContent()]]></code>
</LessSpecificReturnStatement>
<MixedArgument>
<code><![CDATA[$version]]></code>
</MixedArgument>
<MixedAssignment>
<code><![CDATA[$version]]></code>
</MixedAssignment>
<MoreSpecificReturnType>
<code><![CDATA[non-empty-string]]></code>
</MoreSpecificReturnType>
<RedundantCondition>
<code><![CDATA[$this->assets === null]]></code>
</RedundantCondition>
<TypeDoesNotContainNull>
<code><![CDATA[$this->assets === null]]></code>
</TypeDoesNotContainNull>
</file>
<file src="src/Module/Repository/Internal/GitHub/GitHubRepository.php">
<InternalClass>
<code><![CDATA[GitHubRelease::fromApiResponse($this, $this->client, $data)]]></code>
<code><![CDATA[self::URL_RELEASES]]></code>
</InternalClass>
<InternalMethod>
<code><![CDATA[GitHubRelease::fromApiResponse($this, $this->client, $data)]]></code>
<code><![CDATA[getName]]></code>
<code><![CDATA[hasNextPage]]></code>
<code><![CDATA[releasesRequest]]></code>
<code><![CDATA[request]]></code>
<code><![CDATA[uri]]></code>
</InternalMethod>
<InternalProperty>
<code><![CDATA[$this->client]]></code>
<code><![CDATA[$this->name]]></code>
<code><![CDATA[$this->releases]]></code>
</InternalProperty>
<LessSpecificImplementedReturnType>
<code><![CDATA[string]]></code>
</LessSpecificImplementedReturnType>
<LessSpecificReturnStatement>
<code><![CDATA[\sprintf($pattern, $this->getName())]]></code>
</LessSpecificReturnStatement>
<MoreSpecificReturnType>
<code><![CDATA[non-empty-string]]></code>
</MoreSpecificReturnType>
</file>
<file src="src/Module/Repository/Internal/Release.php">
<InvalidNullableReturnType>
<code><![CDATA[Stability]]></code>
</InvalidNullableReturnType>
<LessSpecificReturnStatement>
<code><![CDATA[isset($parts[1])
? $number . '-' . $parts[1]
: $number]]></code>
</LessSpecificReturnStatement>
<MoreSpecificReturnType>
<code><![CDATA[non-empty-string]]></code>
</MoreSpecificReturnType>
<NullableReturnStatement>
<code><![CDATA[Stability::tryFrom(VersionParser::parseStability($version))]]></code>
</NullableReturnStatement>
</file>
<file src="src/Module/Repository/RepositoryProvider.php">
<ArgumentTypeCoercion>
<code><![CDATA[$config->uri]]></code>
</ArgumentTypeCoercion>
</file>
<file src="src/Service/Factoriable.php">
<InvalidDocblock>
<code><![CDATA[Factoriable]]></code>
</InvalidDocblock>
</file>
<file src="src/Service/Logger.php">
<ArgumentTypeCoercion>
<code><![CDATA[$values]]></code>
<code><![CDATA[$values]]></code>
<code><![CDATA[$values]]></code>
<code><![CDATA[$values]]></code>
</ArgumentTypeCoercion>
</file>
</files>
23 changes: 19 additions & 4 deletions src/Module/Archive/ArchiveFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
*/
final class ArchiveFactory
{
/** @var list<non-empty-string> */
private array $extensions = [];

/**
* @var array<ArchiveMatcher>
*/
Expand All @@ -27,9 +30,13 @@ public function __construct()
$this->bootDefaultMatchers();
}

public function extend(\Closure $matcher): void
/**
* @param list<non-empty-string> $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
Expand All @@ -52,22 +59,30 @@ public function create(\SplFileInfo $file): Archive
throw new \InvalidArgumentException($error);
}

/**
* @return list<non-empty-string>
*/
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']);
}

/**
Expand Down
3 changes: 3 additions & 0 deletions src/Module/Downloader/Downloader.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -32,6 +33,7 @@ public function __construct(
private readonly Architecture $architecture,
private readonly OperatingSystem $operatingSystem,
private readonly Stability $stability,
private readonly ArchiveFactory $archiveService,
) {}

/**
Expand Down Expand Up @@ -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));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<AssetInterface>
* @internal
* @psalm-internal Internal\DLoad\Module\Repository
* @psalm-internal Internal\DLoad\Module
*/
final class AssetsCollection extends Collection
{
Expand All @@ -37,6 +38,20 @@ public function whereOperatingSystem(OperatingSystem $os): self
);
}

/**
* @param list<non-empty-string> $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.
*
Expand Down
Loading

0 comments on commit 9f560d3

Please sign in to comment.