Auto-documenter son Makefile 🤩

Dans mes différents développements, que ce soit en C, en Python ou en Go, j'utilise toujours un Makefile pour effectuer un certain nombre de tâches. Quand on a un grand nombre de targets, ça peut rapidement devenir fastidieux et compliqué de documenter son Makefile pour que les prochains utilisateurs comprennent ce qu'il fait. 🤯

Pour répondre à cette problématique, j'ai une solution, l'auto-documentation. 🥵

J'utilise dans mes projets un Makefile pour automatiser l'installation, la construction, les tests et le déploiement.  🤗

La plupart des cibles sont standardisées (exemple : make install). Ce genre de cibles est assez explicite mais certaines peuvent l'être beaucoup moins, d'où l'intérêt de documenter et de créer une aide.😜

Pour donner un exemple du résultat obtenu en faisant un simple make:

Please use 'make <target>' where <target> is one of

  help                    Print help on Makefile []
  lint                    Run the code linters [venv]
  fmt                     Run the code formatters [venv]
  build-plugin            Build plugin [venv]
  release                 Build an release [build-plugin]
  install-plugin          Install plugin [build-plugin]
  uninstall-plugin        Uninstall plugin []
  clean                   Clean this project []
  clean-builds            Clean all generated builds []

Check the Makefile to know exactly what each target is doing.

Pour que ça puisse fonctionner, il va falloir se prémunir de plusieurs choses, la première c'est de définir la cible par défaut :

# Defines the default target that `make` will to try to make,
# or in the case of a phony target, execute the specified commands
# This target is executed whenever we just type `make`
.DEFAULT_GOAL = help

Il ne restera plus qu'à définir la cible nommée "help" :

# The @ makes sure that the command itself isn't echoed in the terminal
help: # Print help on Makefile
	@echo "Please use 'make <target>' where <target> is one of"
	@echo ""
	@grep '^[^.#]\+:\s\+.*#' Makefile | \
	sed "s/\(.\+\):\s*\(.*\) #\s*\(.*\)/`printf "\033[93m"`  \1`printf "\033[0m"`	\3 [\2]/" | \
	expand -35
	@echo ""
	@echo "Check the Makefile to know exactly what each target is doing."

Ainsi, il ne restera plus qu'à ajouter des commentaire en face du nom de notre target, la commande sed se chargera d'aller récupérer le commentaire (et les dépendances, cf : []). 😌

Exemple :

clean: # Clean this project
	rm -rf $(VENV)
	find . -type f -name '*.pyc' -delete
	find . -type f -name '*.pyo' -delete
	find . -type d -name "__pycache__" | xargs rm -rf {};

clean-builds: # Clean all generated builds
	rm -f $(PROJECT_SOURCES)/$(BUILD_DIR)/*

fmt: venv # Run the code formatters
	# Format all '.py' files within and underneath current working directory.
	@./$(VENV)/bin/black -l 79 .

Enfin voilà, j'espère que ça vous aura aidé ! 😊