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
85 changes: 50 additions & 35 deletions src/RequirementChecker/RequirementsBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,36 @@
use function array_map;
use function array_unique;
use function natsort;
use function strcmp;
use function strnatcmp;
use function uksort;
use function usort;

final class RequirementsBuilder
{
/**
* @var list<Requirement>
*/
private array $predefinedRequirements = [];

/**
* @var array<string, array<string|null>>
*/
private array $requiredExtensions = [];

/**
* @var array<string, array<string|null>>
*/
private array $providedExtensions = [];

/**
* @var array<string, array{string|null, RequirementType}>
*/
private array $allExtensions = [];

/**
* @var array<string, array<string|null>>
*/
private array $conflictingExtensions = [];

public function addRequirement(Requirement $requirement): void
Expand All @@ -37,11 +59,13 @@ public function addRequirement(Requirement $requirement): void
public function addRequiredExtension(Extension $extension, ?string $source): void
{
$this->requiredExtensions[$extension->name][] = $source;
$this->allExtensions[$extension->name][$source] = [$source, RequirementType::EXTENSION];
}

public function addProvidedExtension(Extension $extension, ?string $source): void
{
$this->providedExtensions[$extension->name][] = $source;
$this->allExtensions[$extension->name][$source] = [$source, RequirementType::PROVIDED_EXTENSION];
}

public function addConflictingExtension(Extension $extension, ?string $source): void
Expand All @@ -53,21 +77,17 @@ public function all(): Requirements
{
$requirements = $this->predefinedRequirements;

foreach ($this->getUnfilteredSortedRequiredExtensions() as $extensionName => $sources) {
foreach ($sources as $source) {
$requirements[] = Requirement::forRequiredExtension(
$extensionName,
$source,
);
}
}

foreach ($this->getSortedProvidedExtensions() as $extensionName => $sources) {
foreach ($sources as $source) {
$requirements[] = Requirement::forProvidedExtension(
$extensionName,
$source,
);
foreach ($this->getSortedRequiredAndProvidedExtensions() as $extensionName => $sources) {
foreach ($sources as [$source, $type]) {
$requirements[] = RequirementType::EXTENSION === $type
? Requirement::forRequiredExtension(
$extensionName,
$source,
)
: Requirement::forProvidedExtension(
$extensionName,
$source,
);
}
}

Expand Down Expand Up @@ -109,33 +129,28 @@ public function build(): Requirements
}

/**
* @return array<string, list<string>>
* @return array<string, list<array{string|null, RequirementType}>>
*/
private function getUnfilteredSortedRequiredExtensions(): array
private function getSortedRequiredAndProvidedExtensions(): array
{
return array_map(
self::createSortedDistinctList(...),
self::sortByExtensionName(
$this->requiredExtensions,
),
);
}
static function (array $sources): array {
usort(
$sources,
static fn (array $sourceTypePairA, array $sourceTypePairB) => strcmp(
$sourceTypePairA[0],
(string) $sourceTypePairB[0],
),
);

/**
* @return array<string, list<string>>
*/
private function getSortedProvidedExtensions(): array
{
return array_map(
self::createSortedDistinctList(...),
self::sortByExtensionName(
$this->providedExtensions,
),
return $sources;
},
self::sortByExtensionName($this->allExtensions),
);
}

/**
* @return array<string, list<string>>
* @return array<string, list<string|null>>
*/
private function getSortedRequiredExtensions(): array
{
Expand All @@ -151,7 +166,7 @@ private function getSortedRequiredExtensions(): array
}

/**
* @return array<string, list<string>>
* @return array<string, list<string|null>>
*/
private function getSortedConflictedExtensions(): array
{
Expand Down
9 changes: 7 additions & 2 deletions tests/RequirementChecker/RequirementsBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ public function test_it_can_build_requirements_from_required_extensions(): void
new Extension('http'),
'package2',
);
$this->builder->addRequiredExtension(
new Extension('http'),
null,
);
$this->builder->addRequiredExtension(
new Extension('phar'),
'package1',
Expand All @@ -83,6 +87,7 @@ public function test_it_can_build_requirements_from_required_extensions(): void
);

$expected = new Requirements([
Requirement::forRequiredExtension('http', null),
Requirement::forRequiredExtension('http', 'package1'),
Requirement::forRequiredExtension('http', 'package2'),
Requirement::forRequiredExtension('openssl', 'package3'),
Expand Down Expand Up @@ -179,9 +184,9 @@ public function test_it_removes_extension_requirements_if_they_are_provided(): v
$expectedAllRequirements = new Requirements([
Requirement::forRequiredExtension('http', 'package1'),
Requirement::forRequiredExtension('http', 'package2'),
Requirement::forProvidedExtension('http', 'package3'),
Requirement::forRequiredExtension('openssl', 'package3'),
Requirement::forRequiredExtension('phar', 'package1'),
Requirement::forProvidedExtension('http', 'package3'),
]);

$this->assertBuiltRequirementsEquals($expectedBuiltRequirements);
Expand Down Expand Up @@ -218,9 +223,9 @@ public function test_it_does_not_remove_extension_conflicts_if_they_are_provided
$expectedAllRequirements = new Requirements([
Requirement::forRequiredExtension('http', 'package1'),
Requirement::forRequiredExtension('http', 'package2'),
Requirement::forProvidedExtension('http', 'package3'),
Requirement::forRequiredExtension('openssl', 'package3'),
Requirement::forRequiredExtension('phar', 'package1'),
Requirement::forProvidedExtension('http', 'package3'),
]);

$this->assertBuiltRequirementsEquals($expectedBuiltRequirements);
Expand Down