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
30 changes: 29 additions & 1 deletion src/RequirementChecker/AppRequirementsFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,47 @@ final class AppRequirementsFactory
{
private const SELF_PACKAGE = null;

public function createUnfiltered(
ComposerJson $composerJson,
ComposerLock $composerLock,
CompressionAlgorithm $compressionAlgorithm,
): Requirements {
return $this
->createBuilder(
$composerJson,
$composerLock,
$compressionAlgorithm,
)
->all();
}

public function create(
ComposerJson $composerJson,
ComposerLock $composerLock,
CompressionAlgorithm $compressionAlgorithm,
): Requirements {
return $this
->createBuilder(
$composerJson,
$composerLock,
$compressionAlgorithm,
)
->build();
}

private function createBuilder(
ComposerJson $composerJson,
ComposerLock $composerLock,
CompressionAlgorithm $compressionAlgorithm,
): RequirementsBuilder {
$requirementsBuilder = new RequirementsBuilder();

self::retrievePhpVersionRequirements($requirementsBuilder, $composerJson, $composerLock);
self::collectExtensionRequirementsFromCompressionAlgorithm($requirementsBuilder, $compressionAlgorithm);
self::collectComposerLockExtensionRequirements($composerLock, $requirementsBuilder);
self::collectComposerJsonExtensionRequirements($composerJson, $requirementsBuilder);

return $requirementsBuilder->build();
return $requirementsBuilder;
}

private static function retrievePhpVersionRequirements(
Expand Down
29 changes: 29 additions & 0 deletions src/RequirementChecker/Requirement.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,35 @@ public static function forRequiredExtension(string $extension, ?string $packageN
);
}

public static function forProvidedExtension(string $extension, ?string $packageName): self
{
return new self(
RequirementType::PROVIDED_EXTENSION,
$extension,
$packageName,
null === $packageName
? sprintf(
'This application provides the extension "%s".',
$extension,
)
: sprintf(
'The package "%s" provides the extension "%s".',
$packageName,
$extension,
),
null === $packageName
? sprintf(
'This application does not require the extension "%s", it is provided by the application itself.',
$extension,
)
: sprintf(
'This application does not require the extension "%s", it is provided by the package "%s".',
$packageName,
$extension,
),
);
}

public static function forConflictingExtension(string $extension, ?string $packageName): self
{
return new self(
Expand Down
1 change: 1 addition & 0 deletions src/RequirementChecker/RequirementType.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@ enum RequirementType: string
{
case PHP = 'php';
case EXTENSION = 'extension';
case PROVIDED_EXTENSION = 'provided-extension';
case EXTENSION_CONFLICT = 'extension-conflict';
}
60 changes: 60 additions & 0 deletions src/RequirementChecker/RequirementsBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,40 @@ public function addConflictingExtension(Extension $extension, ?string $source):
$this->conflictingExtensions[$extension->name][] = $source;
}

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->getSortedConflictedExtensions() as $extensionName => $sources) {
foreach ($sources as $source) {
$requirements[] = Requirement::forConflictingExtension(
$extensionName,
$source,
);
}
}

return new Requirements($requirements);
}

public function build(): Requirements
{
$requirements = $this->predefinedRequirements;
Expand All @@ -74,6 +108,32 @@ public function build(): Requirements
return new Requirements($requirements);
}

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

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

/**
* @return array<string, list<string>>
*/
Expand Down
36 changes: 36 additions & 0 deletions tests/RequirementChecker/RequirementTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,42 @@ public function test_it_can_be_created_for_an_extension_constraint_for_a_package
self::assertItCanBeCreatedFromItsArrayForm($requirement, $actual);
}

public function test_it_can_be_created_for_a_provided_extension_constraint(): void
{
$requirement = Requirement::forProvidedExtension('mbstring', null);

$expected = [
'type' => 'provided-extension',
'condition' => 'mbstring',
'source' => null,
'message' => 'This application provides the extension "mbstring".',
'helpMessage' => 'This application does not require the extension "mbstring", it is provided by the application itself.',
];

$actual = $requirement->toArray();

self::assertSame($expected, $actual);
self::assertItCanBeCreatedFromItsArrayForm($requirement, $actual);
}

public function test_it_can_be_created_for_a_provided_extension_constraint_for_a_package(): void
{
$requirement = Requirement::forProvidedExtension('mbstring', 'box/test');

$expected = [
'type' => 'provided-extension',
'condition' => 'mbstring',
'source' => 'box/test',
'message' => 'The package "box/test" provides the extension "mbstring".',
'helpMessage' => 'This application does not require the extension "box/test", it is provided by the package "mbstring".',
];

$actual = $requirement->toArray();

self::assertSame($expected, $actual);
self::assertItCanBeCreatedFromItsArrayForm($requirement, $actual);
}

public function test_it_can_be_created_for_a_conflicting_extension_constraint(): void
{
$requirement = Requirement::forConflictingExtension('mbstring', null);
Expand Down
Loading