addArgument( 'artifacts', InputArgument::OPTIONAL, 'Specific artifacts to download, comma separated, e.g "php-src,openssl,curl"', suggestedValues: function (CompletionInput $input) { $input_val = $input->getCompletionValue(); $all_names = ArtifactLoader::getLoadedArtifactNames(); // filter by input value return array_filter($all_names, fn ($name) => str_starts_with($name, $input_val)); }, ); // 2.x compatible options $this->addOption('shallow-clone', null, null, '(deprecated) Clone shallowly repositories when downloading sources'); $this->addOption('for-extensions', 'e', InputOption::VALUE_REQUIRED, 'Fetch by extensions, e.g "openssl,mbstring"'); $this->addOption('for-libs', 'l', InputOption::VALUE_REQUIRED, 'Fetch by libraries, e.g "libcares,openssl,onig"'); $this->addOption('without-suggests', null, null, 'Do not fetch suggested sources when using --for-extensions'); $this->addOption('without-suggestions', null, null, '(deprecated) Do not fetch suggested sources when using --for-extensions'); // download command specific options $this->addOption('clean', null, null, 'Clean old download cache and source before fetch'); $this->addOption('for-packages', null, InputOption::VALUE_REQUIRED, 'Fetch by packages, e.g "php,libssl,libcurl"'); // shared downloader options (no prefix for download command) $this->getDefinition()->addOptions(DownloaderOptions::getConsoleOptions()); } public function handle(): int { // handle --clean option if ($this->getOption('clean')) { return $this->handleClean(); } $this->checkDoctorCache(); $downloader = new ArtifactDownloader(DownloaderOptions::extractFromConsoleOptions($this->input->getOptions())); // arguments if ($artifacts = $this->getArgument('artifacts')) { $artifacts = parse_comma_list($artifacts); $downloader->addArtifacts($artifacts); } // for-extensions $packages = []; if ($exts = $this->getOption('for-extensions')) { $packages = array_map(fn ($x) => "ext-{$x}", parse_extension_list($exts)); // when using for-extensions, also include php package array_unshift($packages, 'php'); array_unshift($packages, 'php-micro'); array_unshift($packages, 'php-embed'); array_unshift($packages, 'php-fpm'); } // for-libs / for-packages if ($libs = $this->getOption('for-libs')) { $packages = array_merge($packages, parse_comma_list($libs)); } if ($libs = $this->getOption('for-packages')) { $packages = array_merge($packages, parse_comma_list($libs)); } // resolve package dependencies and get artifacts directly $suggests = !($this->getOption('without-suggests') || $this->getOption('without-suggestions')); $resolved = DependencyResolver::resolve($packages, [], $suggests); foreach ($resolved as $pkg_name) { $pkg = PackageLoader::getPackage($pkg_name); if ($artifact = $pkg->getArtifact()) { $downloader->add($artifact); } } $starttime = microtime(true); $downloader->download(); $endtime = microtime(true); $elapsed = round($endtime - $starttime); $this->output->writeln(''); $this->output->writeln('Download completed in ' . $elapsed . ' s.'); return static::SUCCESS; } private function handleClean(): int { logger()->warning('You are doing some operations that are not recoverable:'); logger()->warning('- Removing directory: ' . SOURCE_PATH); logger()->warning('- Removing directory: ' . DOWNLOAD_PATH); logger()->warning('- Removing directory: ' . BUILD_ROOT_PATH); logger()->alert('I will remove these directories after 5 seconds!'); sleep(5); if (is_dir(SOURCE_PATH)) { InteractiveTerm::indicateProgress('Removing: ' . SOURCE_PATH); FileSystem::removeDir(SOURCE_PATH); InteractiveTerm::finish('Removed: ' . SOURCE_PATH); } if (is_dir(DOWNLOAD_PATH)) { InteractiveTerm::indicateProgress('Removing: ' . DOWNLOAD_PATH); FileSystem::removeDir(DOWNLOAD_PATH); InteractiveTerm::finish('Removed: ' . DOWNLOAD_PATH); } if (is_dir(BUILD_ROOT_PATH)) { InteractiveTerm::indicateProgress('Removing: ' . BUILD_ROOT_PATH); FileSystem::removeDir(BUILD_ROOT_PATH); InteractiveTerm::finish('Removed: ' . BUILD_ROOT_PATH); } InteractiveTerm::notice('Clean completed.'); return static::SUCCESS; } }