Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 91 additions & 0 deletions src/DependencyResolver/ArrayCollectionIO.php
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
<?php

declare(strict_types=1);

namespace Php\Pie\DependencyResolver;

use Composer\IO\BaseIO;

use function array_merge;
use function is_array;

class ArrayCollectionIO extends BaseIO
{
/** @var string[] */
public array $errors = [];

public function isInteractive(): bool
{
return false;
}

public function isVerbose(): bool
{
return true;
}

public function isVeryVerbose(): bool
{
return true;
}

public function isDebug(): bool
{
return true;
}

public function isDecorated(): bool
{
return false;
}

/** {@inheritDoc} */
public function write($messages, bool $newline = true, int $verbosity = self::NORMAL): void
{
}

/** {@inheritDoc} */
public function writeError($messages, bool $newline = true, int $verbosity = self::NORMAL): void
{
if (is_array($messages)) {
$this->errors = array_merge($this->errors, $messages);

return;
}

$this->errors[] = $messages;
}

/** {@inheritDoc} */
public function overwrite($messages, bool $newline = true, int|null $size = null, int $verbosity = self::NORMAL): void
{
}

/** {@inheritDoc} */
public function overwriteError($messages, bool $newline = true, int|null $size = null, int $verbosity = self::NORMAL): void
{
}

/** {@inheritDoc} */
public function ask(string $question, $default = null): void
{
}

public function askConfirmation(string $question, bool $default = true): void
{
}

/** {@inheritDoc} */
public function askAndValidate(string $question, callable $validator, int|null $attempts = null, $default = null): void
{
}

public function askAndHideAnswer(string $question): void
{
}

/** {@inheritDoc} */
public function select(string $question, array $choices, $default, $attempts = false, string $errorMessage = 'Value "%s" is invalid', bool $multiselect = false): void
{
}
}
6 changes: 4 additions & 2 deletions src/DependencyResolver/ResolveDependencyWithComposer.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -35,14 +35,16 @@ private function factoryRepositorySet(string|null $requestedVersion): Repository

public function __invoke(TargetPlatform $targetPlatform, string $packageName, string|null $requestedVersion): Package
{
$io = new ArrayCollectionIO();

$package = (new VersionSelector(
$this->factoryRepositorySet($requestedVersion),
($this->resolveTargetPhpToPlatformRepository)($targetPlatform->phpBinaryPath),
))
->findBestCandidate($packageName, $requestedVersion);
->findBestCandidate($packageName, $requestedVersion, io: $io);

if (! $package instanceof CompletePackageInterface) {
throw UnableToResolveRequirement::fromRequirement($packageName, $requestedVersion);
throw UnableToResolveRequirement::fromRequirement($packageName, $requestedVersion, $io);
}

/**
Expand Down
16 changes: 13 additions & 3 deletions src/DependencyResolver/UnableToResolveRequirement.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,16 +7,26 @@
use Composer\Package\PackageInterface;
use RuntimeException;

use function array_map;
use function count;
use function implode;
use function sprintf;
use function strip_tags;

class UnableToResolveRequirement extends RuntimeException
{
public static function fromRequirement(string $requiredPackageName, string|null $requiredVersion): self
{
public static function fromRequirement(
string $requiredPackageName,
string|null $requiredVersion,
ArrayCollectionIO $io,
): self {
$errors = $io->errors;

return new self(sprintf(
'Unable to find an installable package %s%s',
'Unable to find an installable package %s%s%s',
$requiredPackageName,
$requiredVersion !== null ? sprintf(' for version %s.', $requiredVersion) : '.',
count($errors) ? "\n\n" . implode("\n\n", array_map(static fn ($e) => strip_tags($e), $errors)) : '',
));
}

Expand Down
17 changes: 13 additions & 4 deletions test/unit/DependencyResolver/UnableToResolveRequirementTest.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,6 +5,7 @@
namespace Php\PieUnitTest\DependencyResolver;

use Composer\Package\PackageInterface;
use Php\Pie\DependencyResolver\ArrayCollectionIO;
use Php\Pie\DependencyResolver\UnableToResolveRequirement;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\TestCase;
Expand DownExpand Up@@ -34,15 +35,23 @@ public function testToPhpOrZendExtensionWithoutVersion(): void

public function testFromRequirementWithVersion(): void
{
$exception = UnableToResolveRequirement::fromRequirement('foo/bar', '^1.2');
$io = new ArrayCollectionIO();
$io->writeError('message1');
$io->writeError(['message2', 'message3']);

self::assertSame('Unable to find an installable package foo/bar for version ^1.2.', $exception->getMessage());
$exception = UnableToResolveRequirement::fromRequirement('foo/bar', '^1.2', $io);

self::assertSame("Unable to find an installable package foo/bar for version ^1.2.\n\nmessage1\n\nmessage2\n\nmessage3", $exception->getMessage());
}

public function testFromRequirementWithoutVersion(): void
{
$exception = UnableToResolveRequirement::fromRequirement('foo/bar', null);
$io = new ArrayCollectionIO();
$io->writeError('message1');
$io->writeError(['message2', 'message3']);

$exception = UnableToResolveRequirement::fromRequirement('foo/bar', null, $io);

self::assertSame('Unable to find an installable package foo/bar.', $exception->getMessage());
self::assertSame("Unable to find an installable package foo/bar.\n\nmessage1\n\nmessage2\n\nmessage3", $exception->getMessage());
}
}