Skip to content

Commit

Permalink
Merge pull request #211 from cweagans/patch-value-object
Browse files Browse the repository at this point in the history
Add a patch value object + support a more verbose patch format
  • Loading branch information
cweagans committed May 17, 2018
2 parents a65d47a + bfb1424 commit 810f6d4
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 14 deletions.
41 changes: 41 additions & 0 deletions src/Patch.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

namespace cweagans\Composer;

class Patch
{
/**
* The package that the patch belongs to.
*
* @var string $package
*/
public $package;

/**
* The description of what the patch does.
*
* @var string $description
*/
public $description;

/**
* The URL where the patch is stored. Can be local.
*
* @var string $url
*/
public $url;

/**
* The sha1 hash of the patch file.
*
* @var string $sha1
*/
public $sha1;

/**
* The patch depth to use when applying the patch (-p flag for `patch`)
*
* @var int $depth
*/
public $depth;
}
62 changes: 48 additions & 14 deletions src/Plugin/Patches.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
use cweagans\Composer\PatchEvent;
use cweagans\Composer\PatchEvents;
use cweagans\Composer\ConfigurablePlugin;
use cweagans\Composer\Patch;

class Patches implements PluginInterface, EventSubscriberInterface
{
Expand Down Expand Up @@ -241,7 +242,7 @@ public function gatherPatches(PackageEvent $event)

// Merge installed patches from dependencies that did not receive an update.
foreach ($this->installedPatches as $patches) {
$this->patches = Util::arrayMergeRecursiveDistinct($this->patches, $patches);
// $this->patches = Util::arrayMergeRecursiveDistinct($this->patches, $patches);
}

// If we're in verbose mode, list the projects we're going to patch.
Expand All @@ -265,11 +266,11 @@ public function gatherPatches(PackageEvent $event)
public function grabPatches()
{
// First, try to get the patches from the root composer.json.
$patches = [];
$extra = $this->composer->getPackage()->getExtra();
if (isset($extra['patches'])) {
$this->io->write('<info>Gathering patches for root package.</info>');
$patches = $extra['patches'];
return $patches;
} // If it's not specified there, look for a patches-file definition.
elseif ($this->getConfig('patches-file') != '') {
$this->io->write('<info>Gathering patches from patch file.</info>');
Expand Down Expand Up @@ -301,13 +302,45 @@ public function grabPatches()
}
if (isset($patches['patches'])) {
$patches = $patches['patches'];
return $patches;
} elseif (!$patches) {
throw new \Exception('There was an error in the supplied patch file');
}
} else {
return array();
}

// Now that we have a populated $patches list, populate patch objects for everything.
foreach ($patches as $package => $patch_defs) {
if (isset($patch_defs[0]) && is_array($patch_defs[0])) {
$this->io->write("<info>Using expanded definition format for package {$package}</info>");

foreach ($patch_defs as $index => $def) {
$patch = new Patch();
$patch->package = $package;
$patch->url = $def["url"];
$patch->description = $def["description"];

$patches[$package][$index] = $patch;
}
} else {
$this->io->write("<info>Using compact definition format for package {$package}</info>");

$temporary_patch_list = [];

foreach ($patch_defs as $description => $url) {
$patch = new Patch();
$patch->package = $package;
$patch->url = $url;
$patch->description = $description;

$temporary_patch_list[] = $patch;
}

$patches[$package] = $temporary_patch_list;
}
}

return $patches;
}

/**
Expand Down Expand Up @@ -343,31 +376,32 @@ public function postInstall(PackageEvent $event)
$extra = $localPackage->getExtra();
$extra['patches_applied'] = array();

foreach ($this->patches[$package_name] as $description => $url) {
$this->io->write(' <info>' . $url . '</info> (<comment>' . $description . '</comment>)');
foreach ($this->patches[$package_name] as $index => $patch) {
/** @var Patch $patch */
$this->io->write(' <info>' . $patch->url . '</info> (<comment>' . $patch->description . '</comment>)');
try {
$this->eventDispatcher->dispatch(
null,
new PatchEvent(PatchEvents::PRE_PATCH_APPLY, $package, $url, $description)
new PatchEvent(PatchEvents::PRE_PATCH_APPLY, $package, $patch->url, $patch->description)
);
$this->getAndApplyPatch($downloader, $install_path, $url);
$this->getAndApplyPatch($downloader, $install_path, $patch->url);
$this->eventDispatcher->dispatch(
null,
new PatchEvent(PatchEvents::POST_PATCH_APPLY, $package, $url, $description)
new PatchEvent(PatchEvents::POST_PATCH_APPLY, $package, $patch->url, $patch->description)
);
$extra['patches_applied'][$description] = $url;
$extra['patches_applied'][$patch->description] = $patch->url;
} catch (\Exception $e) {
$this->io->write(
' <error>Could not apply patch! Skipping. The error was: ' .
$e->getMessage() .
'</error>'
);
if ($this->getConfig('exit-on-patch-failure')) {
throw new \Exception("Cannot apply patch $description ($url)!");
throw new \Exception("Cannot apply patch $patch->description ($patch->url)!");
}
}
}
$localPackage->setExtra($extra);
// $localPackage->setExtra($extra);

$this->io->write('');
$this->writePatchReport($this->patches[$package_name], $install_path);
Expand Down Expand Up @@ -518,9 +552,9 @@ protected function writePatchReport($patches, $directory)
$output = "This file was automatically generated by Composer Patches";
$output .= " (https://github.com/cweagans/composer-patches)\n";
$output .= "Patches applied to this directory:\n\n";
foreach ($patches as $description => $url) {
$output .= $description . "\n";
$output .= 'Source: ' . $url . "\n\n\n";
foreach ($patches as $index => $patch) {
$output .= $patch->description . "\n";
$output .= 'Source: ' . $patch->url . "\n\n\n";
}
file_put_contents($directory . "/PATCHES.txt", $output);
}
Expand Down
6 changes: 6 additions & 0 deletions tests/acceptance/ExpandedDefinitionRequiredOnlyCept.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?php
$I = new AcceptanceTester($scenario);
$I->wantTo('apply a patch to a package using the expanded definition format (required props only');
$I->amInPath(realpath(__DIR__ . '/fixtures/expanded-definition-required-only'));
$I->runShellCommand('composer install');
$I->canSeeFileFound('./vendor/drupal/drupal/.ht.router.php');
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"name": "cweagans/composer-patches-test-project",
"description": "Project for use in cweagans/composer-patches acceptance tests.",
"type": "project",
"license": "BSD-2-Clause",
"repositories": [
{
"type": "path",
"url": "../composer-patches"
}
],
"require": {
"cweagans/composer-patches": "*@dev",
"drupal/drupal": "~8.2"
},
"extra": {
"patches": {
"drupal/drupal": [
{
"description": "Add a startup config for the PHP web server",
"url": "https://www.drupal.org/files/issues/add_a_startup-1543858-58.patch"
}
]
}
}
}

0 comments on commit 810f6d4

Please sign in to comment.