Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions src/PackageFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ class PackageFilter
private $downloader;
private $io;
private $ignorePreleases;
private $notifiedRestriction = false;
private $warnedPackages = [];

public function __construct(IOInterface $io, string $symfonyRequire, Downloader $downloader, bool $ignorePreleases = false)
{
Expand Down Expand Up @@ -91,13 +93,25 @@ public function removeLegacyPackages(array $data, RootPackageInterface $rootPack
if ('symfony/symfony' !== $name && (
array_intersect($versions, $lockedVersions[$name] ?? [])
|| (($knownVersions ??= $this->getVersions()) && !isset($knownVersions['splits'][$name]))
|| (isset($rootConstraints[$name]) && !Intervals::haveIntersections($this->symfonyConstraints, $rootConstraints[$name]))
|| ('symfony/psr-http-message-bridge' === $name && 6.4 > $versions[0])
)) {
$filteredPackages[] = $package;
continue;
}

if ('symfony/symfony' !== $name && isset($rootConstraints[$name]) && !Intervals::haveIntersections($this->symfonyConstraints, $rootConstraints[$name])) {
// the root constraint wins when it has no intersection with the
// "symfony/*" one, e.g. to allow requiring a dev version; be
// loud about it as this also triggers when the root constraint
// simply misses the versions the user asked for
if (null !== $this->io && !isset($this->warnedPackages[$name])) {
$this->warnedPackages[$name] = true;
$this->io->writeError(\sprintf('<warning>Version constraint "%s" for "%s" has no intersection with "%s", keeping the package unrestricted</>', $rootConstraints[$name]->getPrettyString(), $name, $this->symfonyRequire));
}
$filteredPackages[] = $package;
continue;
}

if (null !== $alias = $package->getExtra()['branch-alias'][$package->getVersion()] ?? null) {
$versions[] = $this->versionParser->normalize($alias);
}
Expand All @@ -112,9 +126,9 @@ public function removeLegacyPackages(array $data, RootPackageInterface $rootPack

if ('symfony/symfony' === $name) {
$symfonyPackages[] = $package;
} elseif (null !== $this->io) {
} elseif (null !== $this->io && !$this->notifiedRestriction) {
$this->notifiedRestriction = true;
$this->io->writeError(\sprintf('<info>Restricting packages listed in "symfony/symfony" to "%s"</>', $this->symfonyRequire));
$this->io = null;
}
}

Expand Down
28 changes: 28 additions & 0 deletions tests/PackageFilterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace Symfony\Flex\Tests;

use Composer\IO\BufferIO;
use Composer\IO\NullIO;
use Composer\Package\CompletePackage;
use Composer\Package\Link;
Expand Down Expand Up @@ -209,6 +210,33 @@ public static function provideRemoveLegacyPackages()
]]];
}

public function testRootConstraintWithoutIntersectionIsPreservedButWarnedAbout()
{
$io = new BufferIO();
$downloader = $this->createStub(Downloader::class);
$downloader
->method('getVersions')
->willReturn(['splits' => ['symfony/bar' => ['2.8', '3.0']]]);
$filter = new PackageFilter($io, '~2.8', $downloader);

$l = new ArrayLoader();
$packages = [];
foreach (['2.8.0', '3.0.0'] as $version) {
$packages[] = $l->load(['name' => 'symfony/bar', 'version' => $version], CompletePackage::class);
}

$rootPackage = new RootPackage('test/test', '1.0.0.0', '1.0');
$rootPackage->setRequires([
'symfony/bar' => new Link('__root__', 'symfony/bar', new Constraint('>=', '3.0.0.0'), Link::TYPE_REQUIRE, '>=3.0'),
]);

$this->assertSame($packages, $filter->removeLegacyPackages($packages, $rootPackage, []));

$output = $io->getOutput();
$this->assertStringContainsString('Version constraint ">= 3.0.0.0" for "symfony/bar" has no intersection with "~2.8", keeping the package unrestricted', $output);
$this->assertSame(1, substr_count($output, 'no intersection'), 'the warning should be emitted once per package, not once per version');
}

public function testIgnorePreleases()
{
$io = new NullIO();
Expand Down
Loading