ext-test-matrix generation fix

This commit is contained in:
crazywhalecc
2026-07-07 15:03:31 +08:00
parent c6a227f4de
commit a59473e4ab
2 changed files with 63 additions and 4 deletions

View File

@@ -107,7 +107,12 @@ class GenExtTestMatrixCommand extends BaseCommand
// Separate into regular and virtual extensions (build-static:false excluded globally) // Separate into regular and virtual extensions (build-static:false excluded globally)
$all_regular = []; $all_regular = [];
$all_virtual = []; $all_virtual = [];
$all_libraries = [];
foreach ($all as $pkg_name => $config) { foreach ($all as $pkg_name => $config) {
if (($config['type'] ?? '') === 'library') {
$all_libraries[$pkg_name] = $config;
continue;
}
if (($config['type'] ?? '') !== 'php-extension') { if (($config['type'] ?? '') !== 'php-extension') {
continue; continue;
} }
@@ -154,10 +159,7 @@ class GenExtTestMatrixCommand extends BaseCommand
$raw, $raw,
fn ($d) => isset($pool_set[$d]) && $d !== $pkg_name fn ($d) => isset($pool_set[$d]) && $d !== $pkg_name
)); ));
$os_lib_deps[$this->displayName($pkg_name)] = array_values(array_filter( $os_lib_deps[$this->displayName($pkg_name)] = $this->collectLibraryDeps($raw, $all_libraries, $os);
$raw,
fn ($d) => !str_starts_with($d, 'ext-')
));
} }
$all_ext_lib_deps[$os] = $os_lib_deps; $all_ext_lib_deps[$os] = $os_lib_deps;
@@ -300,6 +302,41 @@ class GenExtTestMatrixCommand extends BaseCommand
return str_starts_with($pkg_name, 'ext-') ? substr($pkg_name, 4) : $pkg_name; return str_starts_with($pkg_name, 'ext-') ? substr($pkg_name, 4) : $pkg_name;
} }
/**
* Collect direct and transitive library dependencies from a package dependency list.
*
* @param string[] $deps
* @param array<string, mixed[]> $library_configs
* @param array<string, true> $seen
*
* @return string[]
*/
private function collectLibraryDeps(array $deps, array $library_configs, string $platform, array $seen = []): array
{
$collected = [];
foreach ($deps as $dep) {
if (str_starts_with($dep, 'ext-') || isset($seen[$dep])) {
continue;
}
$seen[$dep] = true;
$collected[$dep] = $dep;
if (!isset($library_configs[$dep])) {
continue;
}
$child_deps = array_merge(
$this->resolvePlatformList($library_configs[$dep], 'depends', $platform),
$this->resolvePlatformList($library_configs[$dep], 'suggests', $platform),
);
foreach ($this->collectLibraryDeps($child_deps, $library_configs, $platform, $seen) as $child_dep) {
$collected[$child_dep] = $child_dep;
}
}
return array_values($collected);
}
/** /**
* Split orphans into batches such that no two conflicting extensions share a batch. * Split orphans into batches such that no two conflicting extensions share a batch.
* Uses a greedy graph-coloring approach. * Uses a greedy graph-coloring approach.

View File

@@ -176,6 +176,20 @@ class GenExtTestMatrixCommandTest extends TestCase
} }
} }
/**
* --for-libs must include extensions that depend on the library through other libraries.
*/
public function testForLibsFilterIncludesTransitiveLibraryDeps(): void
{
$matrix = $this->runMatrix(['--os' => 'Linux', '--for-libs' => 'libde265']);
$this->assertNotEmpty($matrix, '--for-libs=libde265 must yield at least one entry');
foreach ($matrix as $entry) {
$parts = explode(',', $entry['extension']);
$this->assertContains('imagick', $parts, "Entry {$entry['extension']} should not appear in --for-libs=libde265 results");
}
}
/** /**
* --tier2 must produce only Tier2 runners and no Windows entries. * --tier2 must produce only Tier2 runners and no Windows entries.
*/ */
@@ -260,12 +274,14 @@ class GenExtTestMatrixCommandTest extends TestCase
* - ext-redis simple orphan * - ext-redis simple orphan
* - ext-xml depends on lib 'libxml2' * - ext-xml depends on lib 'libxml2'
* - ext-dom depends on ext-xml (DFS chain) * - ext-dom depends on ext-xml (DFS chain)
* - ext-imagick depends on imagemagick -> libheif -> libde265
* - ext-linux-only restricted to Linux via os: [Linux] * - ext-linux-only restricted to Linux via os: [Linux]
*/ */
private static function buildFixture(): array private static function buildFixture(): array
{ {
// php-extension must be a non-empty assoc array ([] fails is_assoc_array() check). // php-extension must be a non-empty assoc array ([] fails is_assoc_array() check).
$ext = static fn (array $phpExt = ['arg-type' => 'standard'], array $topLevel = []): array => array_merge(['type' => 'php-extension', 'php-extension' => $phpExt], $topLevel); $ext = static fn (array $phpExt = ['arg-type' => 'standard'], array $topLevel = []): array => array_merge(['type' => 'php-extension', 'php-extension' => $phpExt], $topLevel);
$lib = static fn (array $topLevel = []): array => array_merge(['type' => 'library', 'artifact' => ['source' => 'custom']], $topLevel);
return [ return [
// Isolated standalones // Isolated standalones
@@ -284,6 +300,12 @@ class GenExtTestMatrixCommandTest extends TestCase
'ext-xml' => $ext(['arg-type' => 'standard'], ['depends' => ['libxml2']]), 'ext-xml' => $ext(['arg-type' => 'standard'], ['depends' => ['libxml2']]),
'ext-dom' => $ext(['arg-type' => 'standard'], ['depends' => ['ext-xml']]), 'ext-dom' => $ext(['arg-type' => 'standard'], ['depends' => ['ext-xml']]),
// Transitive library chain: imagick -> imagemagick -> libheif -> libde265
'ext-imagick' => $ext(['arg-type' => 'standard'], ['depends' => ['imagemagick']]),
'imagemagick' => $lib(['depends' => ['libheif']]),
'libheif' => $lib(['depends' => ['libde265']]),
'libde265' => $lib(),
// OS-restricted to Linux only // OS-restricted to Linux only
'ext-linux-only' => $ext(['os' => ['Linux']]), 'ext-linux-only' => $ext(['os' => ['Linux']]),
]; ];