Créer et appliquer un patch pour un module sous Linux

Créer et appliquer un patch pour un module sous Linux

08 Mar 2010 |  Drupal

Il est parfois inévitable de devoir modifier un module contribué afin d’étendre les possibilités de celui-ci ou tout simplement pour corriger quelque chose. Dans tous les cas il ne faut pas modifier les fichiers du module et les mettre sur votre site car dans ce cas il vous sera compliqué de mettre à jour votre module. Imaginez le jour ou vous voudrez appliquer la nouvelle version de celui-ci, toutes vos modifications seront écrasées.

Pour modifier correctement un module vous devez créer un patch que vous appliquerez par la suite au module original.

Dans un premier temps nous allons voir comment générer notre patch puis comment l’appliquer. Il existe plusieurs façons pour faire cela. La solution que je vous propose n’est qu’une solution parmi tant d’autres.

Comme exemple j’ai pris la fonction facebook_status_activity() du module facebook_status ci-dessous. Cette fonction permet, lorsque le module activity est installé, d’insérer des activités lorsqu’un utilisateur a mis à jour son statut.

function facebook_status_activity($owner, $poster, $status) {
  //If we're using Activity 2, this function doesn't need to be run.
  if (!module_exists('activity') || function_exists('activity_help')) {
    return FALSE;
  }
  //Privacy setting check.
  if (activity_user_privacy_optout($poster)) {
    return FALSE;
  }
  $data = array(
    'owner' => theme('username', $owner),
    'poster' => theme('username', $poster),
    'status-unformatted' => check_plain($status->status),
    'status-themed' => theme('facebook_status_item', $status),
    'status_time' => $status->status_time,
  );
  $target_users_roles = array(
    ACTIVITY_ALL => 'all',
    $owner->uid => 'owner',
  );
  //If $owner->uid == $poster->uid, this will just overwrite the owner role.
  $target_users_roles[$poster->uid] = 'poster';
  activity_insert($poster->uid, 'facebook_status', 'facebook_status', 'update', $data, $target_users_roles);
}

Avant tout, nous allons créer une copie de notre fichier que nous allons nommer facebook_status.origine.module et qui sera notre version de référence pour effectuer notre comparaison.

Maintenant nous allons pouvoir apporter toutes nos modifications au fichier facebook_status.module. Dans notre cas nous allons ajouter une nouvelle entrée au tableau data, qui contiendra l’id du statut.

'status-id' => $status->sid.

1. Repérer les différences avec la commande diff

A ce stade nous avons nos deux fichiers, l’original et le modifié. La commande diff va nous permettre de voir la différence entre les deux fichiers :

$ diff facebook_status.module.origine facebook_status.module
1558a1559
>     'status-id' => $status->sid,

La comparaison entre la version originale et la nouvelle version nous indique qu’entre la ligne 1558 et 1559 une différence a été trouvée. Ici c’est une nouvelle ligne qui a été insérée, on peut le voir grâce au symbôle ‘>’. Dans le cas d’une suppression le symbôle aurait été ‘<‘.

La commande diff permet également de connaître les différences entre les fichiers de deux répertoires. Pour cela, il suffit d’ajouter le paramètre -r à la commande :

diff -r facebook_status.module facebook_status_origine.module

2. Créer le fichier de patch

Nous allons maintenant créer un fichier contenant cette modification que l’on pourra appliquer facilement par la suite. Nous allons réutiliser la fonction diff avec l’option -u qui en plus de notre différence va nous donner les 3 lignes avant et après notre modification.

$ diff -u facebook_status.module.origine facebook_status.module > facebook_status.module.patch
$ cat facebook_status.module.patch
+++ facebook_status.module.origine    "2010-03-04"
+++ facebook_status.module    "2010-03-01"
@@ -1556,6 +1556,7 @@
   $data = array(
     'owner' => theme('username', $owner),
     'poster' => theme('username', $poster),
+    'status-id' => $status->sid,
     'status-unformatted' => check_plain($status->status),
     'status-themed' => theme('facebook_status_item', $status),
     'status_time' => $status->status_time,

Les différences trouvées ont été enregistrées dans un fichier nommé facebook_status.module.patch.

3. Patcher avec la commande patch

Maintenant que nous avons un fichier patch exploitable nous allons pouvoir l’appliquer à la version originale de notre fichier. Vous pouvez supprimer le fichier facebook_status.module et renommer le fichier facebook_status.module.origine en facebook_status.module afin que les choses retournent à leur état initial ou tout simplement retélécharger le module.

Pour mettre à jour notre fichier, rendez vous dans le repertoire du fichier à patcher et utilisez la commande patch :

$ patch < facebook_status.module.patch
patching file facebook_status.module

Votre fichier est maintenant patché, vous pouvez l’ouvrir pour visualiser les modifications.

Edit :

Dans le cas ou vous auriez à appliquer votre patch à l’ensemble d’un dossier vous pouvez ajouter l’option p0 à la commande patch comme le soumet Julien Dubois

$ patch -p0 < facebook_status.module.patch

Julien Dubreuil

Vous avez une idée, un projet web à réaliser ?

Ensemble, mettons en oeuvre sa réussite. Je vous accompagne dans vos projets, depuis l'élaboration du cahier des charges jusqu'à la mise en production. Pour plus d'information n'hésitez pas à me contacter.

Contactez-moi