Remember all the commands of a project with Makefile
Problematic
When we want to build our application, whatever the language, there are usually a ton of commands to remember.
Here is an example that we can find when we develop in PHP and Javascript:
composer install # Install the PHP dependencies
php artisan key:generate # Generate a secret key
php artisan test # Execute the PHP tests
php artisan test --testsuite=Feature --stop-on-failure # An other command of the tests
yarn # Install the NodeJS dependancies
yarn test # Execute the NodeJS tests
php artisan migrate # Migrate the database
php artisan db:seed # Populate the database with fake data
./node_modules/.bin/eslint my-file.js # Lint the code
# Format the code# ...# etc ...# ...
The problem is: the more technologies we have, the more terminal commands we have to remember.
And if we have several projects at the same time, we run the risk of getting confused by forgetting the commands.
And now, imagine leaving this project for 2 months, and trying to re-understand how to compile your project :/
Makefile
One solution I use on a daily basis is to use a Makefile. It is an utility installed by default in all linux distributions, used first for the C language.
Basically, Makefile is a utility that scans files and runs commands whether files need to be recompiled or not. However, here, we can use it to “store” the important commands of our project.
In software development, Make is a build automation tool that automatically builds executable programs and libraries from source code by reading files called Makefiles which specify how to derive the target program. Though integrated development environments and language-specific compiler features can also be used to manage a build process, Make remains widely used, especially in Unix and Unix-like operating systems. Wikipedia
The basic structure
The usage is very simple. First, create a file named Makefile
. The syntax inside is very simple:
.PHONY: my_command_namemy_command_name: ## A little documentation here echo "The real command behind"
You must indent with a tabulation and not 4 spaces!
Here is an example of a real case:
.PHONY: installinstall: ## Install the application cp -n .env.example .env pnpm install --workspace-root --recursive
.PHONY: serveserve: ## Serve for development docker-compose up
The help command
Paste this on the top of your Makefile:
.DEFAULT_GOAL := help.PHONY: helphelp: @egrep -h '\s##\s' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m %-30s\033[0m %s\n", $$1, $$2}'
.PHONY: serveserve: ## Serve for development docker-compose up
Then use the make
command and press enter ! 🎉
Makefile tips
Use environment variables from .env
file
First create a .env
file in the root project directory and define your variables like this:
MY_VARIABLE="Hello World !"MY_VARIABLE_2="Hello World 2 !"
Then, we can include
the file and use the variable with the $(VARIABLE)
syntax:
include .env
.PHONY: testtest: ## Display variables from ".env" file echo $(MY_VARIABLE)
Hide commands:
In some cases, if we use password or API keys in our commands, we can write a @
in front of our commands like this:
.PHONY: deploydeploy: ## Deploy the application @deploy $(SSH_URL) $(SSH_KEY)
Here, the command @deploy $(SSH_URL) $(SSH_KEY)
won’t be displayed on screen.
Define variables
We can define variables on top of the file like this:
pwd := $(dir $(abspath $(firstword $(MAKEFILE_LIST))))
Use global variables
If we want to export locally variables for our tasks, we can put this line on the top of the file:
export DOCKER_BUILDKIT=1
Note: the exported variables are only available in the Makefile context.
Full example
Here is a full example:
name=alex
include .env # Include environment file# export DOCKER_BUILDKIT=1# pwd := $(dir $(abspath $(firstword $(MAKEFILE_LIST))))
.DEFAULT_GOAL := help.PHONY: helphelp: @grep -E -h '\s##\s' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m %-30s\033[0m %s\n", $$1, $$2}'
.PHONY: exampleexample: ## This is an example echo "Hello World"
.PHONY: npm_unpm_u: ## Install node_modules ncu -i
.PHONY: echo_var_env_fileecho_var_env_file: ## Example echo "Hello $(name)"
.PHONY: example_with_variableexample_with_variable: ## Example with variable @NAME=$$(echo -n "Alex"); \ echo "Hello $$NAME"
The SOLID/STUPID principles
Learn what are the SOLID and STUPID principles with examples
Create a Docker Swarm playground
Let's create Docker Swarm playground on your local machine
Setup a Kubernetes cluster with K3S, Traefik, CertManager and Kubernetes Dashboard
Let's setup step by step our own K3S cluster !
Create an Ansible playground with Docker
Let's create an Ansible playground with Docker
Database ACID/BASE - Understanding the CAP Theorem
Learn what is the CAP Theorem in less than 5 minutes !
HashiCorp Vault - Technological watch
Learn what is HashiCorp Vault in less than 5 minutes !
How to internationalize an AstroJS website while maintaining good SEO ?
We will see how to create an implementation of i18n with AstroJS
LFTP - Deploy an application in command line
Here we will see how to automatically deploy an application with lftp in command line.