diff --git a/composer.json b/composer.json
index aa3b88b4..a26f4dba 100644
--- a/composer.json
+++ b/composer.json
@@ -14,7 +14,8 @@
],
"require": {
"php": ">=5.6.0",
- "composer-plugin-api": "^1.0"
+ "composer-plugin-api": "^1.0",
+ "cweagans/composer-configurable-plugin": "^1.0"
},
"require-dev": {
"composer/composer": "~1.0",
diff --git a/composer.lock b/composer.lock
index 84db7e0c..a4433904 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,8 +4,49 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
- "content-hash": "4083a703b8ed2ed7ff5cff34c8a226c6",
- "packages": [],
+ "content-hash": "22bc9b56528428a17f52fed1908da23c",
+ "packages": [
+ {
+ "name": "cweagans/composer-configurable-plugin",
+ "version": "1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/cweagans/composer-configurable-plugin.git",
+ "reference": "2df389bb1f13830fd95461d51f6eb52d02fc1c21"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/cweagans/composer-configurable-plugin/zipball/2df389bb1f13830fd95461d51f6eb52d02fc1c21",
+ "reference": "2df389bb1f13830fd95461d51f6eb52d02fc1c21",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.4.0"
+ },
+ "require-dev": {
+ "composer/composer": "~1.0",
+ "phpunit/phpunit": "~5.7"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "cweagans\\Composer\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-2-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Cameron Eagans",
+ "email": "me@cweagans.net"
+ }
+ ],
+ "description": "Provides a lightweight configuration system for Composer plugins.",
+ "time": "2017-05-25T04:32:06+00:00"
+ }
+ ],
"packages-dev": [
{
"name": "behat/gherkin",
diff --git a/src/Patches.php b/src/Patches.php
index 975f306e..985da43d 100644
--- a/src/Patches.php
+++ b/src/Patches.php
@@ -28,22 +28,28 @@
class Patches implements PluginInterface, EventSubscriberInterface
{
+ use ConfigurablePlugin;
+
/**
* @var Composer $composer
*/
protected $composer;
+
/**
* @var IOInterface $io
*/
protected $io;
+
/**
* @var EventDispatcher $eventDispatcher
*/
protected $eventDispatcher;
+
/**
* @var ProcessExecutor $executor
*/
protected $executor;
+
/**
* @var array $patches
*/
@@ -63,6 +69,34 @@ public function activate(Composer $composer, IOInterface $io)
$this->executor = new ProcessExecutor($this->io);
$this->patches = array();
$this->installedPatches = array();
+
+ $this->configuration = [
+ 'exit-on-patch-failure' => [
+ 'type' => 'bool',
+ 'default' => true,
+ ],
+ 'disable-patching' => [
+ 'type' => 'bool',
+ 'default' => false,
+ ],
+ 'disable-patching-from-dependencies' => [
+ 'type' => 'bool',
+ 'default' => false,
+ ],
+ 'disable-patch-reports' => [
+ 'type' => 'bool',
+ 'default' => false,
+ ],
+ 'patch-levels' => [
+ 'type' => 'list',
+ 'default' => ['-p1', '-p0', '-p2', '-p4']
+ ],
+ 'patches-file' => [
+ 'type' => 'string',
+ 'default' => '',
+ ]
+ ];
+ $this->configure($this->composer->getPackage()->getExtra(), 'composer-patches');
}
/**
@@ -172,28 +206,30 @@ public function gatherPatches(PackageEvent $event)
$patches_ignore = isset($extra['patches-ignore']) ? $extra['patches-ignore'] : array();
// Now add all the patches from dependencies that will be installed.
- $operations = $event->getOperations();
- $this->io->write('Gathering patches for dependencies. This might take a minute.');
- foreach ($operations as $operation) {
- if ($operation->getJobType() == 'install' || $operation->getJobType() == 'update') {
- $package = $this->getPackageFromOperation($operation);
- $extra = $package->getExtra();
- if (isset($extra['patches'])) {
- if (isset($patches_ignore[$package->getName()])) {
- foreach ($patches_ignore[$package->getName()] as $package_name => $patches) {
- if (isset($extra['patches'][$package_name])) {
- $extra['patches'][$package_name] = array_diff(
- $extra['patches'][$package_name],
- $patches
- );
+ if (!$this->getConfig('disable-patching-from-dependencies')) {
+ $operations = $event->getOperations();
+ $this->io->write('Gathering patches for dependencies. This might take a minute.');
+ foreach ($operations as $operation) {
+ if ($operation->getJobType() == 'install' || $operation->getJobType() == 'update') {
+ $package = $this->getPackageFromOperation($operation);
+ $extra = $package->getExtra();
+ if (isset($extra['patches'])) {
+ if (isset($patches_ignore[$package->getName()])) {
+ foreach ($patches_ignore[$package->getName()] as $package_name => $patches) {
+ if (isset($extra['patches'][$package_name])) {
+ $extra['patches'][$package_name] = array_diff(
+ $extra['patches'][$package_name],
+ $patches
+ );
+ }
}
}
+ $this->patches = $this->arrayMergeRecursiveDistinct($this->patches, $extra['patches']);
+ }
+ // Unset installed patches for this package
+ if (isset($this->installedPatches[$package->getName()])) {
+ unset($this->installedPatches[$package->getName()]);
}
- $this->patches = $this->arrayMergeRecursiveDistinct($this->patches, $extra['patches']);
- }
- // Unset installed patches for this package
- if (isset($this->installedPatches[$package->getName()])) {
- unset($this->installedPatches[$package->getName()]);
}
}
}
@@ -230,9 +266,9 @@ public function grabPatches()
$patches = $extra['patches'];
return $patches;
} // If it's not specified there, look for a patches-file definition.
- elseif (isset($extra['patches-file'])) {
+ elseif ($this->getConfig('patches-file') != '') {
$this->io->write('Gathering patches from patch file.');
- $patches = file_get_contents($extra['patches-file']);
+ $patches = file_get_contents($this->getConfig('patches-file'));
$patches = json_decode($patches, true);
$error = json_last_error();
if ($error != 0) {
@@ -275,10 +311,6 @@ public function grabPatches()
*/
public function postInstall(PackageEvent $event)
{
- // Check if we should exit in failure.
- $extra = $this->composer->getPackage()->getExtra();
- $exitOnFailure = getenv('COMPOSER_EXIT_ON_PATCH_FAILURE') || !empty($extra['composer-exit-on-patch-failure']);
-
// Get the package object for the current operation.
$operation = $event->getOperation();
/** @var PackageInterface $package */
@@ -325,7 +357,7 @@ public function postInstall(PackageEvent $event)
$e->getMessage() .
''
);
- if ($exitOnFailure) {
+ if ($this->getConfig('exit-on-patch-failure')) {
throw new \Exception("Cannot apply patch $description ($url)!");
}
}
@@ -384,7 +416,7 @@ protected function getAndApplyPatch(RemoteFilesystem $downloader, $install_path,
// The order here is intentional. p1 is most likely to apply with git apply.
// p0 is next likely. p2 is extremely unlikely, but for some special cases,
// it might be useful. p4 is useful for Magento 2 patches
- $patch_levels = array('-p1', '-p0', '-p2', '-p4');
+ $patch_levels = $this->getConfig('patch-levels');
foreach ($patch_levels as $patch_level) {
if ($this->io->isVerbose()) {
$comment = 'Testing ability to patch with git apply.';
@@ -453,15 +485,17 @@ protected function getAndApplyPatch(RemoteFilesystem $downloader, $install_path,
*/
protected function isPatchingEnabled()
{
- $extra = $this->composer->getPackage()->getExtra();
+ $enabled = true;
- if (empty($extra['patches']) && empty($extra['patches-ignore']) && !isset($extra['patches-file'])) {
- // The root package has no patches of its own, so only allow patching if
- // it has specifically opted in.
- return isset($extra['enable-patching']) ? $extra['enable-patching'] : false;
- } else {
- return true;
+ $has_no_patches = empty($extra['patches']);
+ $has_no_patches_file = ($this->getConfig('patches-file') == '');
+ $patching_disabled = $this->getConfig('disable-patching');
+
+ if ($patching_disabled || !($has_no_patches && $has_no_patches_file)) {
+ $enabled = false;
}
+
+ return $enabled;
}
/**
@@ -472,6 +506,10 @@ protected function isPatchingEnabled()
*/
protected function writePatchReport($patches, $directory)
{
+ if ($this->getConfig('disable-patch-reports')) {
+ return;
+ }
+
$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";
diff --git a/tests/acceptance/fixtures/patches-file-patch-from-web/composer.json b/tests/acceptance/fixtures/patches-file-patch-from-web/composer.json
index 7ff99527..a28dd92c 100644
--- a/tests/acceptance/fixtures/patches-file-patch-from-web/composer.json
+++ b/tests/acceptance/fixtures/patches-file-patch-from-web/composer.json
@@ -1,19 +1,21 @@
{
- "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"
+ "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": {
+ "composer-patches": {
+ "patches-file": "patches.json"
+ }
}
- ],
- "require": {
- "cweagans/composer-patches": "*@dev",
- "drupal/drupal": "~8.2"
- },
- "extra": {
- "patches-file": "patches.json"
- }
}