Makefile with Python

I like when everything is easy. I like to open some repository and in as few steps as possible to run example and see how it works. Ideally just call run and that's it.

Python is great, Python makes a lot of things very easy. But tooling around, mostly packaging, is not working well. It has a lot of flaws. I'm used to to fix this with Makefile. Some people are furious about that and argue that it's only for building C codes. Well… maybe. But I prefer to be practical.

Check out why I think it's very simple and good to use:


.PHONY: all prepare-dev test lint run doc

VENV_NAME?=venv
VENV_ACTIVATE=. $(VENV_NAME)/bin/activate
PYTHON=${VENV_NAME}/bin/python3

all:
	@echo "make prepare-dev"
	@echo "       prepare development environment, use only once"
	@echo "make test"
	@echo "       run tests"
	@echo "make lint"
	@echo "       run pylint and mypy"
	@echo "make run"
	@echo "       run project"
	@echo "make doc"
	@echo "       build sphinx documentation"

prepare-dev:
	sudo apt-get -y install python3.5 python3-pip
	python3 -m pip install virtualenv
	make venv

# Requirements are in setup.py, so whenever setup.py is changed, re-run installation of dependencies.
venv: $(VENV_PATH)/bin/activate
$(VENV_NAME)/bin/activate: setup.py
	test -d $(VENV_PATH) || virtualenv -p python3 $(VENV_PATH)
	${PYTHON} -m pip install -U pip
	${PYTHON} -m pip install -e .
	touch $(VENV_PATH)/bin/activate


test: venv
	${PYTHON} -m pytest

lint: venv
	${PYTHON} -m pylint
	${PYTHON} -m mypy

run: venv
	${PYTHON} app.py

doc: venv
	$(VENV_ACTIVATE) && cd docs; make html


It's very simple base Makefile which I like to start with at any project. It helps me to install all dependencies I need without searching and run project (or tests, or lints or whatever) without remembering how the tool for it look like.

The best feature is how Makefile works. Notice venv target. It says that it needs to have script venv/bin/activate which needs setup.py. Makefile will run venv target only when you remove (or don't have yet) virtual environment or you change setup.py. Because I use venv as dependency for all tasks, I can change my Python dependencies and just run the tests. Makefile will ensure that virtual environment is updated.

So… maybe Makefile is only for compiling codes… but anyway I think this is very clever. I could use normal bash scripts, sure, but why? It's hard to keep them executable in git repository, not fast to type and I would need to write logic which Makefile already provides.

Not conviced? Well, I don't force you to use it, I'm just saying why I love to use them. :-)