diff --git a/composer/Plugin/RecipeUnpack/RootComposer.php b/composer/Plugin/RecipeUnpack/RootComposer.php index da07224a275caaab614ba0fae9627c52a75d12ca..6ddf5d967ce14f419afe00135a1eed8d76de0bb6 100644 --- a/composer/Plugin/RecipeUnpack/RootComposer.php +++ b/composer/Plugin/RecipeUnpack/RootComposer.php @@ -7,6 +7,7 @@ use Composer\IO\IOInterface; use Composer\Json\JsonFile; use Composer\Json\JsonManipulator; +use Composer\Package\Link; use Composer\Package\Locker; use Composer\Package\RootPackageInterface; @@ -139,23 +140,46 @@ public function writeFiles(): void { $this->io->write("Unpacking has updated the root composer files.", verbosity: IOInterface::VERBOSE); - assert(self::checkRootPackage($composer_content, $this->composer->getPackage()), 'Composer root package and composer.json match'); + if (ini_get('zend.assertions') > 0) { + $diff = self::compareComposerContentWithRootPackage($composer_content, $this->composer->getPackage()); + assert(empty($diff), + sprintf("Composer root package and composer.json mismatch detected.\nrequire: %s\nrequire-dev: %s\n", + array_key_exists('require', $diff) ? implode(', ', $diff['require']) : 'OK', + array_key_exists('require-dev', $diff) ? implode(', ', $diff['require-dev']) : 'OK', + ) + ); + } } /** - * Checks that the composer content and root package match. + * Composer the root composer content and root package. * * @param string $composer_content * The root composer content. * @param \Composer\Package\RootPackageInterface $root_package * The root package. * - * @return bool - * TRUE if the composer content and root package match, FALSE if not. + * @return array{require?: string, require-dev?: string[]} + * An array containing differences between composer content and + * root package or an empty array if they match. */ - private static function checkRootPackage(string $composer_content, RootPackageInterface $root_package): bool { + private static function compareComposerContentWithRootPackage(string $composer_content, RootPackageInterface $root_package): array { $composer = JsonFile::parseJson($composer_content); - return empty(array_diff_key($root_package->getRequires(), $composer['require'] ?? [])) && empty(array_diff_key($root_package->getDevRequires(), $composer['require-dev'] ?? [])); + $diff = []; + + $format_diff = static fn(Link $link): string => (string) $link; + + $requires_diff = array_diff_key($root_package->getRequires(), $composer['require'] ?? []); + if (!empty($requires_diff)) { + $diff['require'] = array_map($format_diff, $requires_diff); + } + + $dev_requires_diff = array_diff_key($root_package->getDevRequires(), $composer['require-dev'] ?? []); + if (!empty($dev_requires_diff)) { + $diff['require-dev'] = array_map($format_diff, $dev_requires_diff); + } + + return $diff; } }