Add command to dump required PHP extensions based on vendor/composer/installed.json, composer.lock, composer.json (in this order)

This commit is contained in:
Alexander Over
2025-02-06 08:44:39 +01:00
parent 21de1a2291
commit 9b809a074f
3 changed files with 75 additions and 0 deletions

View File

@@ -194,6 +194,8 @@ Basic usage for building php with some extensions:
# fetch all libraries # fetch all libraries
./bin/spc download --all ./bin/spc download --all
# dump a list of extensions required by your project
./bin/spc dump-extensions
# only fetch necessary sources by needed extensions (recommended) # only fetch necessary sources by needed extensions (recommended)
./bin/spc download --for-extensions="openssl,pcntl,mbstring,pdo_sqlite" ./bin/spc download --for-extensions="openssl,pcntl,mbstring,pdo_sqlite"
# download pre-built libraries first (save time for compiling dependencies) # download pre-built libraries first (save time for compiling dependencies)

View File

@@ -18,7 +18,9 @@ use SPC\command\dev\PhpVerCommand;
use SPC\command\dev\SortConfigCommand; use SPC\command\dev\SortConfigCommand;
use SPC\command\DoctorCommand; use SPC\command\DoctorCommand;
use SPC\command\DownloadCommand; use SPC\command\DownloadCommand;
use SPC\command\DumpExtensionsCommand;
use SPC\command\DumpLicenseCommand; use SPC\command\DumpLicenseCommand;
use SPC\command\ExtensionDumperCommand;
use SPC\command\ExtractCommand; use SPC\command\ExtractCommand;
use SPC\command\InstallPkgCommand; use SPC\command\InstallPkgCommand;
use SPC\command\MicroCombineCommand; use SPC\command\MicroCombineCommand;
@@ -54,6 +56,7 @@ final class ConsoleApplication extends Application
new MicroCombineCommand(), new MicroCombineCommand(),
new SwitchPhpVersionCommand(), new SwitchPhpVersionCommand(),
new SPCConfigCommand(), new SPCConfigCommand(),
new DumpExtensionsCommand(),
// Dev commands // Dev commands
new AllExtCommand(), new AllExtCommand(),

View File

@@ -0,0 +1,70 @@
<?php
declare(strict_types=1);
namespace SPC\command;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Filesystem\Filesystem;
#[AsCommand(name: 'dump-extensions', description: 'Überprüft die benötigten PHP-Extensions')]
class DumpExtensionsCommand extends BaseCommand
{
private array $files = [
'vendor/composer/installed.json',
'composer.lock',
'composer.json',
];
public function handle(): int
{
$fs = new Filesystem();
$extensions = [];
foreach ($this->files as $file) {
if ($fs->exists($file)) {
$this->output->writeln("<info>Analyzing file: {$file}</info>");
$data = json_decode(file_get_contents($file), true);
if (!$data) {
$this->output->writeln("<error>Error parsing {$file}</error>");
continue;
}
$extensions = array_merge($extensions, $this->extractExtensions($data));
}
}
if (empty($extensions)) {
$this->output->writeln('<comment>No extensions found.</comment>');
return static::SUCCESS;
}
$extensions = array_unique($extensions);
sort($extensions);
$this->output->writeln("\n<info>Required PHP extensions:</info>");
$this->output->writeln(implode(',', array_map(fn ($ext) => substr($ext, 4), $extensions)));
return static::SUCCESS;
}
private function extractExtensions(array $data): array
{
return array_merge(
...array_map(
function ($package) {
return isset($package['require']) ? $this->filterExtensions($package['require']) : [];
},
$data['packages'] ?? [$data]
)
);
}
private function filterExtensions(array $requirements): array
{
return array_keys(array_filter($requirements, function ($key) {
return str_starts_with($key, 'ext-');
}, ARRAY_FILTER_USE_KEY));
}
}