Composer plugin for applying patches from packaged patchsets

Overview

Build Status

Composer Plugin For Applying Patchsets

‼️ NEW Supports both composer branches v1.x and v2.x.

This plugin can automatically apply patches to any dependency of your project.

One of the most distinguishing features is that it can apply patches from special composer packages of type patchset. This is quite convenient as you can store all your patches in one repository and apply them automatically on all systems including developers' machines in a very predictable way. Also you can easily distribute your patchset to the whole community via packagist.

It's (kind-of) an alternative to two other great plugins:

Continue reading this document for more in-depth description or skip right away directly to:

Feature comparison table

Feature creativestyle/composer-plugin-patchset cweagans/composer-patches 1.x netresearch/composer-patches-plugin
Apply patch collection stored in a composer package yes no no
Deduplicate patches yes no TBD
Guarantees proper application on the first install yes no TBD
Full functional test-suite for all features yes no no tests at all
PHP Version Support confirmed by tests 5.6+ 5.3+ no information
Apply patches directly from remote locations no (no support planned) yes yes
Specify target package version constraints yes no yes
Uninstall removed patches in all cases1 yes no TBD
Reapply package patches if order has changed yes TBD TBD
Choose application method (git/patch) per patch yes TBD TBD
Apply patches to root package/directory yes no TBD

1 Root package patching is the exception, please see applying patches to root package in usage docs.

Feature description

  • Apply patches from dedicated composer packages (package your patchset!).

  • Each patch can have a version constraint (composer semver) checked against the target package.

    This means that you can (and should) have the patches fail the build if cannot be applied and still store patches for multiple package versions in the same patchset.

  • Apply patches using patch command and fall-back to git apply if not available.

  • Does not reinstall packages unnecessarily.

  • Reinstalls (cleans) packages which are patched but the patches have been removed guaranteeing a consistent state after multiple updates.

  • Will repatch packages even if order of patches for specific package (version) has changed.

  • Deduplicates patches on package level.

  • Does not overly tie into composer internals. All patching will be done after the main update/installation process at once execution making it simpler and easier to analyze.

    This also means that you have the guarantee that the plugin / patches are at the latest version before the process even starts. Otherwise it's very tricky (if not impossible) to make the plugin behave consistently on the first composer install (e.g. no vendor dir at all) and the subsequent ones.

    Double composer update/install for build is not necessary.

Use Git for applying patches

By default the library will try to use the patch command if not available and fall back to git otherwise. You can force using git for each patch (see: Usage Documentation).

There were some problems using git apply reported in other plugins for packages that were not installed as source (did not have a git repo; .git dir). I was not able to reproduce this problem with git 2.X - however - a workaround for this potential problem has been implemented:

- If the target package has `.git` directory, then the patches are applied relative to target package root
- If no git repo in target package then patches are applied from root project directory

Chicken or egg problem

Patching via composer plugin has one big problem - you cannot catch all events on the first install. Furthermore applying patches on package install/remove is very error prone as you can never predict conflicts with other plugins. Therefor gathering and applying patches before everything was actually installed carries the risk of producing invalid state at the end. This plugin takes a different approach - it performs all actions at once, after the installation/update was performed, just before autoload dump (in case patching changes it).

This guarantees a consistent state as the plugin compares the current state with the desired one and peforms only the actions necessary to get there.

This has one drawback, if your project uses any composer plugins that copy files from vendors to the root of your project then you should patch the root package because the patch applications will happen after those plugins have done their work so patching source files in vendor will have no effect.

Why no remote patches

This plugin will not download patches from external sources directly (http). I consider this a bad practice and will never support it. I won't even comment on downloading patches using unencrypted connection without SHA check. Also what if somebody wants to use your software in 2 years and the patches are no longer available?

Also you will not be able to specify patches in any composer package. You have to use a dedicated packages for this purpose. I can hardly imagine a legit use case when it would be desirable that installing package X will automatically patch some other package Y in your project without explicitly being advertised as a patchset.

You might also like...
Composer Repository Manager for selling Magento 2 extension and offering composer installation for ordered packages.

Magento 2 Composer Repository Credits We got inspired by https://github.com/Genmato. Composer Repository for Magento 2 This extension works as a Magen

Composer registry manager that help to easily switch to the composer repository you want

CRM - Composer Registry Manager Composer Registry Manager can help you easily and quickly switch between different composer repositories. 简体中文 Install

Dependency graph visualization for composer.json (PHP + Composer)
Dependency graph visualization for composer.json (PHP + Composer)

clue/graph-composer Graph visualization for your project's composer.json and its dependencies: Table of contents Usage graph-composer show graph-compo

Drupal Composer Scaffold - A flexible Composer project scaffold builder

This project provides a composer plugin for placing scaffold files (like index.php, update.php, …) from the drupal/core project into their desired location inside the web root. Only individual files may be scaffolded with this plugin.

Victor The Cleaner for Composer - This tool removes unnecessary files and directories from Composer vendor directory.

Victor The Cleaner for Composer This tool removes unnecessary files and directories from Composer vendor directory. The Cleaner leaves only directorie

Composer plugin for Repman - PHP Repository Manager

Repman Composer Plugin Composer plugin for Repman - PHP Repository Manager. Adds a mirror url for all your dependencies without need to update compose

Composer plugin replacing placeholders in the scripts section by dynamic values

Composer Substitution Plugin The Composer Substitution plugin replaces placeholders in the scripts section by dynamic values. It also permits to cache

Textpattern-installer - Textpattern plugin and theme installer for Composer

Textpattern Installer for Composer Package directory | Issues Install plugins and themes to Textpattern CMS with Composer. $ composer require rah/rah_

Composer Plugin for automatically including files for easing function usage in php.

Php Inc Php inc is a composer plugin for automatically including certain files into composer's autoload and autoload-dev files config. Given a set of

Comments
  • fails to create new folder/file with drupal.org patch

    fails to create new folder/file with drupal.org patch

    Given the patch https://www.drupal.org/files/issues/2018-06-26/events_log_track-add-workflows-2974170-7.patch (which adds a new file into a new folder) - the patch fails to apply.

    Is this not a valid patch for composer-plugin-patchset, given that other (non-new-file) patches apply ok - is there anything that I should be trying to diagnose (the same patch applies fine via composer-patches?

    Executing command (CWD): patch '--posix' '--batch' '--forward' '--strip=1' '--input=/Users/toby/Sites/lagoon/govcms8-scaffold-paas/vendor/govcms/patchset/drupal/event_log_track/increase-character-length-2930817-2.patch' '--directory=web/modules/contrib/events_log_track' '--remove-empty-files'
    Applied patch govcms/patchset:drupal/event_log_track/increase-character-length-2930817-2.patch [*] (https://www.drupal.org/files/issues/increase-character-length-2930817-2.patch) using patch method
    
    Executing command (CWD): patch '--posix' '--batch' '--forward' '--strip=1' '--input=/Users/toby/Sites/lagoon/govcms8-scaffold-paas/vendor/govcms/patchset/drupal/event_log_track/events_log_track-add-workflows-2974170-7.patch' '--directory=web/modules/contrib/events_log_track' '--remove-empty-files'
    Failed to apply patch govcms/patchset:drupal/event_log_track/events_log_track-add-workflows-2974170-7.patch [*] (https://www.drupal.org/files/issues/2018-06-26/events_log_track-add-workflows-2974170-7.patch) using patch method
    
                                                                                                                                                                                                                                                 
      [Creativestyle\Composer\Patchset\Exception\PatchApplicationFailedException]                                                                                                                                                                
      Could not apply patch - command "patch '--posix' '--batch' '--forward' '--strip=1' '--input=/Users/toby/Sites/lagoon/govcms8-scaffold-paas/vendor/govcms/patchset/drupal/event_log_track/events_log_track-add-workflows-2974170-7.patch'   
      '--directory=web/modules/contrib/events_log_track' '--remove-empty-files'" failed with:                                                                                                                                                    
      can't find file to patch at input line 6                                                                                                                                                                                                   
      Perhaps you used the wrong -p or --strip option?                                                                                                                                                                                           
      The text leading up to this was:                                                                                                                                                                                                           
      --------------------------                                                                                                                                                                                                                 
      |diff --git a/event_log_track_workflows/event_log_track_workflows.info.yml b/event_log_track_workflows/event_log_track_workflows.info.yml                                                                                                  
      |new file mode 100644                                                                                                                                                                                                                      
      |index 0000000..5ead5ed                                                                                                                                                                                                                    
      |--- /dev/null                                                                                                                                                                                                                             
      |+++ b/event_log_track_workflows/event_log_track_workflows.info.yml                                                                                                                                                                        
      --------------------------                                                                                                                                                                                                                 
      No file to patch.  Skipping patch.                                                                                                                                                                                                         
      1 out of 1 hunk ignored                                                                                                                                                                                                                    
      can't find file to patch at input line 26                                                                                                                                                                                                  
      Perhaps you used the wrong -p or --strip option?                                                                                                                                                                                           
      The text leading up to this was:                                                                                                                                                                                                           
      --------------------------                                                                                                                                                                                                                 
      |diff --git a/event_log_track_workflows/event_log_track_workflows.module b/event_log_track_workflows/event_log_track_workflows.module                                                                                                      
      |new file mode 100755                                                                                                                                                                                                                      
      |index 0000000..0f4038a                                                                                                                                                                                                                    
      |--- /dev/null                                                                                                                                                                                                                             
      |+++ b/event_log_track_workflows/event_log_track_workflows.module                                                                                                                                                                          
      --------------------------                                                                                                                                                                                                                 
      No file to patch.  Skipping patch.                                                                                                                                                                                                         
      1 out of 1 hunk ignored                                                                                                                                                                                                                    
                                                                                                                                                                                                                                                 
    
    Exception trace:
     () at /Users/toby/Sites/lagoon/govcms8-scaffold-paas/vendor/creativestyle/composer-plugin-patchset/src/PatchApplicator.php:176
     Creativestyle\Composer\Patchset\PatchApplicator->applyPatch() at /Users/toby/Sites/lagoon/govcms8-scaffold-paas/vendor/creativestyle/composer-plugin-patchset/src/Patcher.php:309
     Creativestyle\Composer\Patchset\Patcher->applyPatches() at /Users/toby/Sites/lagoon/govcms8-scaffold-paas/vendor/creativestyle/composer-plugin-patchset/src/Patcher.php:388
     Creativestyle\Composer\Patchset\Patcher->patch() at /Users/toby/Sites/lagoon/govcms8-scaffold-paas/vendor/creativestyle/composer-plugin-patchset/src/Plugin.php:71
     Creativestyle\Composer\Patchset\Plugin->applyPatches() at /Users/toby/Sites/lagoon/govcms8-scaffold-paas/vendor/creativestyle/composer-plugin-patchset/src/Plugin.php:55
     Creativestyle\Composer\Patchset\Plugin->onPreAutoloadDump() at n/a:n/a
     call_user_func() at phar:///usr/local/Cellar/composer/1.9.3/bin/composer/src/Composer/EventDispatcher/EventDispatcher.php:176
     Composer\EventDispatcher\EventDispatcher->doDispatch() at phar:///usr/local/Cellar/composer/1.9.3/bin/composer/src/Composer/EventDispatcher/EventDispatcher.php:96
     Composer\EventDispatcher\EventDispatcher->dispatchScript() at phar:///usr/local/Cellar/composer/1.9.3/bin/composer/src/Composer/Autoload/AutoloadGenerator.php:112
     Composer\Autoload\AutoloadGenerator->dump() at phar:///usr/local/Cellar/composer/1.9.3/bin/composer/src/Composer/Installer.php:304
     Composer\Installer->run() at phar:///usr/local/Cellar/composer/1.9.3/bin/composer/src/Composer/Command/InstallCommand.php:122
     Composer\Command\InstallCommand->execute() at phar:///usr/local/Cellar/composer/1.9.3/bin/composer/vendor/symfony/console/Command/Command.php:245
     Symfony\Component\Console\Command\Command->run() at phar:///usr/local/Cellar/composer/1.9.3/bin/composer/vendor/symfony/console/Application.php:835
     Symfony\Component\Console\Application->doRunCommand() at phar:///usr/local/Cellar/composer/1.9.3/bin/composer/vendor/symfony/console/Application.php:185
     Symfony\Component\Console\Application->doRun() at phar:///usr/local/Cellar/composer/1.9.3/bin/composer/src/Composer/Console/Application.php:267
     Composer\Console\Application->doRun() at phar:///usr/local/Cellar/composer/1.9.3/bin/composer/vendor/symfony/console/Application.php:117
     Symfony\Component\Console\Application->run() at phar:///usr/local/Cellar/composer/1.9.3/bin/composer/src/Composer/Console/Application.php:106
     Composer\Console\Application->run() at phar:///usr/local/Cellar/composer/1.9.3/bin/composer/bin/composer:61
     require() at /usr/local/Cellar/composer/1.9.3/bin/composer:24
    
    bug incompatibility 
    opened by tobybellwood 4
  • Support for Composer 2

    Support for Composer 2

    Would be great to see support for Composer 2 added.

    Currently composer install fails using Composer 2 because composer-plugin-patchset requires composer-plugin-api ^1.1.

    opened by aleksblendwerk 1
Releases(v2.2.0)
Owner
MageOps
MageOps
Plugin for composer to apply patches onto dependencies.

composer-patches-plugin This plugin allows you to provide patches for any package from any package. If you don't want a patch package outside the root

Netresearch 75 Aug 7, 2022
A composer plugin, to install differenty types of composer packages in custom directories outside the default composer default installation path which is in the vendor folder.

composer-custom-directory-installer A composer plugin, to install differenty types of composer packages in custom directories outside the default comp

Mina Nabil Sami 136 Dec 30, 2022
Ied plugin composer - Inspired Plugin Composer: Create, publish and edit plugins from within Textpattern CMS.

ied_plugin_composer Create, publish and edit plugins from within Textpattern CMS. Creates a new page under the Extensions tab where you can edit and e

Stef Dawson 8 Oct 3, 2020
Opinionated version of Wikimedia composer-merge-plugin to work in pair with Bamarni composer-bin-plugin.

Composer Inheritance Plugin Opinionated version of Wikimedia composer-merge-plugin to work in pair with bamarni/composer-bin-plugin. Usage If you are

Théo FIDRY 25 Dec 2, 2022
Patches that prevent malicious Minecraft plugins from saturating host internet resources for DDoS.

Minecraft Host DoS Botnet Patches Patches that prevent malicious Minecraft plugins from saturating host internet resources for DDoS. In recent events,

Riley Nevins 4 Jul 16, 2022
As many Magento patches as I can find!

Magento Resources and Links I have been looking for a good repository for all resources for Magento and I thought I will start putting them here for n

Brent W. Peterson 271 Dec 22, 2022
Audit your PHP version for known CVEs and patches

PHP Version Audit PHP Version Audit is a convenience tool to easily check a given PHP version against a regularly updated list of CVE exploits, new re

Daniel 103 Dec 19, 2022
Composer plugin that wraps all composer vendor packages inside your own namespace. Intended for WordPress plugins.

Imposter Plugin Composer plugin that wraps all composer vendor packages inside your own namespace. Intended for WordPress plugins. Built with ♥ by Typ

Typist Tech 127 Dec 17, 2022
Composer Registrar Composer Plugin for Magento 2

This module add a global registration.php that replace the default glob search performed for each request to discover the components not installed from composer.

OpenGento 3 Mar 22, 2022
Magento-composer-installer - Composer installer for Magento modules

!!! support the maintainer of this project via Patreon: https://www.patreon.com/Flyingmana Magento Composer Installer The purpose of this project is t

null 213 Sep 24, 2022