Makefile with Python

en in code • 4 min read

I like when everything is easy. I like to open some repository and in as a few steps as possible to run the 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 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: help prepare-dev test lint run doc

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

.DEFAULT: help
help:
    @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 a 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 the 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 a dependency for all tasks, I can change my Python dependencies and just run the tests. Makefile will ensure that a 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 convinced? Well, I don’t force you to use it, I’m just saying why I love to use them. :-)





You may also like



Popular from code