From ea322c0d3b864c08f67185735a38cea14171a3a1 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Fri, 28 Jul 2023 00:02:49 +0800 Subject: [PATCH] add extract command, add -U option (custom download source --- src/SPC/ConsoleApplication.php | 3 +- src/SPC/builder/BuilderBase.php | 58 +++---------------------- src/SPC/command/DownloadCommand.php | 28 +++++++++++- src/SPC/command/ExtractCommand.php | 35 +++++++++++++++ src/SPC/command/dev/PhpVerCommand.php | 2 +- src/SPC/store/Downloader.php | 4 +- src/SPC/store/SourceExtractor.php | 61 +++++++++++++++++++++++++++ 7 files changed, 132 insertions(+), 59 deletions(-) create mode 100644 src/SPC/command/ExtractCommand.php create mode 100644 src/SPC/store/SourceExtractor.php diff --git a/src/SPC/ConsoleApplication.php b/src/SPC/ConsoleApplication.php index b073cd6a..db03abef 100644 --- a/src/SPC/ConsoleApplication.php +++ b/src/SPC/ConsoleApplication.php @@ -7,7 +7,6 @@ namespace SPC; use SPC\command\DeployCommand; use SPC\store\FileSystem; use Symfony\Component\Console\Application; -use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Command\HelpCommand; use Symfony\Component\Console\Command\ListCommand; @@ -16,7 +15,7 @@ use Symfony\Component\Console\Command\ListCommand; */ class ConsoleApplication extends Application { - public const VERSION = '2.0-rc3'; + public const VERSION = '2.0-rc4'; /** * @throws \ReflectionException diff --git a/src/SPC/builder/BuilderBase.php b/src/SPC/builder/BuilderBase.php index fd1a2844..c9243ca0 100644 --- a/src/SPC/builder/BuilderBase.php +++ b/src/SPC/builder/BuilderBase.php @@ -9,6 +9,7 @@ use SPC\exception\RuntimeException; use SPC\exception\WrongUsageException; use SPC\store\Config; use SPC\store\FileSystem; +use SPC\store\SourceExtractor; use SPC\util\CustomExt; use SPC\util\DependencyUtil; @@ -87,7 +88,7 @@ abstract class BuilderBase $lib->calcDependency(); } - $this->initSource(libs: $libraries); + SourceExtractor::initSource(libs: $libraries); // 构建库 foreach ($this->libs as $lib) { @@ -188,11 +189,11 @@ abstract class BuilderBase public function proveExts(array $extensions): void { CustomExt::loadCustomExt(); - $this->initSource(sources: ['php-src']); + SourceExtractor::initSource(sources: ['php-src']); if ($this->getPHPVersionID() >= 80000) { - $this->initSource(sources: ['micro']); + SourceExtractor::initSource(sources: ['micro']); } - $this->initSource(exts: $extensions); + SourceExtractor::initSource(exts: $extensions); foreach ($extensions as $extension) { $class = CustomExt::getExtClass($extension); $ext = new $class($extension, $this); @@ -221,6 +222,7 @@ abstract class BuilderBase * * @throws RuntimeException * @throws FileSystemException + * @throws WrongUsageException */ public function makeExtensionArgs(): string { @@ -292,52 +294,4 @@ abstract class BuilderBase ); } } - - protected function initSource(?array $sources = null, ?array $libs = null, ?array $exts = null): void - { - if (!file_exists(DOWNLOAD_PATH . '/.lock.json')) { - throw new WrongUsageException('Download lock file "downloads/.lock.json" not found, maybe you need to download sources first ?'); - } - $lock = json_decode(FileSystem::readFile(DOWNLOAD_PATH . '/.lock.json'), true); - - $sources_extracted = []; - // source check exist - if (is_array($sources)) { - foreach ($sources as $source) { - $sources_extracted[$source] = true; - } - } - // lib check source exist - if (is_array($libs)) { - foreach ($libs as $lib) { - // get source name for lib - $source = Config::getLib($lib, 'source'); - $sources_extracted[$source] = true; - } - } - // ext check source exist - if (is_array($exts)) { - foreach ($exts as $ext) { - // get source name for ext - if (Config::getExt($ext, 'type') !== 'external') { - continue; - } - $source = Config::getExt($ext, 'source'); - $sources_extracted[$source] = true; - } - } - - // start check - foreach ($sources_extracted as $source => $item) { - if (!isset($lock[$source])) { - throw new WrongUsageException('Source [' . $source . '] not downloaded, you should download it first !'); - } - - // check source dir exist - $check = $lock[$source]['move_path'] === null ? SOURCE_PATH . '/' . $source : SOURCE_PATH . '/' . $lock[$source]['move_path']; - if (!is_dir($check)) { - FileSystem::extractSource($source, DOWNLOAD_PATH . '/' . ($lock[$source]['filename'] ?? $lock[$source]['dirname']), $lock[$source]['move_path']); - } - } - } } diff --git a/src/SPC/command/DownloadCommand.php b/src/SPC/command/DownloadCommand.php index f25fefcc..23522fda 100644 --- a/src/SPC/command/DownloadCommand.php +++ b/src/SPC/command/DownloadCommand.php @@ -31,6 +31,7 @@ class DownloadCommand extends BaseCommand $this->addOption('with-php', null, InputOption::VALUE_REQUIRED, 'version in major.minor format like 8.1', '8.1'); $this->addOption('clean', null, null, 'Clean old download cache and source before fetch'); $this->addOption('all', 'A', null, 'Fetch all sources that static-php-cli needed'); + $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'); } @@ -139,14 +140,37 @@ class DownloadCommand extends BaseCommand } $chosen_sources = $sources; + // Process -U options + $custom_urls = []; + foreach ($this->input->getOption('custom-url') as $value) { + [$source_name, $url] = explode(':', $value, 2); + $custom_urls[$source_name] = $url; + } + // Download them f_mkdir(DOWNLOAD_PATH); $cnt = count($chosen_sources); $ni = 0; foreach ($chosen_sources as $source) { ++$ni; - logger()->info("Fetching source {$source} [{$ni}/{$cnt}]"); - Downloader::downloadSource($source, Config::getSource($source)); + if (isset($custom_urls[$source])) { + $config = Config::getSource($source); + $new_config = [ + 'type' => 'url', + 'url' => $custom_urls[$source], + ]; + if (isset($config['path'])) { + $new_config['path'] = $config['path']; + } + if (isset($config['filename'])) { + $new_config['filename'] = $config['filename']; + } + logger()->info("Fetching source {$source} from custom url [{$ni}/{$cnt}]"); + Downloader::downloadSource($source, $new_config, true); + } else { + logger()->info("Fetching source {$source} [{$ni}/{$cnt}]"); + Downloader::downloadSource($source, Config::getSource($source)); + } } // 打印拉取资源用时 $time = round(microtime(true) - START_TIME, 3); diff --git a/src/SPC/command/ExtractCommand.php b/src/SPC/command/ExtractCommand.php new file mode 100644 index 00000000..3a9f718a --- /dev/null +++ b/src/SPC/command/ExtractCommand.php @@ -0,0 +1,35 @@ +addArgument('sources', InputArgument::REQUIRED, 'The sources will be compiled, comma separated'); + } + + public function handle(): int + { + $sources = array_map('trim', array_filter(explode(',', $this->getArgument('sources')))); + if (empty($sources)) { + $this->output->writeln('sources cannot be empty, at least contain one !'); + return 1; + } + SourceExtractor::initSource(sources: $sources); + logger()->info('Extract done !'); + return 0; + } +} diff --git a/src/SPC/command/dev/PhpVerCommand.php b/src/SPC/command/dev/PhpVerCommand.php index cdd4cfa6..9b729da2 100644 --- a/src/SPC/command/dev/PhpVerCommand.php +++ b/src/SPC/command/dev/PhpVerCommand.php @@ -22,7 +22,7 @@ class PhpVerCommand extends BaseCommand { // Find php from source/php-src $file = SOURCE_PATH . '/php-src/main/php_version.h'; - $result = preg_match('/#define PHP_VERSION "(\d+\.\d+\.\d+)"/', file_get_contents($file), $match); + $result = preg_match('/#define PHP_VERSION "([^"]+)"/', file_get_contents($file), $match); if ($result === false) { $this->output->writeln('PHP source not found, maybe you need to extract first ?'); return 1; diff --git a/src/SPC/store/Downloader.php b/src/SPC/store/Downloader.php index 39a22494..d8aada0f 100644 --- a/src/SPC/store/Downloader.php +++ b/src/SPC/store/Downloader.php @@ -265,7 +265,7 @@ class Downloader * @throws FileSystemException * @throws RuntimeException */ - public static function downloadSource(string $name, ?array $source = null): void + public static function downloadSource(string $name, ?array $source = null, bool $force = false): void { if ($source === null) { $source = Config::getSource($name); @@ -278,7 +278,7 @@ class Downloader $lock = json_decode(FileSystem::readFile(DOWNLOAD_PATH . '/.lock.json'), true) ?? []; } // If lock file exists, skip downloading - if (isset($lock[$name])) { + if (isset($lock[$name]) && !$force) { if ($lock[$name]['source_type'] === 'archive' && file_exists(DOWNLOAD_PATH . '/' . $lock[$name]['filename'])) { logger()->notice("source [{$name}] already downloaded: " . $lock[$name]['filename']); return; diff --git a/src/SPC/store/SourceExtractor.php b/src/SPC/store/SourceExtractor.php new file mode 100644 index 00000000..8842b890 --- /dev/null +++ b/src/SPC/store/SourceExtractor.php @@ -0,0 +1,61 @@ + $item) { + if (Config::getSource($source) === null) { + throw new WrongUsageException("Source [{$source}] not exists, please check name and correct it !"); + } + if (!isset($lock[$source])) { + throw new WrongUsageException('Source [' . $source . '] not downloaded or not locked, you should download it first !'); + } + + // check source dir exist + $check = $lock[$source]['move_path'] === null ? SOURCE_PATH . '/' . $source : SOURCE_PATH . '/' . $lock[$source]['move_path']; + if (!is_dir($check)) { + FileSystem::extractSource($source, DOWNLOAD_PATH . '/' . ($lock[$source]['filename'] ?? $lock[$source]['dirname']), $lock[$source]['move_path']); + } + } + } +}