add --by-extensions and --without-suggests options for download command

This commit is contained in:
crazywhalecc 2023-10-22 16:35:15 +08:00 committed by Jerry Ma
parent c800a53f77
commit 4e9b8980d0
2 changed files with 73 additions and 4 deletions

View File

@ -8,8 +8,10 @@ use SPC\builder\traits\UnixSystemUtilTrait;
use SPC\exception\DownloaderException; use SPC\exception\DownloaderException;
use SPC\exception\FileSystemException; use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException; use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException;
use SPC\store\Config; use SPC\store\Config;
use SPC\store\Downloader; use SPC\store\Downloader;
use SPC\util\DependencyUtil;
use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
@ -34,6 +36,7 @@ class DownloadCommand extends BaseCommand
$this->addOption('custom-url', 'U', InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Specify custom source download url, e.g "php-src:https://downloads.php.net/~eric/php-8.3.0beta1.tar.gz"'); $this->addOption('custom-url', 'U', InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Specify custom source download url, e.g "php-src:https://downloads.php.net/~eric/php-8.3.0beta1.tar.gz"');
$this->addOption('from-zip', 'Z', InputOption::VALUE_REQUIRED, 'Fetch from zip archive'); $this->addOption('from-zip', 'Z', InputOption::VALUE_REQUIRED, 'Fetch from zip archive');
$this->addOption('by-extensions', 'e', InputOption::VALUE_REQUIRED, 'Fetch by extensions, e.g "openssl,mbstring"'); $this->addOption('by-extensions', 'e', InputOption::VALUE_REQUIRED, 'Fetch by extensions, e.g "openssl,mbstring"');
$this->addOption('without-suggests', null, null, 'Do not fetch suggested sources when using --by-extensions');
} }
public function initialize(InputInterface $input, OutputInterface $output): void public function initialize(InputInterface $input, OutputInterface $output): void
@ -105,11 +108,18 @@ class DownloadCommand extends BaseCommand
Config::$source['openssl']['regex'] = '/href="(?<file>openssl-(?<version>1.[^"]+)\.tar\.gz)\"/'; Config::$source['openssl']['regex'] = '/href="(?<file>openssl-(?<version>1.[^"]+)\.tar\.gz)\"/';
} }
// --by-extensions
if ($by_ext = $this->getOption('by-extensions')) {
$ext = array_map('trim', array_filter(explode(',', $by_ext)));
$sources = $this->calculateSourcesByExt($ext, !$this->getOption('without-suggests'));
array_unshift($sources, 'php-src', 'micro', 'pkg-config');
} else {
// get source list that will be downloaded // get source list that will be downloaded
$sources = array_map('trim', array_filter(explode(',', $this->getArgument('sources')))); $sources = array_map('trim', array_filter(explode(',', $this->getArgument('sources'))));
if (empty($sources)) { if (empty($sources)) {
$sources = array_keys(Config::getSources()); $sources = array_keys(Config::getSources());
} }
}
$chosen_sources = $sources; $chosen_sources = $sources;
// Process -U options // Process -U options
@ -187,4 +197,26 @@ class DownloadCommand extends BaseCommand
logger()->info('Extract success'); logger()->info('Extract success');
return static::SUCCESS; return static::SUCCESS;
} }
/**
* Calculate the sources by extensions
*
* @param array $extensions extension list
* @throws FileSystemException
* @throws WrongUsageException
*/
private function calculateSourcesByExt(array $extensions, bool $include_suggests = true): array
{
[$extensions, $libraries] = $include_suggests ? DependencyUtil::getAllExtLibsByDeps($extensions) : DependencyUtil::getExtLibsByDeps($extensions);
$sources = [];
foreach ($extensions as $extension) {
if (Config::getExt($extension, 'type') === 'external') {
$sources[] = Config::getExt($extension, 'source');
}
}
foreach ($libraries as $library) {
$sources[] = Config::getLib($library, 'source');
}
return array_values(array_unique($sources));
}
} }

View File

@ -99,6 +99,43 @@ class DependencyUtil
return $final; return $final;
} }
public static function getAllExtLibsByDeps(array $exts): array
{
$sorted = [];
$visited = [];
$not_included_exts = [];
foreach ($exts as $ext) {
if (!isset($visited[$ext])) {
self::visitExtAllDeps($ext, $visited, $sorted);
}
}
$libs = [];
foreach ($sorted as $ext) {
if (!in_array($ext, $exts)) {
$not_included_exts[] = $ext;
}
foreach (array_merge(Config::getExt($ext, 'lib-depends', []), Config::getExt($ext, 'lib-suggests', [])) as $dep) {
if (!in_array($dep, $libs)) {
$libs[] = $dep;
}
}
}
return [$sorted, self::getAllLibsByDeps($libs), $not_included_exts];
}
public static function getAllLibsByDeps(array $libs): array
{
$sorted = [];
$visited = [];
foreach ($libs as $lib) {
if (!isset($visited[$lib])) {
self::visitLibAllDeps($lib, $visited, $sorted);
}
}
return $sorted;
}
/** /**
* @throws FileSystemException * @throws FileSystemException
* @throws RuntimeException * @throws RuntimeException