Kontakt
Just type and press enter to search
Cancel

How to simply apply patches with Composer

How to simply apply patches with Composer

Why patch at all?

Actually nobody wants to patch code. Unfortunately it is often necessary because mistakes even sneak into stable software versions. And when it comes to security holes that have to be closed quickly or errors that need to be fixed as fast as possible, waiting for a troubleshooting in one of the next releases often takes too long.

Patches have many disadvantages. They have to be managed. Once a third-party extension or a core has been modified, a simple update is no longer possible. The changed code must be carried along. Sometimes a fork is the solution, but when it comes to updates it is not possible to do it without a lot of effort. And if the patch is poorly documented or not documented at all, the patch may get lost and in the worst case has to be found again.

composer-patches by Cameron Eagans

Cameron Eagans has released composer-patches a slim composer package for such cases that makes it easy to deploy patches for Composer packages. With the command

composer require "cweagans/composer-patches:~1.0"

composer-patches is applied to the project and the composer.json. The patches can be managed in two ways. They can be configured directly in the composer.json.

"extra": {
  "patches": {
    "vendor/package": {
      "Bug #1234: Something is wrong": "patches/1234.diff"
    }
  }
}

If the composer.json should not be overloaded by the configurations, an external file is available as alternative to define the patches. Below this file is called composer.patches.json. In composer.json only the reference to this file is stored.

"extra": {
  "patches-file": "composer.patches.json",
  "enable-patching": true
}

The file composer.patches.json contains the individual patches and the associated patch file.

{
  "patches": {
    "vendor/package": {
      "Bug #1234: Something is wrong": "patches/1234.diff"
    }
  }
}

Instead of a patch file, as used in the following, a link to the external patch file can be used.

{
  "patches": {
    "vendor/package": {
      "Bug #1234: Something is wrong": "https://url.to-the-patch-file.com/1234.diff"
    }
  }
}


Case example: Patching current TYPO3 8.6.1 core with composer-patches

Since one of our customers could not see any content in the frontend after an update to TYPO3 version 8.6.1, we went to search for the track. It turned out that a bug in the core was the reason: styles.content.get not available in FSC anymore. A short time later a patch was available on the TYPO3 review server: Make styles.content.get available after major FSC rewrite.

In order not to be dependent on the next TYPO3 version and still to be able to work on the current version, we decided to patch the core using composer-patches. The composer.patches.json file for this project contains a description of the error and a link to the patch that is used.

{
  "patches": {
    "typo3/cms": {
      "Bug #80044: styles.content.get not available in FSC anymore (https://review.typo3.org/#/c/51884)": "patches/3a02a648.diff"
    }
  }
}

This ensures that the patch is used when composer install is called, and each developer can understand why the patch is necessary. In addition, the configuration is versioned with the project. The patch file itself can not be attracted via a link, since composer-patches unfortunately can't handle neither the TYPO3 provided patch files in Base64 nor archives.

Screenshot der zeigt, dass Die Patch-Datei selbst kann nicht über einen Link angezogen werden

The extracted file from the patch file archive (3307a5d.diff.zip) of TYPO3 is therefore in a patches folder within the project. This avoids additional dependencies on the external TYPO3 review server.

When you call composer install, the patch is inserted.

Anzeige im Terminal, der zeigt, wie beim Aufruf von composer install der Patch eingefügt wird


Case example: A patch for Neos

If a Neos installation needs to be patched, the same procedure can be used. The Neos team is currently working exclusively in Github. For example, the commit c448b4e should be imported as a patch. Patch files can be generated with Github by appending .diff or .patch to the URL.

Screenshot der zeigt, wo man .patch oder .doff anhängen soll

The configuration in the composer.patches.json therefore contains a link as a patch source.

{
  "patches": {
    "neos/neos": {
      "TASK: Add preset attribute description to fusion reference": "https://github.com/neos/neos/commit/c448b4e64050235cd4302996a7630dd2ffcec930.patch"
    }
  }
}

When you call composer install, the patch is inserted.

Das Terminal zeigt: Beim Aufruf von composer install wird der Patch eingefügt.

If you need to patch, do it smart

If you can't avoid a patch, the work with tools like composer-patches is highly recommended.The disadvantages remain within a controllable framework and the overview of the patches in the project is preserved. If the configuration for the patches is given a clean description and thus an implicit documentation, the likelihood that the knowledge about the patch will get lost is very low, and also new colleagues immediately will have an insight. By the versioning of the patch files and the automation with Composer the effort to carry the patch in the project is reduced a lot.

Autor: Daniela Grammlich

Comments

Cameron Eagans • 17.03.2017 - 23:46

Thanks for the writeup! Glad this plugin has been helpful!


Other Posts

Everyone can participate in the development of Neos and Flow
19. April 2017

Everyone can participate in the development of Neos and Flow

A small experience report from the Neos-Sprint in Hamburg with start-up assistance for all who want to … more

Neos Tutorial Part 1 - Setting up a development environment easily
6. April 2016

Neos Tutorial Part 1 - Setting up a development environment easily

Innovative, intuitive and flexible - that's a good description for the Neos CMS. In this multi-part workshop, … more