addArgument('artifacts', InputArgument::OPTIONAL, 'Specific artifacts to dump licenses, comma separated, e.g "php-src,openssl,curl"'); // v2 compatible options $this->addOption('for-extensions', 'e', InputOption::VALUE_REQUIRED, 'Dump by extensions (automatically includes php-src), e.g "openssl,mbstring"'); $this->addOption('for-libs', 'l', InputOption::VALUE_REQUIRED, 'Dump by libraries, e.g "openssl,zlib,curl"'); // v3 options $this->addOption('for-packages', 'p', InputOption::VALUE_REQUIRED, 'Dump by packages, e.g "php,libssl,libcurl"'); $this->addOption('dump-dir', 'd', InputOption::VALUE_REQUIRED, 'Target directory for dumped licenses', BUILD_ROOT_PATH . '/license'); $this->addOption('without-suggests', null, null, 'Do not include suggested packages when using --for-extensions or --for-packages'); } public function handle(): int { $dumper = new LicenseDumper(); $dump_dir = $this->getOption('dump-dir'); $artifacts_to_dump = []; // Handle direct artifact argument if ($artifacts = $this->getArgument('artifacts')) { $artifacts_to_dump = array_merge($artifacts_to_dump, parse_comma_list($artifacts)); } // Handle --for-extensions option if ($exts = $this->getOption('for-extensions')) { $artifacts_to_dump = array_merge( $artifacts_to_dump, $this->resolveFromExtensions(parse_extension_list($exts)) ); } // Handle --for-libs option (v2 compat) if ($libs = $this->getOption('for-libs')) { $artifacts_to_dump = array_merge( $artifacts_to_dump, $this->resolveFromPackages(parse_comma_list($libs)) ); } // Handle --for-packages option if ($packages = $this->getOption('for-packages')) { $artifacts_to_dump = array_merge( $artifacts_to_dump, $this->resolveFromPackages(parse_comma_list($packages)) ); } // Check if any artifacts to dump if (empty($artifacts_to_dump)) { $this->output->writeln('No artifacts specified. Use one of:'); $this->output->writeln(' - Direct argument: dump-license php-src,openssl,curl'); $this->output->writeln(' - --for-extensions: dump-license --for-extensions=openssl,mbstring'); $this->output->writeln(' - --for-libs: dump-license --for-libs=openssl,zlib'); $this->output->writeln(' - --for-packages: dump-license --for-packages=php,libssl'); return self::FAILURE; } // Deduplicate artifacts $artifacts_to_dump = array_values(array_unique($artifacts_to_dump)); logger()->info('Dumping licenses for ' . count($artifacts_to_dump) . ' artifact(s)'); logger()->debug('Artifacts: ' . implode(', ', $artifacts_to_dump)); // Add artifacts to dumper $dumper->addArtifacts($artifacts_to_dump); // Dump $success = $dumper->dump($dump_dir); if ($success) { InteractiveTerm::success('Licenses dumped successfully: ' . $dump_dir); // $this->output->writeln("✓ Successfully dumped licenses to: {$dump_dir}"); // $this->output->writeln(" Total artifacts: " . count($artifacts_to_dump) . ''); return self::SUCCESS; } $this->output->writeln('Failed to dump licenses'); return self::FAILURE; } /** * Resolve artifacts from extension names. * * @param array $extensions Extension names * @return array Artifact names */ private function resolveFromExtensions(array $extensions): array { // Convert extension names to package names $packages = array_map(fn ($ext) => "ext-{$ext}", $extensions); // Automatically include php-related artifacts array_unshift($packages, 'php'); array_unshift($packages, 'php-micro'); array_unshift($packages, 'php-embed'); array_unshift($packages, 'php-fpm'); return $this->resolveFromPackages($packages); } /** * Resolve artifacts from package names. * * @param array $packages Package names * @return array Artifact names */ private function resolveFromPackages(array $packages): array { $artifacts = []; $include_suggests = !$this->getOption('without-suggests'); // Resolve package dependencies $resolved_packages = DependencyResolver::resolve($packages, [], $include_suggests); foreach ($resolved_packages as $pkg_name) { try { $pkg = PackageLoader::getPackage($pkg_name); if ($artifact = $pkg->getArtifact()) { $artifacts[] = $artifact->getName(); } } catch (\Throwable $e) { logger()->debug("Package {$pkg_name} has no artifact or failed to load: {$e->getMessage()}"); } } return array_unique($artifacts); } }