From f4d3a1e478b85ba233bfc98bb45d01c7396fbe22 Mon Sep 17 00:00:00 2001 From: Frank Prins <25006490+PrinsFrank@users.noreply.github.com> Date: Thu, 20 May 2021 20:44:53 +0200 Subject: [PATCH 1/3] Detect missing packages that are a requirement or dev-requirement but not locked. --- src/Composer/Command/ValidateCommand.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/Composer/Command/ValidateCommand.php b/src/Composer/Command/ValidateCommand.php index 0818c8c2f..a4c2071c1 100644 --- a/src/Composer/Command/ValidateCommand.php +++ b/src/Composer/Command/ValidateCommand.php @@ -99,6 +99,23 @@ EOT $lockErrors[] = 'The lock file is not up to date with the latest changes in composer.json, it is recommended that you run `composer update` or `composer update `.'; } + $lockData = $locker->getLockData(); + $lockPackageNames = array_map(static function($lockPackage) {return $lockPackage['name'];}, $lockData['packages']); + $devLockPackageNames = array_map(static function($devLockPackage) {return $devLockPackage['name'];}, $lockData['packages-dev']); + $missingRequiredPackages = array_diff(array_keys($composer->getPackage()->getRequires()), $lockPackageNames); + $missingDevRequiredPackages = array_diff(array_keys($composer->getPackage()->getDevRequires()), $devLockPackageNames); + if (count(array_merge($missingRequiredPackages, $missingDevRequiredPackages)) > 0) { + if (count($missingRequiredPackages) > 0) { + $lockErrors[] = '- Required package "' . implode('", "', $missingRequiredPackages) . '" is not present in the lock file.'; + } + if (count($missingDevRequiredPackages) > 0) { + $lockErrors[] = '- Dev-required package "' . implode('", "', $missingDevRequiredPackages) . '" is not present in the lock file.'; + } + $lockErrors[] = 'This usually happens when composer files are incorrectly merged or the composer.json file is manually edited.'; + $lockErrors[] = 'Read more about correctly resolving merge conflicts -> https://getcomposer.org/doc/articles/resolving-merge-conflicts.md'; + $lockErrors[] = 'and make sure to not edit the composer.json file directly but to use the "require" command (https://getcomposer.org/doc/03-cli.md#require).'; + } + $this->outputResult($io, $file, $errors, $warnings, $checkPublish, $publishErrors, $checkLock, $lockErrors, true); // $errors include publish and lock errors when exists From 32b70142d97212a9e6c15e98b3a52fc64422cdd4 Mon Sep 17 00:00:00 2001 From: Frank Prins <25006490+PrinsFrank@users.noreply.github.com> Date: Thu, 20 May 2021 20:55:00 +0200 Subject: [PATCH 2/3] Replace static anonymous function and replace it with normal anonymous function as static ones are only supported on PHP5.4 and up --- src/Composer/Command/ValidateCommand.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Composer/Command/ValidateCommand.php b/src/Composer/Command/ValidateCommand.php index a4c2071c1..54988ef79 100644 --- a/src/Composer/Command/ValidateCommand.php +++ b/src/Composer/Command/ValidateCommand.php @@ -100,8 +100,8 @@ EOT } $lockData = $locker->getLockData(); - $lockPackageNames = array_map(static function($lockPackage) {return $lockPackage['name'];}, $lockData['packages']); - $devLockPackageNames = array_map(static function($devLockPackage) {return $devLockPackage['name'];}, $lockData['packages-dev']); + $lockPackageNames = array_map(function($lockPackage) {return $lockPackage['name'];}, $lockData['packages']); + $devLockPackageNames = array_map(function($devLockPackage) {return $devLockPackage['name'];}, $lockData['packages-dev']); $missingRequiredPackages = array_diff(array_keys($composer->getPackage()->getRequires()), $lockPackageNames); $missingDevRequiredPackages = array_diff(array_keys($composer->getPackage()->getDevRequires()), $devLockPackageNames); if (count(array_merge($missingRequiredPackages, $missingDevRequiredPackages)) > 0) { From e83e92b2ae79b25a5d009bfc72a843a13dff5ab2 Mon Sep 17 00:00:00 2001 From: Frank Prins <25006490+PrinsFrank@users.noreply.github.com> Date: Thu, 20 May 2021 21:14:30 +0200 Subject: [PATCH 3/3] Ignore platform requirements like "ext-*" and "php" when validating the lock file as they don't get locked --- src/Composer/Command/ValidateCommand.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Composer/Command/ValidateCommand.php b/src/Composer/Command/ValidateCommand.php index 54988ef79..f92f97c12 100644 --- a/src/Composer/Command/ValidateCommand.php +++ b/src/Composer/Command/ValidateCommand.php @@ -16,6 +16,7 @@ use Composer\Factory; use Composer\Package\Loader\ValidatingArrayLoader; use Composer\Plugin\CommandEvent; use Composer\Plugin\PluginEvents; +use Composer\Repository\PlatformRepository; use Composer\Util\ConfigValidator; use Composer\Util\Filesystem; use Symfony\Component\Console\Input\InputArgument; @@ -102,8 +103,10 @@ EOT $lockData = $locker->getLockData(); $lockPackageNames = array_map(function($lockPackage) {return $lockPackage['name'];}, $lockData['packages']); $devLockPackageNames = array_map(function($devLockPackage) {return $devLockPackage['name'];}, $lockData['packages-dev']); - $missingRequiredPackages = array_diff(array_keys($composer->getPackage()->getRequires()), $lockPackageNames); - $missingDevRequiredPackages = array_diff(array_keys($composer->getPackage()->getDevRequires()), $devLockPackageNames); + $requiredPackages = array_filter(array_keys($composer->getPackage()->getRequires()), function($requiredPackageName) {return PlatformRepository::isPlatformPackage($requiredPackageName) === false;}); + $devRequiredPackages = array_filter(array_keys($composer->getPackage()->getDevRequires()), function($devRequiredPackageName) {return PlatformRepository::isPlatformPackage($devRequiredPackageName) === false;}); + $missingRequiredPackages = array_diff($requiredPackages, $lockPackageNames); + $missingDevRequiredPackages = array_diff($devRequiredPackages, $devLockPackageNames); if (count(array_merge($missingRequiredPackages, $missingDevRequiredPackages)) > 0) { if (count($missingRequiredPackages) > 0) { $lockErrors[] = '- Required package "' . implode('", "', $missingRequiredPackages) . '" is not present in the lock file.';