From 12031542ba8e529925d1ffdc1714acf28a43758a Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Wed, 18 Sep 2024 08:49:59 +0200 Subject: [PATCH] Add suggestions of provider packages for ext- and lib- packages (#12113) Fixes #11669 --- src/Composer/DependencyResolver/Problem.php | 48 +++++++++++++++------ 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/src/Composer/DependencyResolver/Problem.php b/src/Composer/DependencyResolver/Problem.php index 652144b23..c54fab1af 100644 --- a/src/Composer/DependencyResolver/Problem.php +++ b/src/Composer/DependencyResolver/Problem.php @@ -278,14 +278,19 @@ class Problem $version = self::getPlatformPackageVersion($pool, $packageName, phpversion($ext) ?: '0'); if (null === $version) { + $providersStr = self::getProvidersList($repositorySet, $packageName, 5); + if ($providersStr !== null) { + $providersStr = "\n\n Alternatively you can require one of these packages that provide the extension (or parts of it):\n$providersStr"; + } + if (extension_loaded($ext)) { return [ $msg, - 'the '.$packageName.' package is disabled by your platform config. Enable it again with "composer config platform.'.$packageName.' --unset".', + 'the '.$packageName.' package is disabled by your platform config. Enable it again with "composer config platform.'.$packageName.' --unset".' . $providersStr, ]; } - return [$msg, 'it is missing from your system. Install or enable PHP\'s '.$ext.' extension.']; + return [$msg, 'it is missing from your system. Install or enable PHP\'s '.$ext.' extension.' . $providersStr]; } return [$msg, 'it has the wrong version installed ('.$version.').']; @@ -299,7 +304,12 @@ class Problem return ["- Root composer.json requires linked library ".$packageName.self::constraintToText($constraint).' but ', $error]; } - return ["- Root composer.json requires linked library ".$packageName.self::constraintToText($constraint).' but ', 'it has the wrong version installed or is missing from your system, make sure to load the extension providing it.']; + $providersStr = self::getProvidersList($repositorySet, $packageName, 5); + if ($providersStr !== null) { + $providersStr = "\n\n Alternatively you can require one of these packages that provide the library (or parts of it):\n$providersStr"; + } + + return ["- Root composer.json requires linked library ".$packageName.self::constraintToText($constraint).' but ', 'it has the wrong version installed or is missing from your system, make sure to load the extension providing it.'.$providersStr]; } } @@ -412,17 +422,8 @@ class Problem return ["- Root composer.json requires $packageName, it ", 'could not be found, it looks like its name is invalid, "'.$illegalChars.'" is not allowed in package names.']; } - if ($providers = $repositorySet->getProviders($packageName)) { - $maxProviders = 20; - $providersStr = implode(array_map(static function ($p): string { - $description = $p['description'] ? ' '.substr($p['description'], 0, 100) : ''; - - return ' - '.$p['name'].$description."\n"; - }, count($providers) > $maxProviders + 1 ? array_slice($providers, 0, $maxProviders) : $providers)); - if (count($providers) > $maxProviders + 1) { - $providersStr .= ' ... and '.(count($providers) - $maxProviders).' more.'."\n"; - } - + $providersStr = self::getProvidersList($repositorySet, $packageName, 15); + if ($providersStr !== null) { return ["- Root composer.json requires $packageName".self::constraintToText($constraint).", it ", "could not be found in any version, but the following packages provide it:\n".$providersStr." Consider requiring one of these to satisfy the $packageName requirement."]; } @@ -635,4 +636,23 @@ class Problem return $constraint ? ' '.$constraint->getPrettyString() : ''; } + + private static function getProvidersList(RepositorySet $repositorySet, string $packageName, int $maxProviders): ?string + { + $providers = $repositorySet->getProviders($packageName); + if (\count($providers) > 0) { + $providersStr = implode(array_map(static function ($p): string { + $description = $p['description'] ? ' '.substr($p['description'], 0, 100) : ''; + + return ' - '.$p['name'].$description."\n"; + }, count($providers) > $maxProviders + 1 ? array_slice($providers, 0, $maxProviders) : $providers)); + if (count($providers) > $maxProviders + 1) { + $providersStr .= ' ... and '.(count($providers) - $maxProviders).' more.'."\n"; + } + + return $providersStr; + } + + return null; + } }