Aller au contenu

Gagnez du temps avec Cookiecutter !

Mise à jour :

logo cookiecutter

Si vous avez déjà passé des heures à configurer la structure d’un nouveau projet, Cookiecutter est fait pour vous ! Cet outil, basé sur Python, permet de générer automatiquement des structures de projets personnalisées à partir de templates. Que vous soyez développeur ou administrateur système, il simplifie vos débuts et garantit une cohérence dans vos environnements de travail. Plus besoin de copier-coller vos anciens projets : avec Cookiecutter, tout est prêt en quelques commandes.

Fonctionnement de Cookiecutter

Cookiecutter repose sur des templates et un fichier cookiecutter.json pour personnaliser vos projets. Avec l’utilisation de Jinja2, vous pouvez ajouter des logiques dynamiques et rendre vos templates extrêmement flexibles. Ces concepts sont les bases pour maîtriser cet outil et automatiser la création de structures adaptées à vos besoins.

Template Cookiecutter

Un template est une structure prédéfinie qui sert de base à vos projets. Il s’agit généralement d’un dépôt Git (local ou distant) contenant tous les fichiers et dossiers nécessaires à votre projet. Ce template peut être aussi basique qu’un fichier unique ou aussi complexe qu’une architecture complète de microservices.

Voici un exemple de structure de template :

  • Répertoiremy-template/
    • Répertoire{{cookiecutter.project_name}}/
      • init .py
      • main.py
    • README.md
    • cookiecutter.json
  • {{cookiecutter.project_name}} : Les accolades indiquent une variable dynamique. Elle sera remplacée par la valeur que vous spécifiez lors de l’exécution de Cookiecutter.
  • cookiecutter.json : Ce fichier contient les variables et leurs valeurs par défaut, définissant les réponses attendues.

Moteur de rendu Jinja2

Cookiecutter utilise Jinja2, un moteur de template Python, pour générer les fichiers finaux. Cela permet d’intégrer des logiques dynamiques dans les fichiers ou noms de fichiers.

Dans un fichier README.md :

# Bienvenue dans {{ cookiecutter.project_name }}
Auteur : {{ cookiecutter.author_name }}

Résultat généré :

# Bienvenue dans Mon Projet
Auteur : Stéphane ROBERT

Une variable comme {{ cookiecutter.project_name }} dans un chemin de fichier sera remplacée dans l’arborescence finale.

Le fichier cookiecutter.json

Ce fichier est au cœur du fonctionnement de Cookiecutter. Il contient les variables dynamiques que vous pouvez personnaliser. Voici un exemple :

{
"project_name": "Mon Projet",
"author_name": "Stéphane ROBERT",
"version": "0.1.0",
"description": "Un projet Python génial",
"license": ["MIT", "GPLv3", "Apache 2.0"]
}
  • Valeurs par défaut : Chaque clé a une valeur par défaut (par exemple, "Mon Projet" pour project_name).
  • Choix multiples : Utilisez des listes pour permettre de choisir parmi plusieurs options (comme pour license).
  • Personnalisation avancée : Vous pouvez ajouter autant de variables que nécessaire pour répondre à vos besoins spécifiques.

Interaction avec l’utilisateur

Lorsque vous exécutez la commande suivante :

Terminal window
cookiecutter https://github.com/author/template-repo

Cookiecutter vous posera une série de questions basées sur les variables définies dans le fichier cookiecutter.json. Par exemple :

Terminal window
project_name [Mon Projet]:
author_name [Stéphane ROBERT]:
version [0.1.0]: 1.0.0
description [Un projet Python génial]: Mon super projet
license [MIT]: Apache 2.0

Les valeurs que vous entrez seront utilisées pour générer vos fichiers.

Prêt à créer un projet avec Cookiecutter ? Passons à la pratique !

Installation de Cookiecutter

Installer Cookiecutter avec Pipx est une solution élégante pour éviter les conflits entre les dépendances de vos projets Python. Contrairement à une installation classique avec pip, où les packages sont installés dans l’environnement Python global, Pipx isole chaque outil dans son propre environnement virtuel. Résultat : vos outils restent indépendants les uns des autres, tout en étant accessibles globalement.

C’est idéal pour des outils en ligne de commande comme Cookiecutter, car cela évite les incompatibilités ou les mises à jour accidentelles qui pourraient casser vos projets existants.

Installation de Pipx

Si vous n’avez pas encore Pipx, commencez par l’installer. Voici comment procéder :

Terminal window
python3 -m pip install --user pipx
python3 -m pipx ensurepath

Une fois installé, vérifiez que tout fonctionne correctement :

Terminal window
pipx --version
1.4.3

Installation de Cookiecutter avec Pipx

L’installation de Cookiecutter est maintenant un jeu d’enfant :

Terminal window
pipx install cookiecutter

Une fois l’installation terminée, vous pouvez vérifier que Cookiecutter est disponible avec :

Terminal window
cookiecutter --version
installing cookiecutter
installed package cookiecutter 2.6.0, installed using Python 3.12.3
These apps are now globally available
- cookiecutter
done! 🌟

Utilisation de cookiecutter

Après l’installation, essayez de générer un projet simple pour tester. Par exemple :

Terminal window
cookiecutter https://github.com/audreyfeldroy/cookiecutter-pypackage

Création d’un template avec Cookiecutter

Créer votre propre template Cookiecutter est une excellente façon de standardiser vos projets et de gagner un temps précieux. Cela permet de partager des structures prêtes à l’emploi avec votre équipe ou de réutiliser des configurations spécifiques à vos besoins. Voici un guide pratique pour créer votre premier template.

Préparez la structure de base

Un template Cookiecutter est simplement un répertoire contenant les fichiers et dossiers qui composeront votre projet final. La clé est d’utiliser des variables dynamiques pour personnaliser ces fichiers et leurs contenus.

Voici une structure typique pour un template :

  • Répertoiremy-template/
    • Répertoire{{cookiecutter.project_name}}/
      • init .py
      • main.py
      • Répertoireconfig/
        • setting.yml
    • README.md
    • cookiecutter.json
  • {{cookiecutter.project_name}} : Ce répertoire prendra le nom du projet défini par l’utilisateur.
  • cookiecutter.json : Contient les variables dynamiques pour personnaliser le template.
  • Fichiers statiques : Ils sont copiés tels quels dans le projet généré.

Créez le fichier cookiecutter.json

Le fichier cookiecutter.json définit les variables que l’utilisateur pourra personnaliser. Chaque clé correspond à une variable, et chaque valeur fournit une valeur par défaut ou une liste d’options.

{
"project_name": "Mon Projet",
"author_name": "Stéphane ROBERT",
"version": "0.1.0",
"description": "Un projet Python génial",
"use_docker": ["yes", "no"]
}
  • Valeurs par défaut : Si l’utilisateur ne fournit pas de réponse, la valeur par défaut sera utilisée.
  • Options multiples : Pour use_docker, l’utilisateur devra choisir entre “yes” et “no”.

Ajoutez des variables dynamiques

Dans les fichiers de votre template, utilisez les variables définies dans cookiecutter.json pour les personnaliser. Les variables sont entourées de doubles accolades ({{ }}).

Dans le fichier README.md de votre template :

# Bienvenue dans {{ cookiecutter.project_name }}
Auteur : {{ cookiecutter.author_name }}
Version : {{ cookiecutter.version }}
{{ cookiecutter.description }}

Ce fichier sera automatiquement rempli avec les valeurs saisies par l’utilisateur.

Testez votre template

Avant de partager votre template, testez-le pour vérifier qu’il fonctionne correctement.

Lancez la commande suivante dans le répertoire contenant votre template :

Terminal window
cookiecutter /chemin/vers/mon-template

Ensuite, répondez aux questions et examinez le projet généré pour vous assurer qu’il est conforme à vos attentes.

Partagez votre template

Une fois votre template prêt, partagez-le pour que d’autres puissent l’utiliser. Vous pouvez l’héberger localement, sur un partage réseau, ou sur une plateforme comme GitHub.

  1. Initialisez un dépôt Git :

    Terminal window
    git init
    git add .
    git commit -m "Premier commit"
  2. Poussez votre template vers un dépôt distant :

    Terminal window
    git remote add origin https://github.com/mon-utilisateur/mon-template.git
    git push -u origin main

Pour utiliser ce template, les utilisateurs pourront exécuter :

Terminal window
cookiecutter https://github.com/mon-utilisateur/mon-template

Maintenez et versionnez votre template

Avec le temps, vous voudrez peut-être mettre à jour votre template ou en publier plusieurs versions. Utilisez Git pour gérer les modifications et les versions.

Ajoutez des tags pour identifier des versions spécifiques :

Terminal window
git tag v1.0.0
git push origin v1.0.0

Les utilisateurs peuvent choisir une version spécifique en utilisant :

Terminal window
cookiecutter https://github.com/mon-utilisateur/mon-template --checkout v1.0.0

Utilisation avancée de Cookiecutter

Une fois que vous maîtrisez les bases de Cookiecutter, il est temps de passer à des fonctionnalités plus avancées pour tirer le meilleur parti de cet outil. Ces techniques permettent d’automatiser encore davantage vos processus, d’intégrer des workflows complexes et d’adapter les templates à des besoins spécifiques.

Utilisation des hooks

Les hooks dans Cookiecutter sont des scripts spéciaux qui permettent d’exécuter des tâches à différents moments de la génération du projet. Pour que ces scripts fonctionnent correctement, leurs noms doivent respecter une convention précise. Voici les trois principaux hooks et leurs rôles :

pre_prompt.py

Ce hook s’exécute avant que l’utilisateur ne soit invité à répondre aux questions définies dans le fichier cookiecutter.json. C’est le moment idéal pour effectuer des validations préliminaires ou définir des conditions spécifiques.

Si vous souhaitez vérifier qu’une variable d’environnement est définie avant de poser des questions :

import os
import sys
def main():
if not os.getenv("MY_ENV_VARIABLE"):
print("Erreur : La variable d'environnement MY_ENV_VARIABLE est requise.")
sys.exit(1)
if __name__ == "__main__":
main()

pre_gen_project.py

Ce hook s’exécute après que l’utilisateur a répondu aux questions, mais avant que le projet ne soit généré. Il est utile pour valider les réponses, ajouter des modifications aux variables ou préparer des ressources nécessaires.

Vérifiez si le nom du projet contient des caractères non autorisés :

import re
import sys
def main():
project_name = "{{ cookiecutter.project_name }}"
if not re.match("^[a-zA-Z0-9_-]+$", project_name):
print("Erreur : Le nom du projet ne peut contenir que des lettres, chiffres, tirets ou underscores.")
sys.exit(1)
if __name__ == "__main__":
main()

post_gen_project.py

Ce hook s’exécute après que le projet a été généré. C’est l’endroit parfait pour effectuer des tâches post-génération, comme l’installation de dépendances, la configuration de fichiers ou l’exécution de commandes supplémentaires.

Automatisez l’initialisation d’un dépôt Git dans le projet généré :

import os
import subprocess
def main():
project_path = os.getcwd()
subprocess.run(["git", "init"], cwd=project_path)
subprocess.run(["git", "add", "."], cwd=project_path)
subprocess.run(["git", "commit", "-m", "Initial commit"], cwd=project_path)
if __name__ == "__main__":
main()

Avec Cookiecutter, vous pouvez conditionner la création d’un fichier (ou d’un dossier) en utilisant le moteur de template Jinja2. Ce dernier permet d’écrire des instructions conditionnelles basées sur les réponses de l’utilisateur fournies via le fichier cookiecutter.json.

Utiliser des conditions

  1. Ajoutez une variable qui déterminera si un fichier doit être créé ou non. Par exemple :
{
"project_name": "Mon Projet",
"author_name": "Stéphane ROBERT",
"include_dockerfile": ["yes", "no"]
}

Ici, la variable include_dockerfile demande à l’utilisateur s’il souhaite inclure un fichier Dockerfile.

  1. Utiliser des conditions Jinja2 pour gérer le fichier

Dans votre template, utilisez une condition pour créer le fichier uniquement si l’utilisateur répond “yes”.

  • Répertoiremy-template/
    • Répertoire{{cookiecutter.project_name}}/
      • init .py
      • main.py
    • README.md
    • {{“Dockerfile” if cookiecutter.include_dockerfile == “yes” else ""}}
    • cookiecutter.json

Cela crée un fichier nommé Dockerfile uniquement si la variable include_dockerfile vaut “yes”. Si ce n’est pas le cas, aucun fichier n’est généré.

  1. Vous pouvez également inclure ou exclure certaines parties du contenu d’un fichier existant en fonction des réponses.

Exemple pour un README.md :

# Bienvenue dans {{ cookiecutter.project_name }}
{% if cookiecutter.include_dockerfile == "yes" %}
Ce projet inclut un Dockerfile pour faciliter la conteneurisation.
{% else %}
Ce projet ne contient pas de Dockerfile.
{% endif %}

Exemples inspirants de Cookiecutter

Voici une sélection d’exemples de Cookiecutter adaptés aux outils et pratiques DevOps. Ces templates offrent des structures prêtes à l’emploi pour démarrer rapidement vos projets.

  1. Cookiecutter Django :
    • Projets Django prêts pour la production.
    • Conteneurisation avec Docker.
    • Intégration CI/CD.
  2. Cookiecutter Ansible Role :
    • Rôles Ansible respectant les bonnes pratiques.
  3. Cookiecutter Flask :
    • Applications Flask avancées.
    • API RESTful et déploiement conteneurisé avec Dockerfiles.
  4. Une liste de templates

Ces exemples sont une excellente source d’inspiration pour démarrer vos projets ou concevoir vos propres templates. Adaptez-les selon vos besoins et gagnez en productivité !

Conclusion

Vous l’aurez compris, Cookiecutter est un outil incroyablement puissant pour automatiser et standardiser la création de projets. Que ce soit pour des applications web, des pipelines DevOps ou des projets de science des données, les templates existants et la flexibilité offerte par Jinja2 vous permettent de gagner du temps et de maintenir une cohérence dans vos workflows. Il ne vous reste plus qu’à explorer, personnaliser et créer vos propres templates pour répondre à vos besoins spécifiques.

Plus d’infos

  1. Site officiel de Cookiecutter
  2. Documentation officielle
  3. GitHub officiel