Générer des templates dynamiques avec mason

Introduction

Mason est un package utilisé pour générer à la volée des fichiers et/ou dossiers en fonction de la saisie de l’utilisateur depuis son terminal. Cette génération est possible grâce aux templates appelés bricks. Celles-ci sont entièrement personnalisables et peuvent être créées comme on le souhaite.

Créé par Felix Angelov, le package est open source et il invite la communauté à partager leurs bricks développées sur le site BrickHub.

Découverte du package

Installation

Partez d’un dossier vide et exécutez les commandes suivantes :

1  dart pub global activate mason # Installation de mason via dart
2  mason —version # Vérifie le bon déroulement de l'installation

Initialisez votre projet à la racine de votre dossier :

1  mason init # Initialise votre projet mason

Cette commande va générer les fichiers/dossiers suivants :

📁 .mason : à ignorer. Il aide Mason à retrouver les templates, vous pouvez l’ajouter dans le .gitignore en cas de publication sur git.

📄 mason.yaml : L’équivalent d’un pubspec.yaml sur un projet Flutter, mais à la place de définir vos dépendances, vous allez définir vos bricks. Pour chaque brique, définissez le nom de la brick et le chemin pour y accéder. Une brick peut également être importée via une url git.

Première utilisation

Par défaut un projet Mason a la brick HELLO dans ses dépendances. Elle permet de générer un fichier HELLO.md avec le contenu Hello [input]! 👋 à la racine du projet. Pour se faire, lancez la commande suivante qui va déclencher un prompt name :

1  mason make hello

Comme pour de nombreux packages, plusieurs options de commandes sont disponibles. Par exemple, pour changer la destination du fichier généré, pré-remplir la saisie ou écraser le fichier précédemment généré.

1  mason make hello -o docs/ --name Toto --on-conflict overwrite

On peut également avoir un fichier de configuration pour remplacer la saisie en prompt.

1  mason make hello -o docs/ -c config.json --on-conflict overwrite

Première brick mason

La base d’un template

Pour la section suivante, nous avons souhaité créer une brick qui permet de générer un bouton Flutter. En spécifiant le nom du fichier, le texte du bouton et sa hauteur, le template devra générer un bouton respectant la nomenclature et les paramètres passés depuis la console.

Pour initialiser une nouvelle brick Mason, il vous faut exécuter la commande suivante :

1  mason new button_widget

Mason vous génère un nouveau dossier button_widget. Dans ce dossier, on y retrouve un dossier nommé __brick__. Ce dossier contient l’ensemble des dossiers et/ou fichiers générés par le template. Il y a aussi d’autres fichiers tels que license, readme et changelog pour de la gestion de version et potentielle publication.

La figure ci-dessus représente le contenu du fichier brick.yaml qui a été ajouté lors de la commande de création de brick. On y retrouve le nom, la description et la version de la brick. Le paramètre vars est défini : il permet d’indiquer les variables demandées lors de la génération du template en prompt dans la console d’exécution.

Génération d’une première brick

Pour compléter notre brick qui va nous servir à générer le bouton, on crée le template à générer avec tous ses paramètres d’entrées.

Mason utiliser la syntaxe moustache pour rendre ses templates dynamiques. Par exemple, si le nom d’un fichier doit être complété en fonction de ce qui est spécifié dans la console, on définit le nom du fichier avec la syntaxe suivante {{fileName.snackCase()}}. L’ajout de la fonction snack va permettre de respecter les bonnes pratiques en terme de nomenclature de fichier.

(Cf. les fonctions disponibles avec la syntaxe moustache).

Dans notre dossier __brick__, on crée un fichier avec la nomenclature précédemment expliquée. Le contenu du fichier contiendra la rédaction du bouton sous la syntaxe Flutter et moustache pour les paramètres dynamiques :

Après l’execution de la commande mason make, le terminal nous demande d’entrer les valeurs des variables du template, précédemment configuré dans notre fichier brick.yaml :

Après avoir complété le template, le fichier est complètement généré. La fig. 3 représente le code généré dans notre projet Flutter.

Mais comment importer le script d’exécution d’une brick mason dans un projet existant ? Comme pour l’initialisation de Mason, la commande mason init est nécessaire. Une fois le fichier généré, vous devez ajouter votre brick à l’aide de la commande :

1  mason add [brick_name] --path [path]
2  ou 
3  mason add [brick_name] --git-url [url]

Une fois la configuration effectuée, vous pouvez exécuter la commande mason make.

Le premier template est terminé, de manière générale la création d’un template n’est pas très difficile et requiert peu de connaissance du package mason. La syntaxe moustache peut sembler particulière au début mais elle se comprend très vite.

Une brick approfondie

Notre objectif principal en utilisant Mason était de générer une brick qui génère des dossiers et fichiers liés à des project respectant la clean architecture sous Flutter. En début de projet, la création des fichiers est très redondant et contient un grand nombre de fichiers partagés entre les différents projets bien que leurs buts soit différents.

Nous avons créé une brick permettant de générer notre architecture de projet en copiant le contenu de notre fichier core qui est très répétitif et le fichier features où l’on retrouve nos fonctionnalités. Comme le montre le dossier _template dans la figure 5 ci-dessous, son architecture de fichier ne change jamais pour respecter la nomenclature de la clean architecture mais les noms de fichiers s’adaptent en fonction des fonctionnalités du projet.

En suivant les mêmes principes que le précédent exemple, nous avons définis des noms de fonctionnalités en tant que variable dans le brick.yaml :

Cette variable features est un tableau : pour chaque nom de fonctionnalité, le template générera un dossier et plusieurs sous fichiers. La syntaxe moustache permet de boucler sur des tableaux de variables.

Dans notre template nous avons défini en nom de fichier la syntaxe suivante :

1  {{#features}}{{.}}{{/features}}

:warning: La plupart des IDE reconnaissent le / comme un identifiant de nouveau sous-fichier. Visuellement votre nom de template ne ressemblera pas à ce que vous souhaitez obtenir mais lors de l’exécution du template, la syntaxe moustache sera reconnue et Mason va générer correctement les fichiers.

Lors de la création de cette brick, nous avions pensé utiliser un fichier de configuration permettant de définir des noms de fonctionnalités totalement personnalisés. Cependant, lors de l’installation d’une brick, un utilisateur qui ne connait pas la brick, n’aura pas connaissance de la typologie et nomenclature du fichier de configuration à créer donc il ne sera pas comment utiliser la brick.

Conclusion

Mason est un très bon outil de génération de dossiers et/ou fichiers. Il peut être utilisé pour la mise en place d’architecture de projet pour éviter le duplica redondant ou la création de fichier très peu interactifs.

D’après notre première expérience, il devient moyennement avantageux quand il s’agit de créer des templates très dynamiques qui requièrent de nombreuses variables. L’utilisation d’un fichier de configuration pourrait régler le problème des templates dynamiques mais pour une utilisation très restreinte au sein d’une même entreprise voire équipe. Les possibilités de templates semblent tout de même assez génériques. Par exemple, pour la création d’entité ou de templates qui sont liés à des packages externes, cela nous semble ‘too much’ et ce serait finalement plus compliqué à mettre en place et à entretenir.

Sources : GitHub | mason et Youtube | Very Good Ventures .

Vous souhaitez en savoir plus ? Contactez-nous !

Clément MARCHAIS – Développeur Mobile
Maxime BIZERAY – Développeur Mobile
Anthony TAIEB – Développeur Mobile