Skip to content

Commit c3920ba

Browse files
committed
596: update usages of InstalledPiePackages to ensure appropriate filtering of multiple packages
1 parent 3cbdb73 commit c3920ba

7 files changed

Lines changed: 54 additions & 27 deletions

File tree

src/Command/InstallExtensionsForProjectCommand.php

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -162,13 +162,18 @@ public function execute(InputInterface $input, OutputInterface $output): int
162162

163163
array_walk(
164164
$extensionsRequired,
165-
function (Link $link) use ($pieComposer, $phpEnabledExtensions, $installedPiePackages, $input, &$anyErrorsHappened): void {
165+
function (Link $link) use ($pieComposer, $phpEnabledExtensions, $installedPiePackages, $input, &$anyErrorsHappened, $targetPlatform): void {
166166
$extension = ExtensionName::normaliseFromString($link->getTarget());
167167
$linkRequiresConstraint = $link->getPrettyConstraint();
168168

169+
$piePackagesForExtension = $installedPiePackages
170+
->findByPhpFormattedExtensionName($extension->phpFormattedExtensionName())
171+
->onlyVerifiedFor($targetPlatform);
172+
169173
$piePackageVersion = null;
170-
if (in_array($extension->name(), array_keys($installedPiePackages))) {
171-
$piePackageVersion = $installedPiePackages[$extension->name()]->version();
174+
175+
if (count($piePackagesForExtension) === 1) {
176+
$piePackageVersion = $piePackagesForExtension->onlyOne()->version();
172177
}
173178

174179
$piePackageVersionMatchesLinkConstraint = null;

src/Command/UninstallCommand.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ private function findPiePackageByPackageName(string $packageToRemove, Composer $
109109
{
110110
$piePackages = $this->installedPiePackages->allPiePackages($composer);
111111

112-
foreach ($piePackages as $piePackage) {
112+
foreach ($piePackages->packages() as $piePackage) {
113113
if ($piePackage->name() === $packageToRemove) {
114114
return $piePackage;
115115
}

src/ComposerIntegration/PhpBinaryPathBasedPlatformRepository.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public function __construct(PhpBinaryPath $phpBinaryPath, Composer $composer, In
4444

4545
$piePackages = $installedPiePackages->allPiePackages($composer);
4646
$extensionsBeingReplacedByPiePackages = [];
47-
foreach ($piePackages as $piePackage) {
47+
foreach ($piePackages->packages() as $piePackage) {
4848
foreach ($piePackage->composerPackage()->getReplaces() as $replaceLink) {
4949
$target = $replaceLink->getTarget();
5050
if (

src/Platform/PiePackageList.php

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,12 @@
77
use Countable;
88
use OutOfRangeException;
99
use Php\Pie\DependencyResolver\Package;
10+
use Php\Pie\Util\PackageVerificationStatus;
11+
use Webmozart\Assert\Assert;
1012

13+
use function array_filter;
14+
use function array_key_first;
15+
use function array_values;
1116
use function count;
1217

1318
/** @internal This is not public API for PIE, so should not be depended upon unless you accept the risk of BC breaks */
@@ -20,16 +25,10 @@ public function __construct(private readonly array $piePackages)
2025

2126
public function findByPhpFormattedExtensionName(string $phpFormattedExtensionName): PiePackageList
2227
{
23-
$matched = [];
24-
foreach ($this->piePackages as $piePackage) {
25-
if ($piePackage->extensionName()->phpFormattedExtensionName() !== $phpFormattedExtensionName) {
26-
continue;
27-
}
28-
29-
$matched[] = $piePackage;
30-
}
31-
32-
return new self($matched);
28+
return new self(array_values(array_filter(
29+
$this->piePackages,
30+
static fn (Package $piePackage) => $piePackage->extensionName()->phpFormattedExtensionName() === $phpFormattedExtensionName,
31+
)));
3332
}
3433

3534
public function findByPackageName(string $packageName): Package
@@ -43,6 +42,21 @@ public function findByPackageName(string $packageName): Package
4342
throw new OutOfRangeException('Package ' . $packageName . ' not in the list');
4443
}
4544

45+
public function onlyVerifiedFor(TargetPlatform $targetPlatform): self
46+
{
47+
return new self(array_values(array_filter(
48+
$this->piePackages,
49+
static fn (Package $piePackage) => $piePackage->verifyPackageStatus($targetPlatform) === PackageVerificationStatus::Verified,
50+
)));
51+
}
52+
53+
public function onlyOne(): Package
54+
{
55+
Assert::count($this->piePackages, 1);
56+
57+
return $this->piePackages[array_key_first($this->piePackages)];
58+
}
59+
4660
/** @return list<Package> */
4761
public function packages(): array
4862
{

test/integration/Command/InstallExtensionsForProjectCommandTest.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
use Php\Pie\Installing\InstallForPhpProject\InstallPiePackageFromPath;
2727
use Php\Pie\Installing\InstallForPhpProject\InstallSelectedPackage;
2828
use Php\Pie\Platform\InstalledPiePackages;
29+
use Php\Pie\Platform\PiePackageList;
2930
use PHPUnit\Framework\Attributes\CoversClass;
3031
use PHPUnit\Framework\MockObject\MockObject;
3132
use PHPUnit\Framework\TestCase;
@@ -135,6 +136,8 @@ public function testInstallingExtensionsForPhpProject(): void
135136
)
136137
->willReturn(0);
137138

139+
$this->installedPiePackages->method('allPiePackages')->willReturn(new PiePackageList([]));
140+
138141
$this->commandTester->execute(
139142
['--allow-non-interactive-project-install' => true],
140143
['verbosity' => BufferedOutput::VERBOSITY_VERY_VERBOSE],
@@ -182,6 +185,8 @@ public function testInstallingExtensionsForPhpProjectWithMultipleMatches(): void
182185
$this->installSelectedPackage->expects(self::never())
183186
->method('withSubCommand');
184187

188+
$this->installedPiePackages->method('allPiePackages')->willReturn(new PiePackageList([]));
189+
185190
$this->commandTester->execute(
186191
['--allow-non-interactive-project-install' => true],
187192
['verbosity' => BufferedOutput::VERBOSITY_VERY_VERBOSE],

test/unit/ComposerIntegration/PhpBinaryPathBasedPlatformRepositoryTest.php

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Php\Pie\DependencyResolver\Package;
1515
use Php\Pie\ExtensionName;
1616
use Php\Pie\Platform\InstalledPiePackages;
17+
use Php\Pie\Platform\PiePackageList;
1718
use Php\Pie\Platform\TargetPhp\PhpBinaryPath;
1819
use Php\Pie\Util\Process;
1920
use PHPUnit\Framework\Attributes\CoversClass;
@@ -35,7 +36,7 @@ public function testPlatformRepositoryContainsExpectedPacakges(): void
3536
$composer = $this->createMock(Composer::class);
3637

3738
$installedPiePackages = $this->createMock(InstalledPiePackages::class);
38-
$installedPiePackages->method('allPiePackages')->willReturn([]);
39+
$installedPiePackages->method('allPiePackages')->willReturn(new PiePackageList([]));
3940

4041
$phpBinaryPath = $this->createMock(PhpBinaryPath::class);
4142
$phpBinaryPath->expects(self::once())
@@ -75,7 +76,7 @@ public function testPlatformRepositoryExcludesExtensionBeingInstalled(): void
7576
$composer = $this->createMock(Composer::class);
7677

7778
$installedPiePackages = $this->createMock(InstalledPiePackages::class);
78-
$installedPiePackages->method('allPiePackages')->willReturn([]);
79+
$installedPiePackages->method('allPiePackages')->willReturn(new PiePackageList([]));
7980

8081
$extensionBeingInstalled = ExtensionName::normaliseFromString('extension_being_installed');
8182

@@ -116,9 +117,9 @@ public function testPlatformRepositoryExcludesReplacedExtensions(): void
116117
'ext-replaced_extension' => new Link('myvendor/replaced_extension', 'ext-replaced_extension', new Constraint('==', '*')),
117118
]);
118119
$installedPiePackages = $this->createMock(InstalledPiePackages::class);
119-
$installedPiePackages->method('allPiePackages')->willReturn([
120+
$installedPiePackages->method('allPiePackages')->willReturn(new PiePackageList([
120121
Package::fromComposerCompletePackage($composerPackage),
121-
]);
122+
]));
122123

123124
$extensionBeingInstalled = ExtensionName::normaliseFromString('extension_being_installed');
124125

@@ -216,14 +217,17 @@ public function testLibrariesAreIncluded(string $packageName): void
216217
self::markTestSkipped('pkg-config not available on Windows');
217218
}
218219

220+
$installedPiePackages = $this->createMock(InstalledPiePackages::class);
221+
$installedPiePackages->method('allPiePackages')->willReturn(new PiePackageList([]));
222+
219223
self::assertTrue(in_array(
220224
'lib-' . $packageName,
221225
array_map(
222226
static fn (PackageInterface $package): string => $package->getName(),
223227
(new PhpBinaryPathBasedPlatformRepository(
224228
PhpBinaryPath::fromCurrentProcess(),
225229
$this->createMock(Composer::class),
226-
$this->createMock(InstalledPiePackages::class),
230+
$installedPiePackages,
227231
ExtensionName::normaliseFromString('extension_being_installed'),
228232
))->getPackages(),
229233
),

test/unit/Platform/InstalledPiePackagesTest.php

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,14 @@ public function testAllPiePackages(): void
2929
$composer = $this->createMock(Composer::class);
3030
$composer->method('getRepositoryManager')->willReturn($repoManager);
3131

32-
$packages = (new InstalledPiePackages())->allPiePackages($composer);
32+
$packages = (new InstalledPiePackages())->allPiePackages($composer)->packages();
3333

34-
self::assertArrayHasKey('bar1', $packages);
35-
self::assertArrayHasKey('bar2', $packages);
34+
self::assertCount(2, $packages);
3635

37-
self::assertSame('bar1', $packages['bar1']->extensionName()->name());
38-
self::assertSame('foo/bar1', $packages['bar1']->name());
39-
self::assertSame('bar2', $packages['bar2']->extensionName()->name());
40-
self::assertSame('foo/bar2', $packages['bar2']->name());
36+
self::assertSame('bar1', $packages[0]->extensionName()->name());
37+
self::assertSame('foo/bar1', $packages[0]->name());
38+
self::assertSame('bar2', $packages[1]->extensionName()->name());
39+
self::assertSame('foo/bar2', $packages[1]->name());
4140
}
4241

4342
public function testInvalidExtensionNamesAreFilteredOut(): void

0 commit comments

Comments
 (0)