Skip to content

Commit 7b88e76

Browse files
committed
bug #412 Don't filter packages that have empty intersection with symfony/symfony when matching extra.symfony.require (nicolas-grekas)
This PR was merged into the 1.1-dev branch. Discussion ---------- Don't filter packages that have empty intersection with symfony/symfony when matching extra.symfony.require Fixes #410 ping @pamil, please confirm. Commits ------- 9edfd10 Don't filter packages that have empty intersection with symfony/symfony when matching extra.symfony.require
2 parents 9fb60f2 + 9edfd10 commit 7b88e76

File tree

3 files changed

+179
-17
lines changed

3 files changed

+179
-17
lines changed

phpunit.xml.dist

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,10 @@
2020
<php>
2121
<ini name="error_reporting" value="-1" />
2222
</php>
23+
24+
<filter>
25+
<whitelist>
26+
<directory>./src/</directory>
27+
</whitelist>
28+
</filter>
2329
</phpunit>

src/Cache.php

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class Cache extends BaseCache
2626
private $symfonyConstraints;
2727
private $io;
2828

29-
public function setSymfonyRequire(string $symfonyRequire, IOInterface $io)
29+
public function setSymfonyRequire(string $symfonyRequire, IOInterface $io = null)
3030
{
3131
$this->versionParser = new VersionParser();
3232
$this->symfonyRequire = $symfonyRequire;
@@ -50,24 +50,49 @@ public function removeLegacyTags(array $data): array
5050
if (!$this->symfonyConstraints || !isset($data['packages']['symfony/symfony'])) {
5151
return $data;
5252
}
53-
$symfonyVersions = $data['packages']['symfony/symfony'];
5453

55-
foreach ($data['packages'] as $name => $versions) {
56-
foreach ($versions as $version => $package) {
57-
if ('symfony/symfony' !== $name && 'self.version' !== ($symfonyVersions[preg_replace('/^(\d++\.\d++)\..*/', '$1.x-dev', $version)]['replace'][$name] ?? null)) {
58-
continue;
59-
}
60-
$normalizedVersion = $package['extra']['branch-alias'][$version] ?? null;
61-
$normalizedVersion = $normalizedVersion ? $this->versionParser->normalize($normalizedVersion) : $package['version_normalized'];
62-
$provider = new Constraint('==', $normalizedVersion);
63-
64-
if (!$this->symfonyConstraints->matches($provider)) {
65-
if ($this->io) {
66-
$this->io->writeError(sprintf('<info>Restricting packages listed in "symfony/symfony" to "%s"</info>', $this->symfonyRequire));
67-
$this->io = null;
68-
}
69-
unset($data['packages'][$name][$version]);
54+
$symfonyPackages = [];
55+
$symfonySymfony = $data['packages']['symfony/symfony'];
56+
57+
foreach ($symfonySymfony as $version => $composerJson) {
58+
if ('dev-master' === $version) {
59+
$normalizedVersion = $this->versionParser->normalize($composerJson['extra']['branch-alias']['dev-master']);
60+
} else {
61+
$normalizedVersion = $composerJson['version_normalized'];
62+
}
63+
64+
if ($this->symfonyConstraints->matches(new Constraint('==', $normalizedVersion))) {
65+
$symfonyPackages += $composerJson['replace'];
66+
} else {
67+
if ($this->io) {
68+
$this->io->writeError(sprintf('<info>Restricting packages listed in "symfony/symfony" to "%s"</info>', $this->symfonyRequire));
69+
$this->io = null;
7070
}
71+
unset($symfonySymfony[$version]);
72+
}
73+
}
74+
75+
if (!$symfonySymfony) {
76+
// ignore requirements: their intersection with versions of symfony/symfony is empty
77+
return $data;
78+
}
79+
80+
$data['packages']['symfony/symfony'] = $symfonySymfony;
81+
unset($symfonySymfony['dev-master']);
82+
83+
foreach ($data['packages'] as $name => $versions) {
84+
if (!isset($symfonyPackages[$name]) || null === $devMasterAlias = $versions['dev-master']['extra']['branch-alias']['dev-master'] ?? null) {
85+
continue;
86+
}
87+
$devMaster = $versions['dev-master'];
88+
$versions = array_intersect_key($versions, $symfonySymfony);
89+
90+
if ($this->symfonyConstraints->matches(new Constraint('==', $this->versionParser->normalize($devMasterAlias)))) {
91+
$versions['dev-master'] = $devMaster;
92+
}
93+
94+
if ($versions) {
95+
$data['packages'][$name] = $versions;
7196
}
7297
}
7398

tests/CacheTest.php

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Flex\Tests;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Flex\Cache;
16+
17+
class CacheTest extends TestCase
18+
{
19+
/**
20+
* @dataProvider provideRemoveLegacyTags
21+
*/
22+
public function testRemoveLegacyTags(array $expected, array $packages, string $symfonyRequire)
23+
{
24+
$cache = (new \ReflectionClass(Cache::class))->newInstanceWithoutConstructor();
25+
$cache->setSymfonyRequire($symfonyRequire);
26+
27+
$this->assertSame(['packages' => $expected], $cache->removeLegacyTags(['packages' => $packages]));
28+
}
29+
30+
public function provideRemoveLegacyTags()
31+
{
32+
yield 'no-symfony/symfony' => [[123], [123], '~1'];
33+
34+
$branchAlias = function ($versionAlias) {
35+
return [
36+
'extra' => [
37+
'branch-alias' => [
38+
'dev-master' => $versionAlias.'-dev',
39+
],
40+
],
41+
];
42+
};
43+
44+
$packages = [
45+
'foo/unrelated' => [
46+
'1.0.0' => [],
47+
],
48+
'symfony/symfony' => [
49+
'3.3.0' => [
50+
'version_normalized' => '3.3.0.0',
51+
'replace' => ['symfony/foo' => 'self.version'],
52+
],
53+
'3.4.0' => [
54+
'version_normalized' => '3.4.0.0',
55+
'replace' => ['symfony/foo' => 'self.version'],
56+
],
57+
'dev-master' => $branchAlias('3.5') + [
58+
'replace' => ['symfony/foo' => 'self.version'],
59+
],
60+
],
61+
'symfony/foo' => [
62+
'3.3.0' => ['version_normalized' => '3.3.0.0'],
63+
'3.4.0' => ['version_normalized' => '3.4.0.0'],
64+
'dev-master' => $branchAlias('3.5'),
65+
],
66+
];
67+
68+
yield 'empty-intersection-ignores' => [$packages, $packages, '~2.0'];
69+
yield 'empty-intersection-ignores' => [$packages, $packages, '~4.0'];
70+
71+
$expected = $packages;
72+
unset($expected['symfony/symfony']['3.3.0']);
73+
unset($expected['symfony/foo']['3.3.0']);
74+
75+
yield 'non-empty-intersection-filters' => [$expected, $packages, '~3.4'];
76+
77+
unset($expected['symfony/symfony']['3.4.0']);
78+
unset($expected['symfony/foo']['3.4.0']);
79+
80+
yield 'master-only' => [$expected, $packages, '~3.5'];
81+
82+
$packages = [
83+
'symfony/symfony' => [
84+
'2.8.0' => [
85+
'version_normalized' => '2.8.0.0',
86+
'replace' => [
87+
'symfony/legacy' => 'self.version',
88+
'symfony/foo' => 'self.version',
89+
],
90+
],
91+
],
92+
'symfony/legacy' => [
93+
'2.8.0' => ['version_normalized' => '2.8.0.0'],
94+
'dev-master' => $branchAlias('2.8'),
95+
],
96+
];
97+
98+
yield 'legacy-are-not-filtered' => [$packages, $packages, '~3.0'];
99+
100+
$packages = [
101+
'symfony/symfony' => [
102+
'2.8.0' => [
103+
'version_normalized' => '2.8.0.0',
104+
'replace' => [
105+
'symfony/foo' => 'self.version',
106+
'symfony/new' => 'self.version',
107+
],
108+
],
109+
'dev-master' => $branchAlias('3.0') + [
110+
'replace' => [
111+
'symfony/foo' => 'self.version',
112+
'symfony/new' => 'self.version',
113+
],
114+
],
115+
],
116+
'symfony/foo' => [
117+
'2.8.0' => ['version_normalized' => '2.8.0.0'],
118+
'dev-master' => $branchAlias('3.0'),
119+
],
120+
'symfony/new' => [
121+
'dev-master' => $branchAlias('3.0'),
122+
],
123+
];
124+
125+
$expected = $packages;
126+
unset($expected['symfony/symfony']['dev-master']);
127+
unset($expected['symfony/foo']['dev-master']);
128+
129+
yield 'master-is-filtered-only-when-in-range' => [$expected, $packages, '~2.8'];
130+
}
131+
}

0 commit comments

Comments
 (0)