Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add composer and io to all events + emit event before throwing exception when patch does not apply #470

Merged
merged 8 commits into from
Feb 12, 2023
2 changes: 1 addition & 1 deletion src/Downloader.php
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ protected function getDownloaders(): array
}


$event = new PluginEvent(PluginEvents::POST_DISCOVER_DOWNLOADERS, $downloaders);
$event = new PluginEvent(PluginEvents::POST_DISCOVER_DOWNLOADERS, $downloaders, $this->composer, $this->io);
$this->composer->getEventDispatcher()->dispatch(PluginEvents::POST_DISCOVER_DOWNLOADERS, $event);
$downloaders = $event->getCapabilities();

Expand Down
61 changes: 58 additions & 3 deletions src/Event/PatchEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@

namespace cweagans\Composer\Event;

use Composer\Composer;
use Composer\EventDispatcher\Event;
use Composer\Package\PackageInterface;
use Composer\IO\IOInterface;
use cweagans\Composer\Patch;
use Exception;

class PatchEvent extends Event
{
Expand All @@ -18,16 +20,39 @@ class PatchEvent extends Event
*/
protected Patch $patch;

/**
* @var Composer $composer
*/
protected Composer $composer;

/**
* @var IOInterface $io
*/
protected IOInterface $io;

/**
* @var ?Exception $error
*/
protected ?Exception $error;

/**
* Constructs a PatchEvent object.
*
* @param string $eventName
* @param Patch $patch
*/
public function __construct(string $eventName, Patch $patch)
{
public function __construct(
string $eventName,
Patch $patch,
Composer $composer,
IOInterface $io,
?Exception $error = null
) {
parent::__construct($eventName);
$this->patch = $patch;
$this->composer = $composer;
$this->io = $io;
$this->error = $error;
}

/**
Expand All @@ -39,4 +64,34 @@ public function getPatch(): Patch
{
return $this->patch;
}

/**
* Returns the Composer object.
*
* @return Composer
*/
public function getComposer(): Composer
{
return $this->composer;
}

/**
* Returns the IOInterface.
*
* @return IOInterface
*/
public function getIO(): IOInterface
{
return $this->io;
}

/**
* Returns the exception about to be thrown when a patch cannot be applied.
*
* @return Exception
*/
public function getError(): ?Exception
{
return $this->error;
}
}
10 changes: 10 additions & 0 deletions src/Event/PatchEvents.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,14 @@ class PatchEvents
* @var string
*/
public const POST_PATCH_APPLY = 'post-patch-apply';


/**
* The POST_PATCH_APPLY_ERROR event occurs when a patch could not be applied by any patcher.
*
* The event listener method receives a cweagans\Composer\Event\PatchEvent instance.
*
* @var string
*/
public const POST_PATCH_APPLY_ERROR = 'post-patch-apply-error';
}
36 changes: 35 additions & 1 deletion src/Event/PluginEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

namespace cweagans\Composer\Event;

use Composer\Composer;
use Composer\EventDispatcher\Event;
use Composer\IO\IOInterface;

class PluginEvent extends Event
{
Expand All @@ -11,16 +13,28 @@ class PluginEvent extends Event
*/
protected array $capabilities;

/**
* @var Composer $composer
*/
protected Composer $composer;

/**
* @var IOInterface $io
*/
protected IOInterface $io;

/**
* Constructs a PluginEvent object.
*
* @param string $eventName
* @param array $capabilities
*/
public function __construct(string $eventName, array $capabilities)
public function __construct(string $eventName, array $capabilities, Composer $composer, IOInterface $io)
{
parent::__construct($eventName);
$this->capabilities = $capabilities;
$this->composer = $composer;
$this->io = $io;
}

/**
Expand All @@ -46,4 +60,24 @@ public function setCapabilities(array $capabilities): void
{
$this->capabilities = $capabilities;
}

/**
* Returns the Composer object.
*
* @return Composer
*/
public function getComposer(): Composer
{
return $this->composer;
}

/**
* Returns the IOInterface.
*
* @return IOInterface
*/
public function getIO(): IOInterface
{
return $this->io;
}
}
2 changes: 1 addition & 1 deletion src/Patcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ protected function getPatchers(): array
$patchers = array_merge($patchers, $newPatchers);
}

$event = new PluginEvent(PluginEvents::POST_DISCOVER_PATCHERS, $patchers);
$event = new PluginEvent(PluginEvents::POST_DISCOVER_PATCHERS, $patchers, $this->composer, $this->io);
$this->composer->getEventDispatcher()->dispatch(PluginEvents::POST_DISCOVER_PATCHERS, $event);
$patchers = $event->getCapabilities();

Expand Down
19 changes: 13 additions & 6 deletions src/Plugin/Patches.php
Original file line number Diff line number Diff line change
Expand Up @@ -224,18 +224,18 @@ public function download(Patch $patch)

$this->composer->getEventDispatcher()->dispatch(
PatchEvents::PRE_PATCH_DOWNLOAD,
new PatchEvent(PatchEvents::PRE_PATCH_DOWNLOAD, $patch)
new PatchEvent(PatchEvents::PRE_PATCH_DOWNLOAD, $patch, $this->composer, $this->io)
);
$downloader->downloadPatch($patch);
$this->composer->getEventDispatcher()->dispatch(
PatchEvents::POST_PATCH_DOWNLOAD,
new PatchEvent(PatchEvents::POST_PATCH_DOWNLOAD, $patch)
new PatchEvent(PatchEvents::POST_PATCH_DOWNLOAD, $patch, $this->composer, $this->io)
);
}

public function guessDepth(Patch $patch)
{
$event = new PatchEvent(PatchEvents::PRE_PATCH_GUESS_DEPTH, $patch);
$event = new PatchEvent(PatchEvents::PRE_PATCH_GUESS_DEPTH, $patch, $this->composer, $this->io);
$this->composer->getEventDispatcher()->dispatch(PatchEvents::PRE_PATCH_GUESS_DEPTH, $event);
$patch = $event->getPatch();

Expand All @@ -255,7 +255,7 @@ public function apply(Patch $patch, string $install_path)

$this->guessDepth($patch);

$event = new PatchEvent(PatchEvents::PRE_PATCH_APPLY, $patch);
$event = new PatchEvent(PatchEvents::PRE_PATCH_APPLY, $patch, $this->composer, $this->io);
$this->composer->getEventDispatcher()->dispatch(PatchEvents::PRE_PATCH_APPLY, $event);
$patch = $event->getPatch();

Expand All @@ -267,12 +267,19 @@ public function apply(Patch $patch, string $install_path)

$status = $patcher->applyPatch($patch, $install_path);
if ($status === false) {
throw new Exception("No available patcher was able to apply patch {$patch->url} to {$patch->package}");
$e = new Exception("No available patcher was able to apply patch {$patch->url} to {$patch->package}");

$this->composer->getEventDispatcher()->dispatch(
PatchEvents::POST_PATCH_APPLY_ERROR,
new PatchEvent(PatchEvents::POST_PATCH_APPLY_ERROR, $patch, $this->composer, $this->io, $e)
);

throw $e;
}

$this->composer->getEventDispatcher()->dispatch(
PatchEvents::POST_PATCH_APPLY,
new PatchEvent(PatchEvents::POST_PATCH_APPLY, $patch)
new PatchEvent(PatchEvents::POST_PATCH_APPLY, $patch, $this->composer, $this->io)
);
}

Expand Down
2 changes: 1 addition & 1 deletion src/Resolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ protected function getPatchResolvers(): array
$resolvers = array_merge($resolvers, $newResolvers);
}

$event = new PluginEvent(PluginEvents::POST_DISCOVER_RESOLVERS, $resolvers);
$event = new PluginEvent(PluginEvents::POST_DISCOVER_RESOLVERS, $resolvers, $this->composer, $this->io);
$this->composer->getEventDispatcher()->dispatch(PluginEvents::POST_DISCOVER_RESOLVERS, $event);
$resolvers = $event->getCapabilities();

Expand Down
29 changes: 29 additions & 0 deletions tests/_data/fixtures/patch-does-not-apply/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "cweagans/composer-patches-test-project",
"description": "Project for use in cweagans/composer-patches acceptance tests.",
"type": "project",
"license": "BSD-3-Clause",
"repositories": [
{
"type": "path",
"url": "../../../../"
}
],
"require": {
"cweagans/composer-patches": "*@dev",
"cweagans/composer-patches-testrepo": "~1.0"
},
"extra": {
"patches": {
"cweagans/composer-patches-testrepo": {
"Patch from a totally different project": "https://patch-diff.githubusercontent.com/raw/cweagans/awesome-diy-software/pull/4.patch"
}
}
},
"config": {
"preferred-install": "source",
"allow-plugins": {
"cweagans/composer-patches": true
}
}
}
14 changes: 14 additions & 0 deletions tests/acceptance/PatchDoesNotApplyCept.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

/**
* @var \Codeception\Scenario $scenario
*/

use cweagans\Composer\Tests\AcceptanceTester;

$I = new AcceptanceTester($scenario);
$I->wantTo('see an error when I try to apply a patch that does not apply');
$I->amInPath(codecept_data_dir('fixtures/patch-does-not-apply'));
$I->runComposerCommand('install', ['-vvv'], false);
$I->seeInComposerOutput("No available patcher was able to apply patch");
$I->seeInComposerOutput("Exception trace");
24 changes: 17 additions & 7 deletions tests/unit/PatchEventTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@
namespace cweagans\Composer\Tests\Unit;

use Codeception\Test\Unit;
use Composer\Composer;
use Composer\IO\NullIO;
use Composer\Package\Package;
use Composer\Package\PackageInterface;
use cweagans\Composer\Event\PatchEvent;
use cweagans\Composer\Event\PatchEvents;
use cweagans\Composer\Patch;
use Exception;

class PatchEventTest extends Unit
{
Expand All @@ -21,23 +24,30 @@ class PatchEventTest extends Unit
*
* @dataProvider patchEventDataProvider
*/
public function testGetters($event_name, $patch)
public function testGetters($event_name, $patch, $composer, $io, $error = null)
{
$patch_event = new PatchEvent($event_name, $patch);
$patch_event = new PatchEvent($event_name, $patch, $composer, $io, $error);
$this->assertEquals($event_name, $patch_event->getName());
$this->assertEquals($patch, $patch_event->getPatch());
$this->assertEquals($composer, $patch_event->getComposer());
$this->assertEquals($io, $patch_event->getIO());
$this->assertEquals($error, $patch_event->getError());
}

public function patchEventDataProvider()
{
$patch = new Patch();
$composer = new Composer();
$io = new NullIO();
$e = new Exception("test");

return array(
[PatchEvents::PRE_PATCH_GUESS_DEPTH, $patch],
[PatchEvents::PRE_PATCH_APPLY, $patch],
[PatchEvents::POST_PATCH_APPLY, $patch],
[PatchEvents::PRE_PATCH_DOWNLOAD, $patch],
[PatchEvents::POST_PATCH_DOWNLOAD, $patch],
[PatchEvents::PRE_PATCH_GUESS_DEPTH, $patch, $composer, $io],
[PatchEvents::PRE_PATCH_APPLY, $patch, $composer, $io],
[PatchEvents::POST_PATCH_APPLY, $patch, $composer, $io],
[PatchEvents::PRE_PATCH_DOWNLOAD, $patch, $composer, $io],
[PatchEvents::POST_PATCH_DOWNLOAD, $patch, $composer, $io],
[PatchEvents::POST_PATCH_APPLY_ERROR, $patch, $composer, $io, $e],
);
}
}
9 changes: 8 additions & 1 deletion tests/unit/PluginEventTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
namespace cweagans\Composer\Tests\Unit;

use Codeception\Test\Unit;
use Composer\Composer;
use Composer\IO\NullIO;
use cweagans\Composer\Event\PluginEvent;
use cweagans\Composer\Event\PluginEvents;

Expand All @@ -20,9 +22,14 @@ class PluginEventTest extends Unit
*/
public function testGetters($event_name, array $capabilities)
{
$plugin_event = new PluginEvent($event_name, $capabilities);
$composer = new Composer();
$io = new NullIO();

$plugin_event = new PluginEvent($event_name, $capabilities, $composer, $io);
$this->assertEquals($event_name, $plugin_event->getName());
$this->assertEquals($capabilities, $plugin_event->getCapabilities());
$this->assertEquals($composer, $plugin_event->getComposer());
$this->assertEquals($io, $plugin_event->getIO());

$plugin_event->setCapabilities(['something']);
$this->assertEquals(['something'], $plugin_event->getCapabilities());
Expand Down