Skip to content

Commit c94b08f

Browse files
Merge pull request #44 from youwe-petervanderwal/feat/only-run-installer-on-require-update
feat: only run the Testing Suite installer on actual composer require/update
2 parents 4838379 + c6d8af3 commit c94b08f

File tree

4 files changed

+104
-29
lines changed

4 files changed

+104
-29
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3232
- Updated remote schema location URL for phpmd rulesets to prevent redirecting which may cause flaky builds.
3333
- Bumped phpro/grumphp-shim dependency from v1 to v2
3434
- Bumped youwe/composer-dependency-installer from v1 to v2
35+
- Testing Suite files are only installed in the project when the package itself is installed and/or updated, for example
36+
when running `composer require youwe/testing-suite`, `composer update [youwe/testing-suite]` or `composer install`
37+
when the package was not installed (yet/anymore).
3538

3639
### Removed
3740
- Removed support for EOL PHP versions. Projects running PHP < 8.1 can stick to version 2 of the testing-suite.

phpmd.xml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,13 @@
44
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
55
xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 https://pmd.sourceforge.io/ruleset_xml_schema.xsd">
66
<description>PHPMD</description>
7-
<rule ref="./config/default/phpmd.xml" />
7+
<rule ref="./config/default/phpmd.xml">
8+
<exclude name="ShortVariable"/>
9+
</rule>
10+
11+
<rule ref="rulesets/naming.xml/ShortVariable">
12+
<properties>
13+
<property name="exceptions" value="io" />
14+
</properties>
15+
</rule>
816
</ruleset>

src/Plugin.php

Lines changed: 39 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,12 @@
1010
namespace Youwe\TestingSuite\Composer;
1111

1212
use Composer\Composer;
13+
use Composer\DependencyResolver\Operation;
1314
use Composer\EventDispatcher\EventSubscriberInterface;
15+
use Composer\Installer\PackageEvent;
1416
use Composer\IO\IOInterface;
1517
use Composer\Plugin\PluginInterface;
18+
use UnexpectedValueException;
1619
use Youwe\TestingSuite\Composer\Installer\InstallerInterface;
1720

1821
/**
@@ -21,8 +24,23 @@
2124
*/
2225
class Plugin implements PluginInterface, EventSubscriberInterface
2326
{
27+
public const PACKAGE_NAME = 'youwe/testing-suite';
28+
2429
/** @var InstallerInterface[] */
25-
private $installers;
30+
private array $installers;
31+
32+
/**
33+
* Subscribe to post update and post install command.
34+
*
35+
* @return array
36+
*/
37+
public static function getSubscribedEvents(): array
38+
{
39+
return [
40+
'post-package-install' => [ 'onPackageChange' ],
41+
'post-package-update' => [ 'onPackageChange' ],
42+
];
43+
}
2644

2745
/**
2846
* Constructor.
@@ -42,7 +60,7 @@ public function __construct(InstallerInterface ...$installers)
4260
*
4361
* @return void
4462
*/
45-
public function activate(Composer $composer, IOInterface $io)
63+
public function activate(Composer $composer, IOInterface $io): void
4664
{
4765
$this->addInstallers(
4866
...include __DIR__ . '/installers.php',
@@ -57,7 +75,7 @@ public function activate(Composer $composer, IOInterface $io)
5775
*
5876
* @return void
5977
*/
60-
public function deactivate(Composer $composer, IOInterface $io)
78+
public function deactivate(Composer $composer, IOInterface $io): void
6179
{
6280
}
6381

@@ -69,7 +87,7 @@ public function deactivate(Composer $composer, IOInterface $io)
6987
*
7088
* @return void
7189
*/
72-
public function uninstall(Composer $composer, IOInterface $io)
90+
public function uninstall(Composer $composer, IOInterface $io): void
7391
{
7492
}
7593

@@ -80,37 +98,34 @@ public function uninstall(Composer $composer, IOInterface $io)
8098
*
8199
* @return void
82100
*/
83-
public function addInstallers(InstallerInterface ...$installers)
101+
public function addInstallers(InstallerInterface ...$installers): void
84102
{
85103
$this->installers = array_merge($this->installers, $installers);
86104
}
87105

88106
/**
89-
* Run the installers.
107+
* Run the installers when this package has been installed/updated
90108
*
109+
* @param PackageEvent $event
91110
* @return void
92111
*/
93-
public function install()
112+
public function onPackageChange(PackageEvent $event): void
94113
{
114+
$operation = $event->getOperation();
115+
116+
$packageName = match (true) {
117+
$operation instanceof Operation\InstallOperation => $operation->getPackage()->getName(),
118+
$operation instanceof Operation\UpdateOperation => $operation->getTargetPackage()->getName(),
119+
default => throw new UnexpectedValueException('Unexpected operation type: ' . $operation::class),
120+
};
121+
122+
if ($packageName !== self::PACKAGE_NAME) {
123+
return;
124+
}
125+
126+
$event->getIO()->write('<info>Running Youwe Testing Suite installer</info>');
95127
foreach ($this->installers as $installer) {
96128
$installer->install();
97129
}
98130
}
99-
100-
/**
101-
* Subscribe to post update and post install command.
102-
*
103-
* @return array
104-
*/
105-
public static function getSubscribedEvents(): array
106-
{
107-
return [
108-
'post-install-cmd' => [
109-
'install',
110-
],
111-
'post-update-cmd' => [
112-
'install',
113-
],
114-
];
115-
}
116131
}

tests/PluginTest.php

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,12 @@
1010
namespace Youwe\TestingSuite\Composer\Tests;
1111

1212
use Composer\Composer;
13+
use Composer\DependencyResolver\Operation;
14+
use Composer\Installer\PackageEvent;
1315
use Composer\IO\IOInterface;
16+
use Composer\Package\PackageInterface;
1417
use PHPUnit\Framework\Attributes\CoversMethod;
18+
use PHPUnit\Framework\Attributes\TestWith;
1519
use PHPUnit\Framework\MockObject\Exception;
1620
use PHPUnit\Framework\TestCase;
1721
use ReflectionProperty;
@@ -49,21 +53,66 @@ public function testActivate(): void
4953
/**
5054
* @throws Exception
5155
*/
52-
public function testInstall(): void
53-
{
56+
#[TestWith(
57+
data: [Operation\InstallOperation::class, 'getPackage', 'youwe/testing-suite', true],
58+
name: 'It runs installers when installing Testing Suite',
59+
)]
60+
#[TestWith(
61+
data: [Operation\UpdateOperation::class, 'getTargetPackage', 'youwe/testing-suite', true],
62+
name: 'It runs installers when updating Testing Suite',
63+
)]
64+
#[TestWith(
65+
data: [Operation\InstallOperation::class, 'getPackage', 'youwe/coding-standard-phpstorm', false],
66+
name: 'It doesn\'t run installers when installing something else',
67+
)]
68+
#[TestWith(
69+
data: [Operation\UpdateOperation::class, 'getTargetPackage', 'youwe/coding-standard-phpstorm', false],
70+
name: 'It doesn\'t run installers when updating something else',
71+
)]
72+
public function testOnPackageChange(
73+
string $operationClass,
74+
string $packageGetter,
75+
string $packageName,
76+
bool $itRunsInstallers,
77+
): void {
5478
$installers = [
5579
$this->createMock(InstallerInterface::class),
5680
$this->createMock(InstallerInterface::class)
5781
];
5882

5983
foreach ($installers as $installer) {
6084
$installer
61-
->expects(self::once())
85+
->expects($itRunsInstallers ? self::once() : self::never())
6286
->method('install');
6387
}
6488

6589
$plugin = new Plugin(...$installers);
66-
$plugin->install();
90+
91+
$package = $this->createMock(PackageInterface::class);
92+
$package->expects(self::once())
93+
->method('getName')
94+
->willReturn($packageName);
95+
96+
$operation = $this->createMock($operationClass);
97+
$operation->expects(self::once())
98+
->method($packageGetter)
99+
->willReturn($package);
100+
101+
$event = $this->createMock(PackageEvent::class);
102+
$event->expects(self::once())
103+
->method('getOperation')
104+
->willReturn($operation);
105+
106+
$io = $this->createMock(IOInterface::class);
107+
$io->expects($itRunsInstallers ? self::once() : self::never())
108+
->method('write')
109+
->with('<info>Running Youwe Testing Suite installer</info>');
110+
111+
$event->expects(self::any())
112+
->method('getIO')
113+
->willReturn($io);
114+
115+
$plugin->onPackageChange($event);
67116
}
68117

69118
public function testGetSubscribesEvents(): void

0 commit comments

Comments
 (0)