Skip to content

Commit

Permalink
[BUGFIX] Ignore non-typo3 packages in PackageState
Browse files Browse the repository at this point in the history
The testing-framework creates test instances per
functional test-case based on properties defining
the system extensions, extension and fixture test
extension to symlink and load in the non-composer
test instances.

Therefore, the `PackageStates.php` file is created
on the first test run per test-case manually based
on the provided properties in the defined order.

With [1] a `PackageCollection` class has been added
to ensure proper extension sorting in the packages
state file based on dependency informations. That
is essentially for the loading and processing order.

Since TYPO3 v12 extensions in composer mode no longer
requires the presence of a `ext_emconf.php` versus
non-composer mode. The `ext_emconf.php` is still added
if a extension is published to TER. Therefore, some
extension authors removed a manual `ext_emconf.php`
from their extensions.

Extension composer.json may contain non-extension
packages as dependencies (`require`), which is not
handled by the PackageCollection due to the fact
that it assumes that all required packages are valid
extensions.

This change modifies the dependency validation method
`PackageCollection->isComposerDependency()` using the
`ComposerPackageManager` class information to determine
if a package is a extension or not.

For example platform requires like `"php"` or packages
like `"composer/installers"` are no longer used for
dependency ordering and therefore throwing a exception.

[1] b2b158f

Resolves: #510
Releases: main
  • Loading branch information
tweis authored and sbuerk committed Nov 22, 2023
1 parent e0d827b commit ee0df3c
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 7 deletions.
24 changes: 18 additions & 6 deletions Classes/Core/PackageCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
use TYPO3\CMS\Core\Service\DependencyOrderingService;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\PathUtility;
use TYPO3\TestingFramework\Composer\ComposerPackageManager;

/**
* Collection for extension packages to resolve their dependencies in a test-base.
Expand All @@ -45,23 +46,28 @@ class PackageCollection
protected array $packages;

/**
* @param ComposerPackageManager $composerPackageManager
* @param PackageManager $packageManager
* @param array<PackageKey, StateConfiguration> $packageStates
*/
public static function fromPackageStates(PackageManager $packageManager, string $basePath, array $packageStates): self
public static function fromPackageStates(ComposerPackageManager $composerPackageManager, PackageManager $packageManager, string $basePath, array $packageStates): self
{
$packages = [];
foreach ($packageStates as $packageKey => $packageStateConfiguration) {
$packagePath = PathUtility::sanitizeTrailingSeparator(
rtrim($basePath, '/') . '/' . $packageStateConfiguration['packagePath']
);
$packages[] = new Package($packageManager, $packageKey, $packagePath);
$packages[] = $package = new Package($packageManager, $packageKey, $packagePath);
$packageManager->registerPackage($package);
}
return new self(...$packages);

return new self($composerPackageManager, ...$packages);
}

public function __construct(PackageInterface ...$packages)
{
public function __construct(
private ComposerPackageManager $composerPackageManager,
PackageInterface ...$packages,
) {
$this->packages = array_combine(
array_map(static fn(PackageInterface $package) => $package->getPackageKey(), $packages),
$packages
Expand Down Expand Up @@ -253,6 +259,11 @@ protected function getDependencyArrayForPackage(PackageInterface $package, array
$dependentPackageKeys[] = $dependentPackageKey;
}
if (!isset($this->packages[$dependentPackageKey])) {
if ($this->isComposerDependency($dependentPackageKey)) {
// The given package has a dependency to a Composer package that has no relation to TYPO3
// We can ignore those, when calculating the extension order
continue;
}
throw new Exception(
sprintf(
'Package "%s" depends on package "%s" which does not exist.',
Expand Down Expand Up @@ -305,6 +316,7 @@ protected function findFrameworkKeys(): array

protected function isComposerDependency(string $packageKey): bool
{
return false;
$packageInfo = $this->composerPackageManager->getPackageInfo($packageKey);
return !(($packageInfo?->isSystemExtension() ?? false) || ($packageInfo?->isExtension()));
}
}
3 changes: 2 additions & 1 deletion Classes/Core/Testbase.php
Original file line number Diff line number Diff line change
Expand Up @@ -613,9 +613,10 @@ public function setUpPackageStates(
);
// PackageManager is required to create a Package instance...
$packageCollection = PackageCollection::fromPackageStates(
$this->composerPackageManager,
$packageManager,
$instancePath,
$packageStates['packages']
$packageStates['packages'],
);
$packageStates['packages'] = $packageCollection->sortPackageStates(
$packageStates['packages'],
Expand Down

0 comments on commit ee0df3c

Please sign in to comment.