One Makefile to rule them all

I work with a lot of differents tools and languages, and switching before projects has become more and more painful. I do not use every technology I know at the same time, and sometimes it can take a few months for me to work on a previous project.

If forget how to use those tools all the time. They all have their specificities; database migrations are dealt with with different commands in python, ruby and php, for instance. More importantly, you can create your own commands or scripts to suit the workflow of a specific project.

The best way I’ve found to ensure all the frequents commands I need are documented somewhere is to have a Makefile at the root of the project. Makefile are archaic and complicated, but they are widespread. I’ve fought in order not to use this tool for years, without finding something better.

With a Makefile, when I pickup a project 6 months later, all I have to do is to quickly browse the Makefile in order know what are the commands I need. Or I can run make [TAB][TAB] and see what the available commands are, or run make help (thanks marmelab).

This project is no exception:

.PHONY: install run test deploy draft publish help

install: ## install the necessary dependencies
	sudo apt-get install fzf
	bundle install

run: ## starts the webserver that displays the blog
	bundle exec jekyll serve

deploy: ## Deploy the latest version of the blog on the web 
	git push origin master

# make draft title="my new draft"
draft: ## create a draft
	bundle exec jekyll draft "$(title)"

publish: ## turn a draft into a post for publication 

unpublish: ## turn a post into a draft

	@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'

I wrote this article with a few commands like:

make draft title="One Makefile to rule them all"
make publish (it opens fzf to choose which article should be published)
git commit
make deploy

In another project, we use a Makefile in order to centralize all the useful Docker, django and postgresql commands.

See a typo ? You can suggest a modification on Github.