Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
## Allowing patches to be applied from dependencies
If your project doesn't supply any patches of its own, but you still want to accept patches from dependencies, you must have the following in your composer file:
```json
{
"require":{
"cweagans/composer-patches":"^1.5.0"
},
"extra":{
"enable-patching":true
}
}
```
If you do have a `patches` section in your composer file that defines your own set of patches then the `enable-patching` setting will be ignored and patches from dependencies will always be applied.
## Ignoring patches
There may be situations in which you want to ignore a patch supplied by a dependency. For example:
- You use a different more recent version of a dependency, and now a patch isn't applying.
- You have a more up to date patch than the dependency, and want to use yours instead of theirs.
- A dependency's patch adds a feature to a project that you don't need.
- Your patches conflict with a dependency's patches.
```json
{
"require":{
"cweagans/composer-patches":"~1.0",
"drupal/drupal":"~8.2",
"drupal/lightning":"~8.1"
},
"config":{
"preferred-install":"source"
},
"extra":{
"patches":{
"drupal/drupal":{
"Add startup configuration for PHP server":"https://www.drupal.org/files/issues/add_a_startup-1543858-30.patch"
}
},
"patches-ignore":{
"drupal/lightning":{
"drupal/panelizer":{
"This patch has known conflicts with our Quick Edit integration":"https://www.drupal.org/files/issues/2664682-49.patch"
}
}
}
}
}
```
## Allowing to force the patch level (-pX)
Some situations require to force the patchLevel used to apply patches on a particular package.
Its useful for packages like drupal/core which packages only a subdir of the original upstream project on which patches are based.
```json
{
"extra":{
"patchLevel":{
"drupal/core":"-p2"
}
}
}
```
## Using patches from HTTP URLs
Composer [blocks](https://getcomposer.org/doc/06-config.md#secure-http) you from downloading anything from HTTP URLs, you can disable this for your project by adding a `secure-http` setting in the config section of your `composer.json`. Note that the `config` section should be under the root of your `composer.json`.
```json
{
"config":{
"secure-http":false
}
}
```
However, it's always advised to setup HTTPS to prevent MITM code injection.
## Patches containing modifications to composer.json files
Because patching occurs _after_ Composer calculates dependencies and installs packages, changes to an underlying dependency's `composer.json` file introduced in a patch will have _no effect_ on installed packages.
If you need to modify a dependency's `composer.json` or its underlying dependencies, you cannot use this plugin. Instead, you must do one of the following:
- Work to get the underlying issue resolved in the upstream package.
- Fork the package and [specify your fork as the package repository](https://getcomposer.org/doc/05-repositories.md#vcs) in your root `composer.json`
- Specify compatible package version requirements in your root `composer.json`
## Error handling
If a patch cannot be applied (hunk failed, different line endings, etc.) a message will be shown and the patch will be skipped.
To enforce throwing an error and stopping package installation/update immediately, you have two available options:
1. Add `"composer-exit-on-patch-failure": true` option to the `extra` section of your composer.json file.
1. Export `COMPOSER_EXIT_ON_PATCH_FAILURE=1`
By default, failed patches are skipped.
## Patches reporting
When a patch is applied, the plugin writes a report-file `PATCHES.txt` to a patching directory (e.g. `./patch-me/PATCHES.txt`),
which contains a list of applied patches.
If you want to avoid this behavior, add a specific key to the `extra` section:
```json
"extra":{
"composer-patches-skip-reporting":true
}
```
Or provide an environment variable `COMPOSER_PATCHES_SKIP_REPORTING` with a config.
## Patching composer.json in dependencies
This doesn't work like you'd want. By the time you're running `composer install`,
the metadata from your dependencies' composer.json has already been aggregated by
packagist (or whatever metadata repo you're using). Unfortunately, this means that
you cannot e.g. patch a dependency to be compatible with an earlier version of PHP
or change the framework version that a plugin depends on.
@anotherjames over at @computerminds wrote an article about how to work around
that particular problem for a Drupal 8 -> Drupal 9 upgrade:
[Apply Drupal 9 compatibility patches with Composer](https://www.computerminds.co.uk/articles/apply-drupal-9-compatibility-patches-composer)([archive](https://web.archive.org/web/20210124171010/https://www.computerminds.co.uk/articles/apply-drupal-9-compatibility-patches-composer))
## Difference between this and netresearch/composer-patches-plugin
- This plugin is much more simple to use and maintain
- This plugin doesn't require you to specify which package version you're patching
- This plugin is easy to use with Drupal modules (which don't use semantic versioning).
- This plugin will gather patches from all dependencies and apply them as if they were in the root composer.json
## Credits
A ton of this code is adapted or taken straight from https://github.com/jpstacey/composer-patcher, which is abandoned in favor of https://github.com/netresearch/composer-patches-plugin, which is (IMHO) overly complex and difficult to use.
$this->io->write("Not scaffolding files for <comment>{$name}</comment>, because it is not listed in the element 'extra.drupal-scaffold.allowed-packages' in the root-level composer.json file.");
}
else{
$this->io->write("Package <comment>{$name}</comment> has scaffold operations, and is already allowed in the root-level composer.json file.");
}
}
// @todo We could prompt the user and ask if they wish to allow a
// newly-added package. This might be useful if, for example, the user
// might wish to require an installation profile that contains scaffolded
thrownew\RuntimeException($interpolator->interpolate("Could not symlink source file <info>[src-rel-path]</info> to <info>[dest-rel-path]</info>!"),[],$e);
}
$io->write($interpolator->interpolate(" - Link <info>[dest-rel-path]</info> from <info>[src-rel-path]</info>"));
If you are already using Composer Merge Plugin 1.4 (or older) and you are updating the plugin to 2.0 (or newer), it is recommended that you update the plugin first using Composer 1.
If you update the incompatible plugin using Composer 2, the plugin will be ignored:
> The "wikimedia/composer-merge-plugin" plugin was skipped because it requires a Plugin API version ("^1.0") that does not match your Composer installation ("2.0.0"). You may need to run composer update with the "--no-plugins" option.
Consequently, Composer will be unaware of the merged dependencies and will remove them requiring you to run `composer update` again to reinstall merged dependencies.
Usage
-----
```json
{
"require":{
"wikimedia/composer-merge-plugin":"dev-master"
},
"extra":{
"merge-plugin":{
"include":[
"composer.local.json",
"extensions/*/composer.json"
],
"require":[
"submodule/composer.json"
],
"recurse":true,
"replace":false,
"ignore-duplicates":false,
"merge-dev":true,
"merge-extra":false,
"merge-extra-deep":false,
"merge-replace":true,
"merge-scripts":false
}
}
}
```
### Updating sub-levels `composer.json` files
In order for Composer Merge Plugin to install dependencies from updated or newly created sub-level `composer.json` files in your project you need to run the command:
```
$ composer update
```
This will [instruct Composer to recalculate the file hash](https://getcomposer.org/doc/03-cli.md#update) for the top-level `composer.json` thus triggering Composer Merge Plugin to look for the sub-level configuration files and update your dependencies.
Plugin configuration
--------------------
The plugin reads its configuration from the `merge-plugin` section of your
composer.json's `extra` section. An `include` setting is required to tell
Composer Merge Plugin which file(s) to merge.
### include
The `include` setting can specify either a single value or an array of values.
Each value is treated as a PHP `glob()` pattern identifying additional
composer.json style configuration files to merge into the root package
configuration for the current Composer execution.
The following sections of the found configuration files will be merged into
the Composer root package configuration as though they were directly included