setName('patches-doctor'); $this->setDescription('Run a series of checks to ensure that Composer Patches has a usable environment.'); $this->setAliases(['pd']); } protected function execute(InputInterface $input, OutputInterface $output): int { $plugin = $this->getPatchesPluginInstance(); if (is_null($plugin)) { return 1; } $plugin->loadLockedPatches(); $composer = $this->requireComposer(); $io = $this->getIO(); $plugin_manager = $composer->getPluginManager(); $capabilities = $plugin_manager->getPluginCapabilities( PatcherProvider::class, ['composer' => $composer, 'io' => $this->getIO()] ); $suggestions = []; $io->write(""); $io->write("System information"); $io->write("================================================================================"); $io->write( str_pad("Composer version: ", 72) . "" . str_pad( $this->getApplication()->getVersion(), 8, " ", STR_PAD_LEFT ) . "" ); $system_issues = false; if (!str_starts_with($this->getApplication()->getVersion(), "2")) { $system_issues = true; } $io->write(str_pad("PHP version: ", 72) . "" . str_pad(PHP_VERSION, 8, " ", STR_PAD_LEFT) . ""); if (PHP_VERSION_ID < 80000) { $system_issues = true; } if ($system_issues) { $suggestions[] = [ "message" => "Upgrade Composer and/or PHP to a more modern/supported version", "link" => "https://docs.cweagans.net/composer-patches/troubleshooting/guide#upgrade-system-software" ]; } $io->write(""); $io->write("Available patchers"); $io->write("================================================================================"); $has_usable_patcher = false; foreach ($capabilities as $capability) { /** @var PatcherProvider $capability */ $newPatchers = $capability->getPatchers(); foreach ($newPatchers as $i => $patcher) { if (!$patcher instanceof PatcherInterface) { throw new \UnexpectedValueException( 'Plugin capability ' . get_class($capability) . ' returned an invalid value.' ); } $usable = $patcher->canUse(); $has_usable_patcher = $has_usable_patcher || $usable; $io->write( str_pad(get_class($patcher) . " usable: ", 77) . ($usable ? "yes" : " no") ); } } $io->write( str_pad( "Has usable patchers: ", 77 ) . ($has_usable_patcher ? "yes" : " no") ); if (!$has_usable_patcher) { $suggestions[] = [ "message" => "Install software dependencies for applying patches", "link" => "https://docs.cweagans.net/composer-patches/troubleshooting/guide#install-patching-software" ]; } $io->write(""); $io->write("Common configuration issues"); $io->write("================================================================================"); $has_http_urls = false; foreach ($plugin->getPatchCollection()->getPatchedPackages() as $package) { foreach ($plugin->getPatchCollection()->getPatchesForPackage($package) as $patch) { if (str_starts_with($patch->url, 'http://')) { $has_http_urls = true; break 2; } } } $io->write( str_pad("has plain http patch URLs:", 77) . ($has_http_urls ? "yes" : " no") ); if ($has_http_urls) { $sh = $composer->getConfig()->get('secure-http'); $io->write( str_pad('secure-http disabled:', 77) . ($sh ? " no" : "yes") ); if ($sh) { $suggestions[] = [ "message" => "Patches must either be downloaded securely or 'secure-http' must be disabled", "link" => "https://docs.cweagans.net/composer-patches/troubleshooting/guide#download-patches-securely" ]; } } if (!empty($suggestions)) { $io->write(""); $io->write("Suggestions"); $io->write("================================================================================"); foreach ($suggestions as $suggestion) { $io->write(" - " . $suggestion['message']); $io->write(" More information: " . $suggestion['link']); } } return 0; } }