Skip to content

Commit c455fb5

Browse files
committed
Merge pull request wikimedia#43 from bd808/issue/41
Better support for initial install of plugin
2 parents fa2079f + 59cfc46 commit c455fb5

File tree

5 files changed

+101
-21
lines changed

5 files changed

+101
-21
lines changed

example/composer.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@
99
"wikimedia/composer-merge-plugin": "*@dev"
1010
},
1111
"config": {
12-
"preferred-install": "source"
12+
"preferred-install": "source",
13+
"classmap-authoritative": true,
14+
"prepend-autoloader": false,
15+
"optimize-autoloader": true
1316
},
1417
"extra": {
1518
"merge-plugin": {

src/MergePlugin.php

Lines changed: 57 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
namespace Wikimedia\Composer;
1212

1313
use Composer\Composer;
14-
use Composer\Config;
14+
use Composer\DependencyResolver\Operation\InstallOperation;
1515
use Composer\EventDispatcher\EventSubscriberInterface;
1616
use Composer\Factory;
1717
use Composer\Installer;
@@ -115,10 +115,26 @@ class MergePlugin implements PluginInterface, EventSubscriberInterface
115115
protected $loadedFiles = array();
116116

117117
/**
118+
* Is this the first time that our plugin has been installed?
119+
*
118120
* @var bool $pluginFirstInstall
119121
*/
120122
protected $pluginFirstInstall;
121123

124+
/**
125+
* Is the autoloader file supposed to be written out?
126+
*
127+
* @var bool $dumpAutoloader
128+
*/
129+
protected $dumpAutoloader;
130+
131+
/**
132+
* Is the autoloader file supposed to be optimized?
133+
*
134+
* @var bool $optimizeAutoloader
135+
*/
136+
protected $optimizeAutoloader;
137+
122138
/**
123139
* {@inheritdoc}
124140
*/
@@ -136,23 +152,23 @@ public static function getSubscribedEvents()
136152
{
137153
return array(
138154
InstallerEvents::PRE_DEPENDENCIES_SOLVING => 'onDependencySolve',
139-
ScriptEvents::PRE_INSTALL_CMD => 'onInstallOrUpdate',
140-
ScriptEvents::PRE_UPDATE_CMD => 'onInstallOrUpdate',
141-
ScriptEvents::PRE_AUTOLOAD_DUMP => 'onInstallOrUpdate',
142155
PackageEvents::POST_PACKAGE_INSTALL => 'onPostPackageInstall',
143156
ScriptEvents::POST_INSTALL_CMD => 'onPostInstallOrUpdate',
144157
ScriptEvents::POST_UPDATE_CMD => 'onPostInstallOrUpdate',
158+
ScriptEvents::PRE_AUTOLOAD_DUMP => 'onInstallUpdateOrDump',
159+
ScriptEvents::PRE_INSTALL_CMD => 'onInstallUpdateOrDump',
160+
ScriptEvents::PRE_UPDATE_CMD => 'onInstallUpdateOrDump',
145161
);
146162
}
147163

148164
/**
149-
* Handle an event callback for an install or update command by checking
150-
* for "merge-patterns" in the "extra" data and merging package contents
151-
* if found.
165+
* Handle an event callback for an install, update or dump command by
166+
* checking for "merge-patterns" in the "extra" data and merging package
167+
* contents if found.
152168
*
153169
* @param Event $event
154170
*/
155-
public function onInstallOrUpdate(Event $event)
171+
public function onInstallUpdateOrDump(Event $event)
156172
{
157173
$config = $this->readConfig($this->getRootPackage());
158174
if (isset($config['recurse'])) {
@@ -167,6 +183,14 @@ public function onInstallOrUpdate(Event $event)
167183
$this->devMode = $event->isDevMode();
168184
$this->mergePackages($config);
169185
}
186+
187+
if ($event->getName() === ScriptEvents::PRE_AUTOLOAD_DUMP) {
188+
$this->dumpAutoloader = true;
189+
$flags = $event->getFlags();
190+
if (isset($flags['optimize'])) {
191+
$this->optimizeAutoloader = $flags['optimize'];
192+
}
193+
}
170194
}
171195

172196
/**
@@ -432,7 +456,14 @@ protected function mergeLinks(array $origin, array $merge, array &$dups)
432456
public function onDependencySolve(InstallerEvent $event)
433457
{
434458
if (empty($this->duplicateLinks)) {
459+
// @codeCoverageIgnoreStart
460+
// We shouldn't really ever be able to get here as this event is
461+
// triggered inside Composer\Installer and should have been
462+
// preceded by a pre-install or pre-update event but better to
463+
// have an unneeded check than to break with some future change in
464+
// the event system.
435465
return;
466+
// @codeCoverageIgnoreEnd
436467
}
437468

438469
$request = $event->getRequest();
@@ -456,10 +487,13 @@ public function onDependencySolve(InstallerEvent $event)
456487
*/
457488
public function onPostPackageInstall(PackageEvent $event)
458489
{
459-
$package = $event->getOperation()->getPackage()->getName();
460-
if ($package === self::PACKAGE_NAME) {
461-
$this->debug('composer-merge-plugin installed');
462-
$this->pluginFirstInstall = true;
490+
$op = $event->getOperation();
491+
if ($op instanceof InstallOperation) {
492+
$package = $op->getPackage()->getName();
493+
if ($package === self::PACKAGE_NAME) {
494+
$this->debug('composer-merge-plugin installed');
495+
$this->pluginFirstInstall = true;
496+
}
463497
}
464498
}
465499

@@ -490,19 +524,28 @@ public function onPostInstallOrUpdate(Event $event)
490524
'</comment>'
491525
);
492526

527+
$config = $this->composer->getConfig();
528+
529+
$preferSource = $config->get('preferred-install') == 'source';
530+
$preferDist = $config->get('preferred-install') == 'dist';
531+
493532
$installer = Installer::create(
494533
$event->getIO(),
495534
// Create a new Composer instance to ensure full processing of
496535
// the merged files.
497536
Factory::create($event->getIO(), null, false)
498537
);
499538

539+
$installer->setPreferSource($preferSource);
540+
$installer->setPreferDist($preferDist);
541+
$installer->setDevMode($event->isDevMode());
542+
$installer->setDumpAutoloader($this->dumpAutoloader);
543+
$installer->setOptimizeAutoloader($this->optimizeAutoloader);
544+
500545
// Force update mode so that new packages are processed rather
501546
// than just telling the user that composer.json and composer.lock
502547
// don't match.
503548
$installer->setUpdate(true);
504-
$installer->setDevMode($event->isDevMode());
505-
// TODO: can we set more flags to match the current run?
506549

507550
$installer->run();
508551
}

tests/phpunit/MergePluginTest.php

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@
1919
use Composer\Package\BasePackage;
2020
use Composer\Package\Package;
2121
use Composer\Package\RootPackage;
22-
use Composer\Script\CommandEvent;
22+
use Composer\Script\Event;
2323
use Composer\Script\ScriptEvents;
2424
use Prophecy\Argument;
25-
use \ReflectionMethod;
25+
use ReflectionMethod;
2626

2727
/**
2828
* @covers Wikimedia\Composer\MergePlugin
@@ -96,9 +96,17 @@ function ($args) use ($that) {
9696
}
9797
);
9898

99+
$root->getSuggests()->shouldBeCalled();
100+
$root->setSuggests(Argument::type('array'))->will(
101+
function ($args) use ($that) {
102+
$suggest = $args[0];
103+
$that->assertEquals(1, count($suggest));
104+
$that->assertArrayHasKey('ext-apc', $suggest);
105+
}
106+
);
107+
99108
$root->getDevRequires()->shouldNotBeCalled();
100109
$root->getRepositories()->shouldNotBeCalled();
101-
$root->getSuggests()->shouldNotBeCalled();
102110

103111
$extraInstalls = $this->triggerPlugin($root->reveal(), $dir);
104112

@@ -215,8 +223,9 @@ function ($args) use ($that) {
215223

216224
$extraInstalls = $this->triggerPlugin($root->reveal(), $dir);
217225

218-
$this->assertEquals(1, count($extraInstalls));
226+
$this->assertEquals(2, count($extraInstalls));
219227
$this->assertEquals('monolog/monolog', $extraInstalls[0][0]);
228+
$this->assertEquals('foo', $extraInstalls[1][0]);
220229
}
221230

222231
/**
@@ -434,15 +443,15 @@ protected function triggerPlugin($package, $directory)
434443
chdir($directory);
435444
$this->composer->getPackage()->willReturn($package);
436445

437-
$event = new CommandEvent(
446+
$event = new Event(
438447
ScriptEvents::PRE_INSTALL_CMD,
439448
$this->composer->reveal(),
440449
$this->io->reveal(),
441450
true, //dev mode
442451
array(),
443452
array()
444453
);
445-
$this->fixture->onInstallOrUpdate($event);
454+
$this->fixture->onInstallUpdateOrDump($event);
446455

447456
$requestInstalls = array();
448457
$request = $this->prophesize('Composer\DependencyResolver\Request');
@@ -465,6 +474,27 @@ function ($args) use (&$requestInstalls) {
465474
);
466475

467476
$this->fixture->onDependencySolve($event);
477+
478+
$event = new Event(
479+
ScriptEvents::PRE_AUTOLOAD_DUMP,
480+
$this->composer->reveal(),
481+
$this->io->reveal(),
482+
true, //dev mode
483+
array(),
484+
array( 'optimize' => true )
485+
);
486+
$this->fixture->onInstallUpdateOrDump($event);
487+
488+
$event = new Event(
489+
ScriptEvents::POST_INSTALL_CMD,
490+
$this->composer->reveal(),
491+
$this->io->reveal(),
492+
true, //dev mode
493+
array(),
494+
array()
495+
);
496+
$this->fixture->onPostInstallOrUpdate($event);
497+
468498
return $requestInstalls;
469499
}
470500

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
{
22
"require": {
33
"monolog/monolog": "~1.0"
4+
},
5+
"suggest": {
6+
"ext-apc": "caching is good"
47
}
58
}

tests/phpunit/fixtures/testOneMergeWithConflicts/composer.local.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"monolog/monolog": "1.10.0"
44
},
55
"require-dev": {
6+
"foo": "^1.0",
67
"xyzzy": "dev-master"
78
}
89
}

0 commit comments

Comments
 (0)