From fdde9e593343111d8f78e66901851ac427b3bae1 Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Wed, 14 Oct 2020 10:57:23 +0200 Subject: [PATCH] On composer install we fix locked packages, but consider them locked for error reporting --- src/Composer/DependencyResolver/Request.php | 12 +++++++++++- src/Composer/DependencyResolver/Rule.php | 4 ++++ src/Composer/Installer.php | 3 +-- .../Fixtures/installer/partial-update-from-lock.test | 5 ++--- .../root-alias-change-with-circular-dep.test | 2 -- 5 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/Composer/DependencyResolver/Request.php b/src/Composer/DependencyResolver/Request.php index af3141cec..618f1b784 100644 --- a/src/Composer/DependencyResolver/Request.php +++ b/src/Composer/DependencyResolver/Request.php @@ -45,6 +45,7 @@ class Request protected $requires = array(); protected $fixedPackages = array(); protected $lockedPackages = array(); + protected $fixedLockedPackages = array(); protected $updateAllowList = array(); protected $updateAllowTransitiveDependencies = false; @@ -84,6 +85,15 @@ class Request $this->lockedPackages[spl_object_hash($package)] = $package; } + /** + * Mark a package fixed, but also keep track it is from the lock file (needed for composer install error reporting) + */ + public function fixLockedPackage(PackageInterface $package) + { + $this->fixedPackages[spl_object_hash($package)] = $package; + $this->fixedLockedPackages[spl_object_hash($package)] = $package; + } + public function unlockPackage(PackageInterface $package) { unset($this->lockedPackages[spl_object_hash($package)]); @@ -132,7 +142,7 @@ class Request public function isLockedPackage(PackageInterface $package) { - return isset($this->lockedPackages[spl_object_hash($package)]); + return isset($this->lockedPackages[spl_object_hash($package)]) || isset($this->fixedLockedPackages[spl_object_hash($package)]); } public function getFixedOrLockedPackages() diff --git a/src/Composer/DependencyResolver/Rule.php b/src/Composer/DependencyResolver/Rule.php index 2f57acd5f..371c2ab05 100644 --- a/src/Composer/DependencyResolver/Rule.php +++ b/src/Composer/DependencyResolver/Rule.php @@ -199,6 +199,10 @@ abstract class Rule case self::RULE_FIXED: $package = $this->deduplicateDefaultBranchAlias($this->reasonData['package']); + if ($request->isLockedPackage($package)) { + return $package->getPrettyName().' is locked to version '.$package->getPrettyVersion().' and an update of this package was not requested.'; + } + return $package->getPrettyName().' is present at version '.$package->getPrettyVersion() . ' and cannot be modified by Composer'; case self::RULE_PACKAGE_CONFLICT: diff --git a/src/Composer/Installer.php b/src/Composer/Installer.php index b0aa17046..7e83bf136 100644 --- a/src/Composer/Installer.php +++ b/src/Composer/Installer.php @@ -633,7 +633,7 @@ class Installer } foreach ($lockedRepository->getPackages() as $package) { - $request->fixPackage($package); + $request->fixLockedPackage($package); } foreach ($this->locker->getPlatformRequirements($this->devMode) as $link) { @@ -651,7 +651,6 @@ class Installer // installing the locked packages on this platform resulted in lock modifying operations, there wasn't a conflict, but the lock file as-is seems to not work on this system if (0 !== count($lockTransaction->getOperations())) { $this->io->writeError('Your lock file cannot be installed on this system without changes. Please run composer update.', true, IOInterface::QUIET); - // TODO actually display operations to explain what happened? return 1; } } catch (SolverProblemsException $e) { diff --git a/tests/Composer/Test/Fixtures/installer/partial-update-from-lock.test b/tests/Composer/Test/Fixtures/installer/partial-update-from-lock.test index bce29a21f..d176b02d3 100644 --- a/tests/Composer/Test/Fixtures/installer/partial-update-from-lock.test +++ b/tests/Composer/Test/Fixtures/installer/partial-update-from-lock.test @@ -21,7 +21,8 @@ Partial update from lock file should update everything to the state of the lock, "require": { "a/old": "*", "b/unstable": "*", - "c/uptodate": "*" + "c/uptodate": "*", + "e/newreq": "*" } } --LOCK-- @@ -60,7 +61,6 @@ update b/unstable { "name": "a/old", "version": "1.0.0", "type": "library" }, { "name": "b/unstable", "version": "1.0.0", "type": "library", "require": {"f/dependency": "1.*"} }, { "name": "c/uptodate", "version": "1.0.0", "type": "library" }, - { "name": "d/removed", "version": "1.0.0", "type": "library" }, { "name": "e/newreq", "version": "1.0.0", "type": "library" }, { "name": "f/dependency", "version": "1.0.0", "type": "library" } ], @@ -77,5 +77,4 @@ update b/unstable Upgrading a/old (0.9.0 => 1.0.0) Downgrading b/unstable (1.1.0-alpha => 1.0.0) Downgrading c/uptodate (2.0.0 => 1.0.0) -Installing d/removed (1.0.0) Installing e/newreq (1.0.0) diff --git a/tests/Composer/Test/Fixtures/installer/root-alias-change-with-circular-dep.test b/tests/Composer/Test/Fixtures/installer/root-alias-change-with-circular-dep.test index 5cd80b27b..28e4ac4bf 100644 --- a/tests/Composer/Test/Fixtures/installer/root-alias-change-with-circular-dep.test +++ b/tests/Composer/Test/Fixtures/installer/root-alias-change-with-circular-dep.test @@ -62,6 +62,4 @@ Your lock file does not contain a compatible set of packages. Please run compose - b/requirer is locked to version 1.0.0 and an update of this package was not requested. - b/requirer 1.0.0 requires root/pkg ^1 -> found root/pkg[2.x-dev] but it does not match the constraint. -Use the option --with-all-dependencies to allow upgrades, downgrades and removals for packages currently locked to specific versions. - --EXPECT--