Als je met Drupal werkt, ontkom je er niet aan: soms is een module nog niet helemaal up-to-date of mist er een bugfix in de core van Drupal. In dat geval kun je een patch gebruiken. Een patch is een klein bestand waarin wijzigingen in de code zijn vastgelegd. Dit bestand kun je gebruiken om de wijziging in jouw project alvast door te voeren zonder te moeten wachten op een officiële release.
In dit artikel leg ik uit hoe je patches in Drupal beheert met composer, hoe en wanneer composer ze doorvoert en wat de beste manier is om patches toe te voegen aan je project.
Waarom patches gebruiken?
Drupal core en de contributed modules worden ontwikkeld door de community. Dat betekent dat iedereen kan bijdragen aan het ontwikkelen van nieuwe functionaliteit en het oplossen van bugs. De wijzigingen die hiervoor nodig zijn worden aangeleverd door patches of merge requests. In dit artikel licht ik alleen het gebruik van patches toe.
Maintainers van Drupal core of een module hebben niet altijd direct de mogelijkheid om deze wijzigingen ook direct door te voeren in een nieuwe release. De code moet worden getest en gereviewd. In de tussentijd kun je de wel de patch gebruiken om een probleem in je eigen project op te lossen, zonder te wachten op de volgende release van de module.
Een patch is een tijdelijke oplossing: zodra de bugfix in een officiële release zit, kun je de patch weer verwijderen.
Composer en patches in Drupal
In een moderne Drupal-setup beheer je je codebase met composer. Composer regelt in de basis het ophalen van modules en dependencies. Met een extra plugin kan composer ook de gedefinieerde patches downloaden en gelijk doorvoeren.
De meest gebruikte plugin hiervoor is cweagans/composer-patches
. Zodra je deze in je project hebt geïnstalleerd, zal composer de gedefinieerde patches automatisch downloaden en toepassen tijdens composer install
en composer update
. Dit is een ideale oplossing als je met meerdere developers aan een project werkt, omdat de patches automatisch worden geïnstalleerd en dus niet iedere developer handmatig de patches hoeft door te voeren.
De patches definieer je onder "patches" in het composer.json
bestand, zoals hieronder:
{
"name": "...",
"description": "...",
...
...
...
"config": {
"allow-plugins": {
...
"cweagans/composer-patches": true,
...
},
},
"extra": {
...
...
...
"patches": {
"drupal/core": {
"[core][3226791] Validation error saving untranslatable Media reference field": "patches/3226791.patch"
}
}
},
...
...
...
}
Zoals je kunt zien definieer je eerst de naam van de module (of core) als key. Vervolgens definieer je een of meerdere patches. Per patch gebruik je een omschrijving van de patch als key en geef je het pad (of URL) naar de patch mee als value.
Online patches vs. lokale patches
Hoewel het handig lijkt om direct naar een URL te verwijzen, heeft dat een risico: patches online kunnen wijzigen of verdwijnen. Dit kan ervoor zorgen dat je build later ineens breekt of andere code toepast dan je verwacht.
Daarom is het veiliger om patches lokaal op te slaan in je repository. Zo weet je zeker dat de patch die jij getest hebt ook consistent wordt toegepast in elke omgeving (development, test, productie, CI/CD). Maak bijvoorbeeld een mapje "patches" aan in de root van je project en plaats daar een lokale kopie van de patch. Je kunt een patch vanaf drupal.org (of een andere bron) eenvoudig downloaden met wget
en direct opslaan in je patches
map. Bijvoorbeeld:
$ wget -O patches/[LOKALE-BESTANDSNAAM].patch [URL-NAAR-PATCH]
Wanneer worden patches doorgevoerd?
Telkens als je de commando's composer install
of composer update
uitvoert, controleert composer of er patches gedefinieerd zijn in je composer.json
. Als dat zo is, worden deze automatisch toegepast op de juiste module of op Drupal core.
Automatisch PATCHES.txt bestand
Wanneer je patches toepast via cweagans/composer-patches
, wordt er automatisch een PATCHES.txt bestand aangemaakt in de map van de betreffende module. Dit bestand bevat een overzicht van alle patches die Composer heeft toegepast op de module, inclusief de beschrijving en de bron uit je composer.json
bestand.
Belangrijk om te weten is dat dit bestand dus automatisch wordt gegenereerd door Composer en het dus niet handmatig moet worden aangepast. Zie het vooral als documentatie die helpt bij onderhoud en debuggen.
Dit zijn de best practices
-
Documenteer goed: schrijf in de beschrijving bij elke patch waar deze voor is bedoeld. Zelf hanteer ik als omschrijving het volgende format:
[DRUPAL_ORG_NODE_ID][MODULE_NAME] [NODE_TITLE_OP_DRUPAL_ORG]
. Dat ziet er dan bijvoorbeeld zo uit:"[core][3226791] Validation error saving untranslatable Media reference field": "patches/3226791.patch"
- Controleer regelmatig: zodra de patch in een officiële release van de module zit, verwijder hem uit je
composer.json
. Meestal krijg je ook een melding te zien tijdenscomposer install
dat de patch niet meer kan worden toegepast. - Lokaal opslaan: bewaar patches in een eigen map in de repo in plaats van ze rechtstreeks van een URL te downloaden. Hiermee voorkom je verrassingen in de toekomst.
Conclusie
Patches zijn een hulpmiddel om bugs in Drupal snel te verhelpen, nog voordat er een officiële release is. Met Composer en de cweagans/composer-patches
plugin beheer je patches overzichtelijk en worden ze automatisch toegepast bij jou en je collega's. Door patches lokaal op te slaan, zorg je bovendien voor stabiliteit en betrouwbaarheid in je project.