| 1 |
# composer-patches |
| 2 |
|
| 3 |
Simple patches plugin for Composer. Applies a patch from a local or remote file to any package required with composer. |
| 4 |
|
| 5 |
Note that the 1.x versions of Composer Patches are supported on a best-effort |
| 6 |
basis due to the imminent release of 2.0.0. You may still be interested in |
| 7 |
using 1.x if you need Composer to cooperate with earlier PHP versions. No new |
| 8 |
features will be added to 1.x releases, but any security or bug fixes will |
| 9 |
still be accepted. |
| 10 |
|
| 11 |
## Usage |
| 12 |
|
| 13 |
Example composer.json: |
| 14 |
|
| 15 |
```json |
| 16 |
{ |
| 17 |
"require": { |
| 18 |
"cweagans/composer-patches": "~1.0", |
| 19 |
"drupal/drupal": "~8.2" |
| 20 |
}, |
| 21 |
"config": { |
| 22 |
"preferred-install": "source" |
| 23 |
}, |
| 24 |
"extra": { |
| 25 |
"patches": { |
| 26 |
"drupal/drupal": { |
| 27 |
"Add startup configuration for PHP server": "https://www.drupal.org/files/issues/add_a_startup-1543858-30.patch" |
| 28 |
} |
| 29 |
} |
| 30 |
} |
| 31 |
} |
| 32 |
|
| 33 |
``` |
| 34 |
|
| 35 |
## Using an external patch file |
| 36 |
|
| 37 |
Instead of a patches key in your root composer.json, use a patches-file key. |
| 38 |
|
| 39 |
```json |
| 40 |
{ |
| 41 |
"require": { |
| 42 |
"cweagans/composer-patches": "~1.0", |
| 43 |
"drupal/drupal": "~8.2" |
| 44 |
}, |
| 45 |
"config": { |
| 46 |
"preferred-install": "source" |
| 47 |
}, |
| 48 |
"extra": { |
| 49 |
"patches-file": "local/path/to/your/composer.patches.json" |
| 50 |
} |
| 51 |
} |
| 52 |
|
| 53 |
``` |
| 54 |
|
| 55 |
Then your `composer.patches.json` should look like this: |
| 56 |
|
| 57 |
``` |
| 58 |
{ |
| 59 |
"patches": { |
| 60 |
"vendor/project": { |
| 61 |
"Patch title": "http://example.com/url/to/patch.patch" |
| 62 |
} |
| 63 |
} |
| 64 |
} |
| 65 |
``` |
| 66 |
|
| 67 |
## Allowing patches to be applied from dependencies |
| 68 |
|
| 69 |
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: |
| 70 |
|
| 71 |
```json |
| 72 |
{ |
| 73 |
"require": { |
| 74 |
"cweagans/composer-patches": "^1.5.0" |
| 75 |
}, |
| 76 |
"extra": { |
| 77 |
"enable-patching": true |
| 78 |
} |
| 79 |
} |
| 80 |
``` |
| 81 |
|
| 82 |
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. |
| 83 |
|
| 84 |
## Ignoring patches |
| 85 |
|
| 86 |
There may be situations in which you want to ignore a patch supplied by a dependency. For example: |
| 87 |
|
| 88 |
- You use a different more recent version of a dependency, and now a patch isn't applying. |
| 89 |
- You have a more up to date patch than the dependency, and want to use yours instead of theirs. |
| 90 |
- A dependency's patch adds a feature to a project that you don't need. |
| 91 |
- Your patches conflict with a dependency's patches. |
| 92 |
|
| 93 |
```json |
| 94 |
{ |
| 95 |
"require": { |
| 96 |
"cweagans/composer-patches": "~1.0", |
| 97 |
"drupal/drupal": "~8.2", |
| 98 |
"drupal/lightning": "~8.1" |
| 99 |
}, |
| 100 |
"config": { |
| 101 |
"preferred-install": "source" |
| 102 |
}, |
| 103 |
"extra": { |
| 104 |
"patches": { |
| 105 |
"drupal/drupal": { |
| 106 |
"Add startup configuration for PHP server": "https://www.drupal.org/files/issues/add_a_startup-1543858-30.patch" |
| 107 |
} |
| 108 |
}, |
| 109 |
"patches-ignore": { |
| 110 |
"drupal/lightning": { |
| 111 |
"drupal/panelizer": { |
| 112 |
"This patch has known conflicts with our Quick Edit integration": "https://www.drupal.org/files/issues/2664682-49.patch" |
| 113 |
} |
| 114 |
} |
| 115 |
} |
| 116 |
} |
| 117 |
} |
| 118 |
``` |
| 119 |
|
| 120 |
## Allowing to force the patch level (-pX) |
| 121 |
|
| 122 |
Some situations require to force the patchLevel used to apply patches on a particular package. |
| 123 |
Its useful for packages like drupal/core which packages only a subdir of the original upstream project on which patches are based. |
| 124 |
|
| 125 |
```json |
| 126 |
{ |
| 127 |
"extra": { |
| 128 |
"patchLevel": { |
| 129 |
"drupal/core": "-p2" |
| 130 |
} |
| 131 |
} |
| 132 |
} |
| 133 |
``` |
| 134 |
|
| 135 |
## Using patches from HTTP URLs |
| 136 |
|
| 137 |
Composer [](https://getcomposer.org/doc/06-config.md#secure-httpblocks](https://getcomposer.org/doc/06-config.md#secure-http](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`. |
| 138 |
|
| 139 |
```json |
| 140 |
{ |
| 141 |
"config": { |
| 142 |
"secure-http": false |
| 143 |
} |
| 144 |
} |
| 145 |
``` |
| 146 |
|
| 147 |
However, it's always advised to setup HTTPS to prevent MITM code injection. |
| 148 |
|
| 149 |
## Patches containing modifications to composer.json files |
| 150 |
|
| 151 |
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. |
| 152 |
|
| 153 |
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: |
| 154 |
- Work to get the underlying issue resolved in the upstream package. |
| 155 |
- Fork the package and [](https://getcomposer.org/doc/05-repositories.md#vcsspecify your fork as the package repository](https://getcomposer.org/doc/05-repositories.md#vcs](https://getcomposer.org/doc/05-repositories.md#vcs) in your root `composer.json` |
| 156 |
- Specify compatible package version requirements in your root `composer.json` |
| 157 |
|
| 158 |
## Error handling |
| 159 |
|
| 160 |
If a patch cannot be applied (hunk failed, different line endings, etc.) a message will be shown and the patch will be skipped. |
| 161 |
|
| 162 |
To enforce throwing an error and stopping package installation/update immediately, you have two available options: |
| 163 |
|
| 164 |
1. Add `"composer-exit-on-patch-failure": true` option to the `extra` section of your composer.json file. |
| 165 |
1. Export `COMPOSER_EXIT_ON_PATCH_FAILURE=1` |
| 166 |
|
| 167 |
By default, failed patches are skipped. |
| 168 |
|
| 169 |
## Patches reporting |
| 170 |
|
| 171 |
When a patch is applied, the plugin writes a report-file `PATCHES.txt` to a patching directory (e.g. `./patch-me/PATCHES.txt`), |
| 172 |
which contains a list of applied patches. |
| 173 |
|
| 174 |
If you want to avoid this behavior, add a specific key to the `extra` section: |
| 175 |
```json |
| 176 |
"extra": { |
| 177 |
"composer-patches-skip-reporting": true |
| 178 |
} |
| 179 |
``` |
| 180 |
|
| 181 |
Or provide an environment variable `COMPOSER_PATCHES_SKIP_REPORTING` with a config. |
| 182 |
|
| 183 |
## Patching composer.json in dependencies |
| 184 |
|
| 185 |
This doesn't work like you'd want. By the time you're running `composer install`, |
| 186 |
the metadata from your dependencies' composer.json has already been aggregated by |
| 187 |
packagist (or whatever metadata repo you're using). Unfortunately, this means that |
| 188 |
you cannot e.g. patch a dependency to be compatible with an earlier version of PHP |
| 189 |
or change the framework version that a plugin depends on. |
| 190 |
|
| 191 |
@anotherjames over at @computerminds wrote an article about how to work around |
| 192 |
that particular problem for a Drupal 8 -> Drupal 9 upgrade: |
| 193 |
|
| 194 |
[](https://www.computerminds.co.uk/articles/apply-drupal-9-compatibility-patches-composerApply Drupal 9 compatibility patches with Composer](https://www.computerminds.co.uk/articles/apply-drupal-9-compatibility-patches-composer](https://www.computerminds.co.uk/articles/apply-drupal-9-compatibility-patches-composer) ([](https://web.archive.org/web/20210124171010/https://www.computerminds.co.uk/articles/apply-drupal-9-compatibility-patches-composerarchive](https://web.archive.org/web/20210124171010/https://www.computerminds.co.uk/articles/apply-drupal-9-compatibility-patches-composer](https://web.archive.org/web/20210124171010/https://www.computerminds.co.uk/articles/apply-drupal-9-compatibility-patches-composer)) |
| 195 |
|
| 196 |
## Difference between this and netresearch/composer-patches-plugin |
| 197 |
|
| 198 |
- This plugin is much more simple to use and maintain |
| 199 |
- This plugin doesn't require you to specify which package version you're patching |
| 200 |
- This plugin is easy to use with Drupal modules (which don't use semantic versioning). |
| 201 |
- This plugin will gather patches from all dependencies and apply them as if they were in the root composer.json |
| 202 |
|
| 203 |
## Credits |
| 204 |
|
| 205 |
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. |
| 206 |
|