output->writeln('This command is only available in source mode.');
return static::USER_ERROR;
}
$all = PackageConfig::getAll();
$extensions = [];
foreach ($all as $pkg_name => $config) {
if (($config['type'] ?? '') !== 'php-extension') {
continue;
}
// Strip ext- prefix for display name
$name = str_starts_with($pkg_name, 'ext-') ? substr($pkg_name, 4) : $pkg_name;
// Determine OS support from php-extension.os field.
// If the field is absent, the extension supports all three OSes.
$os_list = $config['php-extension']['os'] ?? null;
if ($os_list === null) {
$linux = true;
$macos = true;
$windows = true;
} else {
$linux = in_array('Linux', $os_list, true);
$macos = in_array('Darwin', $os_list, true);
$windows = in_array('Windows', $os_list, true);
}
$extensions[] = [
'name' => $name,
'linux' => $linux,
'macos' => $macos,
'windows' => $windows,
'url' => $this->resolveSourceUrl($config, $name),
];
}
// Sort alphabetically by name
usort($extensions, fn ($a, $b) => strcmp($a['name'], $b['name']));
$output = [
'generated_at' => date('c'),
'extensions' => $extensions,
];
$output_path = ROOT_DIR . '/docs/.vitepress/ext-data.json';
file_put_contents($output_path, json_encode($output, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . PHP_EOL);
$this->output->writeln("Generated {$output_path} with " . count($extensions) . ' extensions.');
return static::SUCCESS;
}
private function resolveSourceUrl(array $config, string $ext_name): ?string
{
$source = $config['artifact']['source'] ?? null;
if ($source === null) {
return null;
}
return match ($source['type'] ?? '') {
'pecl' => 'https://pecl.php.net/package/' . ($source['name'] ?? $ext_name),
'git' => rtrim($source['url'] ?? '', '/'),
'ghtar', 'ghrel', 'ghtagtar', 'pie' => isset($source['repo'])
? 'https://github.com/' . $source['repo']
: null,
default => null,
};
}
}