Makefile-driven development

💡 idea: good Makefile interface = important development tool


Today at the office my coworker asked why my UI tests ran so fast.

me: we can run them async now.
coworker: really?
me: yep. just use this command.
coworker: oh. didn't know we had that command.

lesson #1: without an interface, automation tools don’t get used


Here’s how I imagine the interaction between the README.md and its neighbors:

              x    
            x   x
          x       x
        x  Makefile x
      xxxxxxxxxxxxxxxxx
    x     README.md     x 
  xxxxxxxxxxxxxxxxxxxxxxxx
x        source code        x 
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx                      

The README is typically used for day-1 items (how to I get this thing up and running?) and more meta concerns (why should I use this package in the first place?)

As a result, the README rots quickly unless you’re onboarding new devs very frequently.

If you want to keep track of how to use your project on a daily basis, the best option I’ve found is to use a Makefile.

lesson #2: have a Makefile!


Back to my coworker.

Why didn’t he just look at the Makefile?

Because the Makefile had a bad user interface.

Here’s an interaction with a typical Makefile.

targetName:
    long cryptic cmd --mystery_arg='foo' --hmm_whats_this && do_this_too

Even if you understand each command perfectly, you may not understand the context of when/why you’d run it.

lesson #3: don’t let your Makefile user interface suck!


Now, the fun part: a solution!

Just add a short table of contents:

# Makefile
help:
    @echo
    @echo "📊 CODE QUALITY"
    @echo
    @echo "lint:    lint using flake8"
    @echo "test:    run unit tests, view basic coverage report in terminal"
    @echo "cov:     view HTML coverage report in browser"
    @echo
    @echo "📦 DEPENDENCIES"
    @echo
    @echo "pipfr:   freeze dependencies into requirements.txt"
    @echo "pipin:   install dependencies from requirements.txt"
    @echo "piprs:   remove any installed pkg *not* in requirements.txt"
    @echo

Then, next time you need to recall a workflow, just run make help:

📊 CODE QUALITY

lint:    lint using flake8
test:    run unit tests, view basic coverage report in terminal
cov:     view HTML coverage report in browser

📦 DEPENDENCIES

pipfr:   freeze dependencies into requirements.txt
pipin:   install dependencies from requirements.txt
piprs:   remove any installed pkg *not* in requirements.txt

This is what I’ve done lately and it’s been working for me.