This Makefile was always out-of-date because it was impossible to test it. These days, we maintain a "best practice" showcase of a Python app at https://github.com/niteoweb/pyramid-realworld-example-app/ and that repo has a fully functional Makefile built according to the specs below.
We use Makefiles for all our projects to have a memorable way to install and run them, while allowing discovering of advanced commands.
The idea is that if I switch to a project I haven't worked on in a while, I know that I can run tests with make test
and that I can start the program with make run
. Any other commands, and more info about what they do in the background is always available inside the Makefiles.
This is heaps better than having basic commands documented in the docs
folder:
- I don't have to consult documentation all the time, for every project, since there are slight differences between projects. Instead we have sane default for the 20% of commands we type in 80% of the time.
- The commands in documentation tend to bitrot fast since only people new to the project use them directly, seniors either have bash aliases or other shortcuts made for themselves. By keeping shortcuts in Makefile, everyone uses them and they keep on working.
We use a .installed
file to mark most recent installation timestamp. Then when you run, for example, make run
, Makefile will check if environment specification files (such as Pipfile
and Pipfile.lock
) have been modified after .installed
. If yes, then an installation is required, and make run
will first run the install
step, only then the run
step.
This allows people that are not full-time on the project and/or do not have experience with projects build requirements, to stay away from traps such as "oh, you should first reinstall X because yesterday we added dependency Y". If dependencies change, make
will know that (re)installation is required.
All projects' Makefiles should provide the following commands, if applicable:
See make install
Force re-installation of the project. Even if .installed
is newer than Pipfile
and Pipfile.lock
.
Run the program. For example, start Pyramid webserver in development mode.
Run all unit tests. Supports filter=foo
to run only a subset of tests that have foo
in their (file)name.
Run all Selenium-based browser tests. Supports filter=foo
to run only a subset of tests that have foo
in their (file)name.
Format the codebase, for example with black
.
Sort all imports, to avoid doing it manually.
Run static type analysis over the codebase, to chase down potential bugs.
Run linters such as flake8
, to chase down potential bugs
Run all lintes, type checks, formatting and lastly all unit tests.
Run Postgresql in frontend mode. Usually provided via a Docker container.
Start/stop Postgresql in backend mode. Usually provided via a Docker container.
Purge and recreate a development Postgresql database, populate it with dummy data. In projects that rely on databases, this step is usually required before running make run
.
Remove any installed/compiled files so we can start from scratch. Usually followed by make install
to do a "nuke-from-orbit" type of re-installation in case of strange bugs.
See Makefile
in this repository.
In the terminal, find out the locale type supported by the system by running locale -a
.
And then, add the following line to your Makefile with the supported locale type by your system.
export LC_CTYPE=en_GB.UTF-8