Dans ce didacticiel, nous verrons comment un développeur Go peut utiliser un Makefile pour développer ses propres applications.
Que sont les Makefiles?
Makefile est un outil d'automatisation incroyablement utile que vous pouvez utiliser pour exécuter et créer des applications non seulement sur Go, mais aussi dans la plupart des autres langages de programmation.
Il peut souvent être vu dans le répertoire racine de nombreuses applications Go sur Github et Gitlab. Il est largement utilisé comme outil d'automatisation des tâches qui accompagnent souvent les développeurs.
Si vous utilisez Go pour créer des services Web, le Makefile vous aidera à résoudre les tâches suivantes:
- Automatisez l'invocation de commandes simples, telles que: compiler, démarrer, arrêter, regarder, etc.
- Gérez les variables d'environnement spécifiques au projet. Il doit inclure le fichier .env.
- Un mode de développement qui se compile automatiquement en cas de changement.
- Un mode de développement qui montre les erreurs de compilation.
- Définition de GOPATH pour un projet spécifique afin que nous puissions stocker les dépendances dans le dossier du fournisseur.
- La surveillance simplifiée des fichiers, par exemple, permet à watch run = "go test. / ... "
Voici une structure de répertoire typique pour un projet:
.env Makefile main.go bin/ src/ vendor/
Si nous appelons la commande make dans ce répertoire, nous obtenons la sortie suivante:
$ make Choose a command run in my-web-server: install Install missing dependencies. Runs `go get` internally. start Start in development mode. Auto-starts when code changes. stop Stop development mode. compile Compile the binary. watch Run given command when code changes. eg; make watch run="go test ./..." exec Run given command, wrapped with custom GOPATH. eg; make exec run="go test ./..." clean Clean build files. Runs `go clean` internally.
Variables d'environnement
La première chose que nous voulons du Makefile est d'inclure les variables d'environnement que nous avons définies pour le projet. Par conséquent, la première ligne ressemblera à ceci:
include .env
Ensuite, nous définissons le nom du projet, les dossiers / fichiers Go, les chemins vers pid ...
PROJECTNAME=$(shell basename "$(PWD)")
Dans le reste du Makefile, nous utiliserons souvent la variable GOPATH. Toutes nos équipes doivent être associées au GOPATH d'un projet spécifique, sinon elles ne fonctionneront pas. Cela fournit une isolation nette de nos projets, mais en même temps complique le travail. Pour simplifier la tâche, nous pouvons ajouter une commande exec qui exécutera n'importe quelle commande avec notre GOPATH.
Cependant, il convient de se rappeler que vous devez utiliser exec uniquement si vous voulez faire quelque chose qui ne peut pas être écrit dans le makefile.
Mode de développement
Le mode de développement devrait:
- Vider le cache de build
- Compiler le code
- Exécutez le service en arrière-plan
- Répétez ces étapes lorsque le code change.
Cela semble facile. Cependant, la difficulté réside dans le fait que nous exécutons simultanément le service et l'observateur de fichiers. Avant de démarrer un nouveau processus, nous devons nous assurer qu'il s'arrête correctement et que nous ne violons pas le comportement habituel de la ligne de commande lorsque vous appuyez sur Control-C ou Control-D.
start: bash -c "trap 'make stop' EXIT; $(MAKE) compile start-server watch run='make compile start-server'" stop: stop-server
Le code décrit ci-dessus résout les tâches suivantes:
- Compile et exécute le service en arrière-plan.
- Le processus principal ne s'exécute pas en arrière-plan, nous pouvons donc l'interrompre à l'aide de Control-C.
- Arrête les processus d'arrière-plan lorsque le processus principal est interrompu. piège est nécessaire juste pour cela.
- Recompile et redémarre le serveur lorsque le code change.
Dans les sections suivantes, je vais expliquer ces commandes plus en détail.
Compilation
La commande compile n'appelle pas simplement go compile en arrière-plan - elle efface la sortie d'erreur et imprime une version simplifiée.
Voici à quoi ressemble la sortie de la ligne de commande lorsque nous avons effectué des modifications de rupture:

compile: @-touch $(STDERR) @-rm $(STDERR) @-$(MAKE) -s go-compile 2> $(STDERR) @cat $(STDERR) | sed -e '1s/.*/\nError:\n/' | sed 's/make\[.*/ /' | sed "/^/s/^/ /" 1>&2
Démarrage / arrêt du serveur
start-server démarre un binaire compilé en arrière-plan, enregistrant son PID dans un fichier temporaire. stop-server lit le PID et tue le processus si nécessaire.
start-server: @echo " > $(PROJECTNAME) is available at $(ADDR)" @-$(GOBIN)/$(PROJECTNAME) 2>&1 & echo $$! > $(PID) @cat $(PID) | sed "/^/s/^/ \> PID: /" stop-server: @-touch $(PID) @-kill `cat $(PID)` 2> /dev/null || true @-rm $(PID) restart-server: stop-server start-server
Suivi des changements
Nous avons besoin d'un fichier de surveillance pour suivre les modifications. J'en ai essayé plusieurs, mais je n'ai pas trouvé de solution appropriée, j'ai donc écrit mon propre outil de surveillance de fichiers -
yolo . Installez-le à l'aide de la commande:
$ go get github.com/azer/yolo
Après l'installation, nous pouvons observer les changements dans le répertoire du projet, à l'exclusion des dossiers du fournisseur et du dossier bin.
Nous avons maintenant une commande watch qui suit récursivement les modifications apportées au répertoire du projet, à l'exception du répertoire du fournisseur. Nous pouvons simplement passer n'importe quelle commande à exécuter.
Par exemple, démarrez les appels make-start-server lorsque le code change:
make watch run="make compile start-server"
Nous pouvons l'utiliser pour exécuter des tests ou vérifier automatiquement les conditions de course. Les variables d'environnement seront définies lors de l'exécution, vous n'avez donc pas à vous soucier de GOPATH:
make watch run="go test ./..."
Une fonctionnalité intéressante de
Yolo est son interface Web. Si vous l'activez, vous pouvez immédiatement voir la sortie de votre commande dans l'interface Web. Il vous suffit de passer l'option -a:
yolo -i . -e vendor -e bin -c "go run foobar.go" -a localhost:9001
Ouvrez localhost: 9001 dans un navigateur et voyez immédiatement le résultat du travail:

Installation de dépendance
Lorsque nous apportons des modifications au code, nous aimerions que les dépendances manquantes soient chargées avant la compilation. La commande d'installation fera le travail pour nous:
install: go-get
Nous automatiserons l'appel d'installation lorsque le fichier change avant la compilation, de sorte que les dépendances seront installées automatiquement. Si vous souhaitez installer la dépendance manuellement, vous pouvez exécuter:
make install get="github.com/foo/bar"
En interne, cette commande sera convertie en:
$ GOPATH=~/my-web-server GOBIN=~/my-web-server/bin go get github.com/foo/bar
Comment ça marche? Voir la section suivante où nous ajoutons des commandes Go régulières pour implémenter des commandes de niveau supérieur.
Commandes Go
Puisque nous voulons installer GOPATH dans le répertoire du projet afin de simplifier la gestion des dépendances, qui n'a pas encore été formellement résolue dans l'écosystème Go, nous devons encapsuler toutes les commandes Go dans un Makefile.
go-compile: go-clean go-get go-build go-build: @echo " > Building binary..." @GOPATH=$(GOPATH) GOBIN=$(GOBIN) go build -o $(GOBIN)/$(PROJECTNAME) $(GOFILES) go-generate: @echo " > Generating dependency files..." @GOPATH=$(GOPATH) GOBIN=$(GOBIN) go generate $(generate) go-get: @echo " > Checking if there is any missing dependencies..." @GOPATH=$(GOPATH) GOBIN=$(GOBIN) go get $(get) go-install: @GOPATH=$(GOPATH) GOBIN=$(GOBIN) go install $(GOFILES) go-clean: @echo " > Cleaning build cache" @GOPATH=$(GOPATH) GOBIN=$(GOBIN) go clean
Aide
Enfin, nous avons besoin de la commande help pour voir une liste des commandes disponibles. Nous pouvons générer automatiquement une sortie d'aide magnifiquement formatée à l'aide des commandes sed et column:
help: Makefile @echo " Choose a command run in "$(PROJECTNAME)":" @sed -n 's/^
La commande suivante analyse le Makefile pour les lignes commençant par ## et les affiche. De cette façon, vous pouvez simplement commenter des commandes spécifiques, et les commentaires seront affichés avec la commande d'aide.
Si nous ajoutons quelques commentaires:
Nous obtiendrons:
$ make help Choose a command run in my-web-server: install Install missing dependencies. Runs `go get` internally. start Start in development mode. Auto-starts when code changes. stop Stop development mode.
Version finale
include .env PROJECTNAME=$(shell basename "$(PWD)")