composer install avec Make

Je vois très souvent Make utilisé comme un simple lanceur de scripts (chose que Composer sait déjà faire), ce qui est passer à côté de sa plus intéressante fonctionnalité : ne faire quelque chose que lorsque c’est nécessaire.

Make figures out automatically which files it needs to update, based on which source files have changed.

Pour ce faire, on ajoute des prérequis à nos cibles : une cible est ce qu’on veut créer (ou mettre à jour), et ses prérequis de quoi elle dépend. Les commandes qui vont créer ou mettre à jour une cible constituent une recette. Ce trio compose une règle, à placer dans un Makefile pour être lue par Make :

cible: prérequis
	recette

Si l’on exécute make cible, alors

Revenons à Composer : notre cible est le dossier vendor qui est créé ou mis à jour par composer install, faisant de cette commande la recette. Celle-ci se basant sur le seul fichier composer.lock, ce dernier est donc le prérequis. CQFD !

vendor: composer.lock
	composer install

— Make se base sur le mtime, ça ne pose pas de problème avec le fait que vendor est un dossier ?

mtime pose tout un tas de problèmes… Notamment, celui d’un dossier n’est mis à jour que lorsqu’un fichier est ajouté, supprimé ou renommé à sa racine, ce qui empêche généralement d’en faire une cible convenable… si la recette ne met pas elle-même à jour le mtime !

En l’occurrence, Composer « touche » le dossier vendor après une installation pour cette exacte raison ; son mtime sera donc toujours correct.

— Et composer.json alors ?

On peut effectivement trouver sur Internet des versions de cette règle ajoutant composer.json comme prérequis. C’est une mauvaise idée.

Composer met lui-même composer.lock à jour à partir de certaines données présentes dans composer.json. Si ces dernières changent, la présence de composer.json dans les prérequis est donc inutile.

Imaginez maintenant qu’une autre donnée change, comme description. Make exécuterait de nouveau composer install, mais puisque changer la description n’implique aucun changement dans le dossier vendor, le mtime de ce dernier ne serait pas mis à jour. Il se retrouverait donc plus vieux que composer.json, poussant Make à tenter de le mettre à jour encore et encore, pour rien.