Fix issue loading aliases and fix markPackageNameForLoading when called twice in a row for same package it would overwrite the constraint the second time
parent
b7f1550896
commit
4b9b499ce5
|
@ -85,6 +85,8 @@ class PoolBuilder
|
||||||
*/
|
*/
|
||||||
private $updateAllowWarned = array();
|
private $updateAllowWarned = array();
|
||||||
|
|
||||||
|
private $indexCounter = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int[] $acceptableStabilities array of stability => BasePackage::STABILITY_* value
|
* @param int[] $acceptableStabilities array of stability => BasePackage::STABILITY_* value
|
||||||
* @psalm-param array<string, int> $acceptableStabilities
|
* @psalm-param array<string, int> $acceptableStabilities
|
||||||
|
@ -154,7 +156,7 @@ class PoolBuilder
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->markPackageNameForLoading($packageName, $constraint);
|
$this->markPackageNameForLoading($request, $packageName, $constraint);
|
||||||
}
|
}
|
||||||
|
|
||||||
// clean up packagesToLoad for anything we manually marked loaded above
|
// clean up packagesToLoad for anything we manually marked loaded above
|
||||||
|
@ -216,19 +218,28 @@ class PoolBuilder
|
||||||
$this->loadedPackages = array();
|
$this->loadedPackages = array();
|
||||||
$this->packages = array();
|
$this->packages = array();
|
||||||
$this->unacceptableFixedPackages = array();
|
$this->unacceptableFixedPackages = array();
|
||||||
|
$this->indexCounter = 0;
|
||||||
|
|
||||||
return $pool;
|
return $pool;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function markPackageNameForLoading($name, ConstraintInterface $constraint)
|
private function markPackageNameForLoading(Request $request, $name, ConstraintInterface $constraint)
|
||||||
{
|
{
|
||||||
// Maybe it was already marked before but not loaded yet. In that case
|
// Maybe it was already marked before but not loaded yet. In that case
|
||||||
// we have to extend the constraint (we don't check if they match because
|
// we have to extend the constraint (we don't check if they match because
|
||||||
// MultiConstraint::create() will optimize anyway)
|
// MultiConstraint::create() will optimize anyway)
|
||||||
if (isset($this->packagesToLoad[$name]) && !Intervals::isSubsetOf($constraint, $this->packagesToLoad[$name])) {
|
if (isset($this->packagesToLoad[$name])) {
|
||||||
|
// Already marked for loading and this does not expand the constraint to be loaded, nothing to do
|
||||||
|
if (Intervals::isSubsetOf($constraint, $this->packagesToLoad[$name])) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// extend the constraint to be loaded
|
||||||
$constraint = MultiConstraint::create(array($this->packagesToLoad[$name], $constraint), false);
|
$constraint = MultiConstraint::create(array($this->packagesToLoad[$name], $constraint), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Not yet loaded or already marked for a reload, override the existing constraint
|
||||||
|
// (either it's a new one to load, or it has already been extended above)
|
||||||
if (!isset($this->loadedPackages[$name])) {
|
if (!isset($this->loadedPackages[$name])) {
|
||||||
$this->packagesToLoad[$name] = $constraint;
|
$this->packagesToLoad[$name] = $constraint;
|
||||||
return;
|
return;
|
||||||
|
@ -245,18 +256,18 @@ class PoolBuilder
|
||||||
// yet so we get the required package versions
|
// yet so we get the required package versions
|
||||||
$this->packagesToLoad[$name] = MultiConstraint::create(array($this->loadedPackages[$name], $constraint), false);
|
$this->packagesToLoad[$name] = MultiConstraint::create(array($this->loadedPackages[$name], $constraint), false);
|
||||||
unset($this->loadedPackages[$name]);
|
unset($this->loadedPackages[$name]);
|
||||||
|
|
||||||
// remove all already-loaded packages matching those to be loaded to avoid duplicates
|
|
||||||
foreach ($this->packages as $index => $pkg) {
|
|
||||||
if ($pkg->getName() === $name) {
|
|
||||||
unset($this->packages[$index]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function loadPackagesMarkedForLoading(Request $request, $repositories)
|
private function loadPackagesMarkedForLoading(Request $request, $repositories)
|
||||||
{
|
{
|
||||||
foreach ($this->packagesToLoad as $name => $constraint) {
|
foreach ($this->packagesToLoad as $name => $constraint) {
|
||||||
|
// remove all already-loaded packages matching those to be loaded to avoid duplicates
|
||||||
|
foreach ($this->packages as $index => $pkg) {
|
||||||
|
if ($pkg->getName() === $name) {
|
||||||
|
$this->removeLoadedPackage($request, $pkg, $index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$this->loadedPackages[$name] = $constraint;
|
$this->loadedPackages[$name] = $constraint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,9 +298,8 @@ class PoolBuilder
|
||||||
|
|
||||||
private function loadPackage(Request $request, PackageInterface $package, $propagateUpdate = true)
|
private function loadPackage(Request $request, PackageInterface $package, $propagateUpdate = true)
|
||||||
{
|
{
|
||||||
end($this->packages);
|
$index = $this->indexCounter++;
|
||||||
$index = key($this->packages) + 1;
|
$this->packages[$index] = $package;
|
||||||
$this->packages[] = $package;
|
|
||||||
|
|
||||||
if ($package instanceof AliasPackage) {
|
if ($package instanceof AliasPackage) {
|
||||||
$this->aliasMap[spl_object_hash($package->getAliasOf())][$index] = $package;
|
$this->aliasMap[spl_object_hash($package->getAliasOf())][$index] = $package;
|
||||||
|
@ -319,8 +329,9 @@ class PoolBuilder
|
||||||
$aliasPackage = new AliasPackage($basePackage, $alias['alias_normalized'], $alias['alias']);
|
$aliasPackage = new AliasPackage($basePackage, $alias['alias_normalized'], $alias['alias']);
|
||||||
$aliasPackage->setRootPackageAlias(true);
|
$aliasPackage->setRootPackageAlias(true);
|
||||||
|
|
||||||
$this->packages[] = $aliasPackage;
|
$newIndex = $this->indexCounter++;
|
||||||
$this->aliasMap[spl_object_hash($aliasPackage->getAliasOf())][$index+1] = $aliasPackage;
|
$this->packages[$newIndex] = $aliasPackage;
|
||||||
|
$this->aliasMap[spl_object_hash($aliasPackage->getAliasOf())][$newIndex] = $aliasPackage;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($package->getRequires() as $link) {
|
foreach ($package->getRequires() as $link) {
|
||||||
|
@ -333,19 +344,19 @@ class PoolBuilder
|
||||||
if ($request->getUpdateAllowTransitiveDependencies() && isset($this->skippedLoad[$require])) {
|
if ($request->getUpdateAllowTransitiveDependencies() && isset($this->skippedLoad[$require])) {
|
||||||
if ($request->getUpdateAllowTransitiveRootDependencies() || !$this->isRootRequire($request, $this->skippedLoad[$require])) {
|
if ($request->getUpdateAllowTransitiveRootDependencies() || !$this->isRootRequire($request, $this->skippedLoad[$require])) {
|
||||||
$this->unfixPackage($request, $require);
|
$this->unfixPackage($request, $require);
|
||||||
$this->markPackageNameForLoading($require, $linkConstraint);
|
$this->markPackageNameForLoading($request, $require, $linkConstraint);
|
||||||
} elseif (!$request->getUpdateAllowTransitiveRootDependencies() && $this->isRootRequire($request, $require) && !isset($this->updateAllowWarned[$require])) {
|
} elseif (!$request->getUpdateAllowTransitiveRootDependencies() && $this->isRootRequire($request, $require) && !isset($this->updateAllowWarned[$require])) {
|
||||||
$this->updateAllowWarned[$require] = true;
|
$this->updateAllowWarned[$require] = true;
|
||||||
$this->io->writeError('<warning>Dependency "'.$require.'" is also a root requirement. Package has not been listed as an update argument, so keeping locked at old version. Use --with-all-dependencies to include root dependencies.</warning>');
|
$this->io->writeError('<warning>Dependency "'.$require.'" is also a root requirement. Package has not been listed as an update argument, so keeping locked at old version. Use --with-all-dependencies to include root dependencies.</warning>');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$this->markPackageNameForLoading($require, $linkConstraint);
|
$this->markPackageNameForLoading($request, $require, $linkConstraint);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// We also need to load the requirements of a fixed package
|
// We also need to load the requirements of a fixed package
|
||||||
// unless it was skipped
|
// unless it was skipped
|
||||||
if (!isset($this->skippedLoad[$require])) {
|
if (!isset($this->skippedLoad[$require])) {
|
||||||
$this->markPackageNameForLoading($require, $linkConstraint);
|
$this->markPackageNameForLoading($request, $require, $linkConstraint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -358,7 +369,7 @@ class PoolBuilder
|
||||||
if (isset($this->loadedPackages[$replace]) && isset($this->skippedLoad[$replace])) {
|
if (isset($this->loadedPackages[$replace]) && isset($this->skippedLoad[$replace])) {
|
||||||
if ($request->getUpdateAllowTransitiveRootDependencies() || !$this->isRootRequire($request, $this->skippedLoad[$replace])) {
|
if ($request->getUpdateAllowTransitiveRootDependencies() || !$this->isRootRequire($request, $this->skippedLoad[$replace])) {
|
||||||
$this->unfixPackage($request, $replace);
|
$this->unfixPackage($request, $replace);
|
||||||
$this->markPackageNameForLoading($replace, $link->getConstraint());
|
$this->markPackageNameForLoading($request, $replace, $link->getConstraint());
|
||||||
} elseif (!$request->getUpdateAllowTransitiveRootDependencies() && $this->isRootRequire($request, $replace) && !isset($this->updateAllowWarned[$replace])) {
|
} elseif (!$request->getUpdateAllowTransitiveRootDependencies() && $this->isRootRequire($request, $replace) && !isset($this->updateAllowWarned[$replace])) {
|
||||||
$this->updateAllowWarned[$replace] = true;
|
$this->updateAllowWarned[$replace] = true;
|
||||||
$this->io->writeError('<warning>Dependency "'.$replace.'" is also a root requirement. Package has not been listed as an update argument, so keeping locked at old version. Use --with-all-dependencies to include root dependencies.</warning>');
|
$this->io->writeError('<warning>Dependency "'.$replace.'" is also a root requirement. Package has not been listed as an update argument, so keeping locked at old version. Use --with-all-dependencies to include root dependencies.</warning>');
|
||||||
|
@ -430,14 +441,7 @@ class PoolBuilder
|
||||||
if (!($lockedPackage instanceof AliasPackage) && $lockedPackage->getName() === $name) {
|
if (!($lockedPackage instanceof AliasPackage) && $lockedPackage->getName() === $name) {
|
||||||
if (false !== $index = array_search($lockedPackage, $this->packages, true)) {
|
if (false !== $index = array_search($lockedPackage, $this->packages, true)) {
|
||||||
$request->unfixPackage($lockedPackage);
|
$request->unfixPackage($lockedPackage);
|
||||||
unset($this->packages[$index]);
|
$this->removeLoadedPackage($request, $lockedPackage, $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)]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -455,6 +459,18 @@ class PoolBuilder
|
||||||
unset($this->loadedPackages[$name]);
|
unset($this->loadedPackages[$name]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function removeLoadedPackage(Request $request, PackageInterface $package, $index)
|
||||||
|
{
|
||||||
|
unset($this->packages[$index]);
|
||||||
|
if (isset($this->aliasMap[spl_object_hash($package)])) {
|
||||||
|
foreach ($this->aliasMap[spl_object_hash($package)] as $aliasIndex => $aliasPackage) {
|
||||||
|
$request->unfixPackage($aliasPackage);
|
||||||
|
unset($this->packages[$aliasIndex]);
|
||||||
|
}
|
||||||
|
unset($this->aliasMap[spl_object_hash($package)]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private function getRootAliasesPerPackage(array $aliases)
|
private function getRootAliasesPerPackage(array $aliases)
|
||||||
{
|
{
|
||||||
$normalizedAliases = array();
|
$normalizedAliases = array();
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
--TEST--
|
||||||
|
Check root aliases are loaded
|
||||||
|
|
||||||
|
--ROOT--
|
||||||
|
{
|
||||||
|
"minimum-stability": "dev",
|
||||||
|
"aliases": [
|
||||||
|
{
|
||||||
|
"package": "req/pkg",
|
||||||
|
"version": "dev-feature-foo",
|
||||||
|
"alias": "dev-master"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
--REQUEST--
|
||||||
|
{
|
||||||
|
"require": {
|
||||||
|
"package/a": "dev-master",
|
||||||
|
"req/pkg": "dev-feature-foo"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
--FIXED--
|
||||||
|
[
|
||||||
|
]
|
||||||
|
|
||||||
|
--PACKAGES--
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "req/pkg", "version": "dev-feature-foo",
|
||||||
|
"source": { "reference": "feat.f", "type": "git", "url": "" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "req/pkg", "version": "dev-master",
|
||||||
|
"extra": { "branch-alias": { "dev-master": "1.0.x-dev" } },
|
||||||
|
"source": { "reference": "forked", "type": "git", "url": "" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "req/pkg", "version": "dev-master",
|
||||||
|
"extra": { "branch-alias": { "dev-master": "1.0.x-dev" } },
|
||||||
|
"source": { "reference": "master", "type": "git", "url": "" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "package/a", "version": "dev-master",
|
||||||
|
"require": { "req/pkg": "dev-master" }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
--EXPECT--
|
||||||
|
[
|
||||||
|
"package/a-dev-master",
|
||||||
|
"package/a-9999999-dev (alias of dev-master)",
|
||||||
|
"req/pkg-dev-feature-foo#feat.f",
|
||||||
|
"req/pkg-dev-master#feat.f (alias of dev-feature-foo)",
|
||||||
|
"req/pkg-dev-master#forked",
|
||||||
|
"req/pkg-dev-master#master",
|
||||||
|
"req/pkg-1.0.9999999.9999999-dev#forked (alias of dev-master)",
|
||||||
|
"req/pkg-1.0.9999999.9999999-dev#master (alias of dev-master)"
|
||||||
|
]
|
|
@ -0,0 +1,57 @@
|
||||||
|
--TEST--
|
||||||
|
Check root aliases get selected correctly
|
||||||
|
|
||||||
|
--ROOT--
|
||||||
|
{
|
||||||
|
"stability-flags": {
|
||||||
|
"a/aliased": "dev"
|
||||||
|
},
|
||||||
|
"aliases": [
|
||||||
|
{
|
||||||
|
"package": "a/aliased",
|
||||||
|
"version": "dev-master",
|
||||||
|
"alias": "1.0.0"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"references": {
|
||||||
|
"a/aliased": "abcd"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
--REQUEST--
|
||||||
|
{
|
||||||
|
"require": {
|
||||||
|
"a/aliased": "dev-master",
|
||||||
|
"b/requirer": "*"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
--FIXED--
|
||||||
|
[
|
||||||
|
]
|
||||||
|
|
||||||
|
--PACKAGES--
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "a/aliased", "version": "dev-master",
|
||||||
|
"source": { "reference": "orig", "type": "git", "url": "" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "a/aliased", "version": "1.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "b/requirer", "version": "1.0.0",
|
||||||
|
"require": { "a/aliased": "1.0.0" },
|
||||||
|
"source": { "reference": "1.0.0", "type": "git", "url": "" }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
--EXPECT--
|
||||||
|
[
|
||||||
|
"b/requirer-1.0.0.0#1.0.0",
|
||||||
|
"a/aliased-dev-master#abcd",
|
||||||
|
"a/aliased-1.0.0.0#abcd (alias of dev-master)",
|
||||||
|
"a/aliased-1.0.0.0#abcd",
|
||||||
|
"a/aliased-9999999-dev#abcd (alias of dev-master)"
|
||||||
|
]
|
|
@ -42,5 +42,5 @@ Stability flags apply
|
||||||
4,
|
4,
|
||||||
5,
|
5,
|
||||||
6,
|
6,
|
||||||
"default/pkg-1.2.0.0 alias of 6"
|
"default/pkg-1.2.0.0 (alias of 6)"
|
||||||
]
|
]
|
||||||
|
|
|
@ -41,6 +41,7 @@ class PoolBuilderTest extends TestCase
|
||||||
$rootAliases = !empty($root['aliases']) ? $root['aliases'] : array();
|
$rootAliases = !empty($root['aliases']) ? $root['aliases'] : array();
|
||||||
$minimumStability = !empty($root['minimum-stability']) ? $root['minimum-stability'] : 'stable';
|
$minimumStability = !empty($root['minimum-stability']) ? $root['minimum-stability'] : 'stable';
|
||||||
$stabilityFlags = !empty($root['stability-flags']) ? $root['stability-flags'] : array();
|
$stabilityFlags = !empty($root['stability-flags']) ? $root['stability-flags'] : array();
|
||||||
|
$rootReferences = !empty($root['references']) ? $root['references'] : array();
|
||||||
$stabilityFlags = array_map(function ($stability) {
|
$stabilityFlags = array_map(function ($stability) {
|
||||||
return BasePackage::$stabilities[$stability];
|
return BasePackage::$stabilities[$stability];
|
||||||
}, $stabilityFlags);
|
}, $stabilityFlags);
|
||||||
|
@ -71,7 +72,7 @@ class PoolBuilderTest extends TestCase
|
||||||
return $pkg;
|
return $pkg;
|
||||||
};
|
};
|
||||||
|
|
||||||
$repositorySet = new RepositorySet($minimumStability, $stabilityFlags, $rootAliases);
|
$repositorySet = new RepositorySet($minimumStability, $stabilityFlags, $rootAliases, $rootReferences);
|
||||||
$repositorySet->addRepository($repo = new ArrayRepository());
|
$repositorySet->addRepository($repo = new ArrayRepository());
|
||||||
$repositorySet->addRepository($lockedRepo = new LockArrayRepository());
|
$repositorySet->addRepository($lockedRepo = new LockArrayRepository());
|
||||||
foreach ($packages as $package) {
|
foreach ($packages as $package) {
|
||||||
|
@ -114,15 +115,22 @@ class PoolBuilderTest extends TestCase
|
||||||
}
|
}
|
||||||
|
|
||||||
$suffix = '';
|
$suffix = '';
|
||||||
|
if ($package->getSourceReference()) {
|
||||||
|
$suffix = '#'.$package->getSourceReference();
|
||||||
|
}
|
||||||
if ($package->getRepository() instanceof LockArrayRepository) {
|
if ($package->getRepository() instanceof LockArrayRepository) {
|
||||||
$suffix = ' (locked)';
|
$suffix .= ' (locked)';
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($package instanceof AliasPackage && $id = array_search($package->getAliasOf(), $packageIds, true)) {
|
if ($package instanceof AliasPackage) {
|
||||||
return (string) $package->getName().'-'.$package->getVersion() .' alias of '.$id . $suffix;
|
if ($id = array_search($package->getAliasOf(), $packageIds, true)) {
|
||||||
|
return (string) $package->getName().'-'.$package->getVersion() . $suffix . ' (alias of '.$id . ')';
|
||||||
|
}
|
||||||
|
|
||||||
|
return (string) $package->getName().'-'.$package->getVersion() . $suffix . ' (alias of '.$package->getAliasOf()->getVersion().')';
|
||||||
}
|
}
|
||||||
|
|
||||||
return (string) $package . $suffix;
|
return (string) $package->getName().'-'.$package->getVersion() . $suffix;
|
||||||
}, $result);
|
}, $result);
|
||||||
|
|
||||||
$this->assertSame($expect, $result);
|
$this->assertSame($expect, $result);
|
||||||
|
|
Loading…
Reference in New Issue