Преглед изворни кода

PoolBuilder: properly clean up alias packages when unfixing packages

Prevent aliases to be duplicated: no need to apply root aliases from
composer.json on packages currently locked, they should have their
aliases in the lock file, otherwise request an update.
Nils Adermann пре 5 година
родитељ
комит
613450e58a

+ 16 - 6
src/Composer/DependencyResolver/PoolBuilder.php

@@ -220,7 +220,9 @@ class PoolBuilder
             }
         }
 
-        if (isset($this->rootAliases[$name][$package->getVersion()])) {
+        // if propogateUpdate is false we are loading a fixed package, root aliases do not apply as they are manually
+        // loaded as separate packages in this case
+        if ($propagateUpdate && isset($this->rootAliases[$name][$package->getVersion()])) {
             $alias = $this->rootAliases[$name][$package->getVersion()];
             if ($package instanceof AliasPackage) {
                 $basePackage = $package->getAliasOf();
@@ -345,11 +347,19 @@ class PoolBuilder
     private function unfixPackage(Request $request, $name)
     {
         // remove locked package by this name which was already initialized
-        foreach ($this->packages as $i => $loadedPackage) {
-            if ($loadedPackage->getName() === $name && $loadedPackage->getRepository() === $request->getLockedRepository()) {
-                $request->unfixPackage($loadedPackage);
-                unset($this->packages[$i]);
-                unset($this->aliasMap[spl_object_hash($loadedPackage)]);
+        foreach ($request->getLockedRepository()->getPackages() as $lockedPackage) {
+            if (!($lockedPackage instanceof AliasPackage) && $lockedPackage->getName() === $name) {
+                if (false !== $index = array_search($lockedPackage, $this->packages, true)) {
+                    $request->unfixPackage($lockedPackage);
+                    unset($this->packages[$index]);
+                    if (isset($this->aliasMap[spl_object_hash($lockedPackage)])) {
+                        foreach ($this->aliasMap[spl_object_hash($lockedPackage)] as $aliasIndex => $aliasPackage) {
+                            $request->unfixPackage($aliasPackage);
+                            unset($this->packages[$aliasIndex]);
+                        }
+                        unset($this->aliasMap[spl_object_hash($lockedPackage)]);
+                    }
+                }
             }
         }
 

+ 72 - 12
tests/Composer/Test/Fixtures/installer/update-allow-list-with-dependencies-alias.test

@@ -7,33 +7,52 @@ Require a new package in the composer.json and updating with its name as an argu
             "type": "package",
             "package": [
                 { "name": "current/pkg", "version": "1.0.0", "require": { "current/dep": "<1.2.0" } },
-                { "name": "current/pkg", "version": "1.1.0", "require": { "current/dep": "^1.0" } },
+                { "name": "current/dep", "version": "dev-master", "extra": {"branch-alias": {"dev-master": "1.0.x-dev"}}},
                 { "name": "current/dep", "version": "1.0.0" },
-                { "name": "current/dep", "version": "1.1.0" },
+                { "name": "current/dep", "version": "1.1.0", "require": {"current/dep2": "*"} },
                 { "name": "current/dep", "version": "1.2.0" },
-                { "name": "new/pkg", "version": "1.0.0", "require": { "current/dep": "^1.1" } },
+                { "name": "current/dep2", "version": "dev-master", "extra": {"branch-alias": {"dev-master": "1.0.x-dev"}}},
+                { "name": "new/pkg", "version": "1.0.0", "require": { "current/dep": "^1.1", "current/dep2": "*"} },
                 { "name": "new/pkg", "version": "1.1.0", "require": { "current/dep": "^1.2" } }
             ]
         }
     ],
     "require": {
-        "current/pkg": "1.*",
+        "current/dep": "dev-master as 1.1.0",
+        "current/dep2": "dev-master as 1.1.0",
+        "current/pkg": "1.0.0 as 2.0.0",
         "new/pkg": "1.*"
-    }
+    },
+    "minimum-stability": "dev"
 }
 --INSTALLED--
 [
-    { "name": "current/pkg", "version": "1.0.0", "require": { "current/dep": "<1.2.0" } },
-    { "name": "current/dep", "version": "1.0.0" }
+    { "name": "current/dep", "version": "dev-master", "extra": {"branch-alias": {"dev-master": "1.0.x-dev"}}},
+    { "name": "current/dep2", "version": "dev-master", "extra": {"branch-alias": {"dev-master": "1.0.x-dev"}}},
+    { "name": "current/pkg", "version": "1.0.0", "require": { "current/dep": "<1.2.0" } }
 ]
 --LOCK--
 {
     "packages": [
-        { "name": "current/pkg", "version": "1.0.0", "require": { "current/dep": "<1.2.0" } },
-        { "name": "current/dep", "version": "1.0.0" }
+        { "name": "current/dep", "version": "dev-master", "extra": {"branch-alias": {"dev-master": "1.0.x-dev"}}, "type": "library"},
+        { "name": "current/dep2", "version": "dev-master", "extra": {"branch-alias": {"dev-master": "1.0.x-dev"}}, "type": "library"},
+        { "name": "current/pkg", "version": "1.0.0", "require": { "current/dep": "<1.2.0" } }
     ],
     "packages-dev": [],
-    "aliases": [],
+    "aliases": [
+        {
+            "alias": "1.1.0",
+            "alias_normalized": "1.1.0.0",
+            "version": "dev-master",
+            "package": "current/dep"
+        },
+        {
+            "alias": "1.1.0",
+            "alias_normalized": "1.1.0.0",
+            "version": "dev-master",
+            "package": "current/dep2"
+        }
+    ],
     "minimum-stability": "dev",
     "stability-flags": [],
     "prefer-stable": false,
@@ -42,7 +61,48 @@ Require a new package in the composer.json and updating with its name as an argu
     "platform-dev": []
 }
 --RUN--
-update new/pkg --with-dependencies
+update new/pkg --with-all-dependencies
+--EXPECT-LOCK--
+{
+    "packages": [
+        { "name": "current/dep", "version": "dev-master", "extra": {"branch-alias": {"dev-master": "1.0.x-dev"}}, "type": "library"},
+        { "name": "current/dep2", "version": "dev-master", "extra": {"branch-alias": {"dev-master": "1.0.x-dev"}}, "type": "library"},
+        { "name": "current/pkg", "version": "1.0.0", "require": { "current/dep": "<1.2.0" }, "type": "library"},
+        { "name": "new/pkg", "version": "1.0.0", "require": { "current/dep": "^1.1", "current/dep2": "*"}, "type": "library"}
+    ],
+    "packages-dev": [],
+    "aliases": [
+        {
+            "alias": "1.1.0",
+            "alias_normalized": "1.1.0.0",
+            "version": "dev-master",
+            "package": "current/dep"
+        },
+        {
+            "alias": "1.1.0",
+            "alias_normalized": "1.1.0.0",
+            "version": "dev-master",
+            "package": "current/dep2"
+        },
+        {
+            "alias": "2.0.0",
+            "alias_normalized": "2.0.0.0",
+            "version": "1.0.0.0",
+            "package": "current/pkg"
+        }
+    ],
+    "minimum-stability": "dev",
+    "stability-flags": {
+        "current/dep": 20,
+        "current/dep2": 20
+    },
+    "prefer-stable": false,
+    "prefer-lowest": false,
+    "platform": [],
+    "platform-dev": []
+}
 --EXPECT--
-Upgrading current/dep (1.0.0 => 1.1.0)
+Marking current/dep (1.1.0) as installed, alias of current/dep (dev-master)
+Marking current/pkg (2.0.0) as installed, alias of current/pkg (1.0.0)
+Marking current/dep2 (1.1.0) as installed, alias of current/dep2 (dev-master)
 Installing new/pkg (1.0.0)