Basculer un projet Drupal 8 existant sous composer

switch

Composer est devenu incontournable pour des projets Drupal 8 relativement ambitieux. Même si il est encore possible d'initialiser un projet Drupal 8 avec drush ou encore tout simplement en téléchargeant une archive zip, ces deux méthodes peuvent devenir limitantes avec le temps. Ou tout du moins ne pas faciliter l'installation de nouveaux modules ayant des dépendances sur des librairies tierces.

Une autre des raisons que j'ai pu rencontrées, pour lesquels certains projets Drupal 8 n'ont pas été initiés par Composer, est l'absence de support de Composer sur certains hébergements mutualisés, même dits professionnels.

Si le démarrage d'un projet sans Composer peut donner l'impression de gagner du temps au début (en court-circuitant une phase nécessaire d'appropriation de Composer), cela peut très vite devenir chronophage, et le gain de temps initial s'estomper à vue d'oeil.

Arrive le moment inéluctable où il faut s'appuyer sur Composer pour gérer simplement ne serait-ce que les modules installés.

Basculer un projet Drupal 8 existant sur une base de code géré par Composer peut se faire relativement facilement.

Créer un nouveau projet basé sur Composer

En premier lieu, initialiser un nouveau projet avec le template Composer recommandé (et si nécessaire installer Composer au préalable).

composer create-project drupal-composer/drupal-project:8.x-dev NEW_PROJECT --stability dev --no-interaction

Cette commande va créer un nouveau répertoire NEW_PROJECT, et télécharger la dernière version de Drupal, et ses dépendances

Le répertoire initialisé va ressembler à ceci

├── config
├── drush
├── scripts
├── vendor
└── web

Installer les modules et thème contribués actifs sur le nouveau projet

C'est la partie la plus rébarbative de la procédure, surtout si le nombre de module activé est conséquent. Il est nécessaire d'installer les différents modules ou thèmes contribués, activés sur le projet, avec Composer.

Vous pouvez lister les différents modules depuis la page de configuration Extensions, ou encore lister les modules avec une commande drush.

drush pml | grep "Enabled"

Ce qui vous permet d"obtenir la liste des modules activés, ainsi que leur version.

 Administration       Admin Toolbar (admin_toolbar)                                                       Module  Enabled        8.x-1.24    
 Administration       Admin Toolbar Extra Tools (admin_toolbar_tools)                                     Module  Enabled        8.x-1.24    
 Chaos tool suite     Chaos tools (ctools)                                                                Module  Enabled        8.x-3.0     
 Custom               Linkit (linkit)                                                                     Module  Enabled        8.x-4.3     
 Field types          Datetime (datetime)                                                                 Module  Enabled        8.6.3       
 Field types          File (file)                                                                         Module  Enabled        8.6.3       
 Field types          Image (image)                                                                       Module  Enabled        8.6.3       
 Field types          Link (link)                                                                         Module  Enabled        8.6.3       
 Field types          Options (options)                                                                   Module  Enabled        8.6.3       
 Field types          Text (text)                                                                         Module  Enabled        8.6.3       
 Multilingual         Interface Translation (locale)                                                      Module  Enabled        8.6.3       
 Multilingual         Language (language)                                                                 Module  Enabled        8.6.3       
 Other                Contact storage (contact_storage)                                                   Module  Enabled        8.x-1.0-bet 
 Other                Pathauto (pathauto)                                                                 Module  Enabled        8.x-1.3     
 Other                Redirect (redirect)                                                                 Module  Enabled        8.x-1.3     
 Other                Redirect 404 (redirect_404)                                                         Module  Enabled        8.x-1.3     
 Other                Token (token)                                                                       Module  Enabled        8.x-1.5     
 SEO                  Metatag (metatag)                                                                   Module  Enabled        8.x-1.7     
 SEO                  Metatag: Open Graph (metatag_open_graph)                                            Module  Enabled        8.x-1.7     
 SEO                  Simple XML Sitemap (simple_sitemap)                                                 Module  Enabled        8.x-2.12    
 Spam control         Antibot (antibot)                                                                   Module  Enabled        8.x-1.2     
 Spam control         Honeypot (honeypot)                                                                 Module  Enabled        8.x-1.29    
 Statistics           Matomo Analytics (matomo)                                                           Module  Enabled        8.x-1.7     
 Bootstrap            Bootstrap (bootstrap)                                                               Theme   Enabled        8.x-3.13    

Et ainsi pour chaque module présent sur le projet existant, vous pouvez les installer avec la commande, par exemple pour le module redirect.

composer require drupal/redirect ~1.3

et ceci pour chaque module.

Une autre alternative, au lieu de lancer cette commande module par module est de compléter le fichier composer.json avec cette liste de module, la version minimum à récupérer, puis de lancer la commande

composer update --with-dependencies

Afin de mettre à jour et télécharger tous les modules renseignés dans le fichier composer.json.

Récupérer les fichiers utilisateurs

Une fois tous les modules actifs téléchargés sur le nouveau projet basé sur Composer, il ne reste plus qu'à copier les fichiers utilisateurs (généralement le répertoire sites/default/files), les modules custom le cas échéant, ainsi que les librairies, configurer le fichier settings.php pour la connexion à la base de données.

Et le tour est joué.

Pensez à vider les caches avant d'accéder à votre nouveau projet basée cette fois sur Composer, afin de reconstruire le Registre des modules, au cas où ces derniers n'auraient pas été installé dans le répertoire modules/contrib sur le projet existant.

Versionner le code source d'un projet Drupal

Selon votre hébergement, vos contraintes et processus de déploiement, et si vous utilisez git (très recommandé)  il peut être intéressant de versionner tout le code source de Drupal. En effet par défaut, le template Drupal Composer exclut les répertoires suivants.

# Ignore directories generated by Composer
/drush/contrib/
/vendor/
/web/core/
/web/modules/contrib/
/web/themes/contrib/
/web/profiles/contrib/
/web/libraries/

Vous pouvez commenter ces lignes afin de pouvoir versionner l'intégralité de votre base de code. Néanmoins, certains modules ou librairies tierces peuvent ne pas être versionnés car le processus de téléchargement aura utilisé une commande git clone, et à ce titre aura créé un répertoire .git dans le répertoire du projet, excluant ce répertoire (par la présence d'un submodule git) de votre base de code principale versionnée.

Afin de pouvoir versionner l'intégralité de la base de code, nous pouvons modifier légèrement le comportement du template Composer du projet.

Nous allons modifier le fichier ci-dessous afin de rajouter une commande nous permettant de supprimer les répertoire .git présents dans les 2 répertoires principaux vendor et web après chaque commande de mise à jour effectuée avec composer.

scripts/
└── composer
    └── ScriptHandler.php

Nous rajoutons ces nouvelles méthodes à la classe ScriptHandler

protected static function getDrupalRoot($project_root) {
  return $project_root .  '/web';
}

protected static function getVendorRoot($project_root) {
  return $project_root .  '/vendor';
}

public static function removeGitDirectories(Event $event) {
  $root = static::getDrupalRoot(getcwd());
  exec('find ' . $root . ' -name \'.git\' | xargs rm -rf');
  exec('find ' . $root . ' -name \'.gitignore\' | xargs rm -rf');
  
  $vendor = static::getVendorRoot(getcwd());
  exec('find ' . $vendor . ' -name \'.git\' | xargs rm -rf');
  exec('find ' . $vendor . ' -name \'.gitignore\' | xargs rm -rf');
}

Puis dans le fichier composer.json, nous modifions la section scripts pour obtenir

"scripts": {
    "drupal-scaffold": "DrupalComposer\\DrupalScaffold\\Plugin::scaffold",
    "pre-install-cmd": [
        "DrupalProject\\composer\\ScriptHandler::checkComposerVersion"
    ],
    "pre-update-cmd": [
        "DrupalProject\\composer\\ScriptHandler::checkComposerVersion"
    ],
    "post-install-cmd": [
        "DrupalProject\\composer\\ScriptHandler::createRequiredFiles",
        "DrupalProject\\composer\\ScriptHandler::removeGitDirectories"
    ],
    "post-update-cmd": [
        "DrupalProject\\composer\\ScriptHandler::createRequiredFiles",
        "DrupalProject\\composer\\ScriptHandler::removeGitDirectories"
    ]
},

Ainsi, à chaque commande d'installation ou de mise à jour lancée avec composer, les éventuels sous-modules git créés seront alors supprimés, permettant de versionner l'intégralité du code source sous le même projet.

Cette stratégie de versionner ou non l'intégralité de la base de code n'est pas à appliquer systématiquement. Elle doit être évaluée projet par projet, selon votre organisation, vos processus de déploiement et la nature de vos projets, depuis un simple site Drupal 8 jusqu'à une usine à site Drupal. Un conseil auprès d'un développeur Drupal, ou auprès de vos équipes DevOps si vous en disposez, ne sera très certainement pas inutile.

 

Commentaires

Ajouter un commentaire