Invoke
I am preparing to write a series of articles that provide a number of
Makefile
templates that can be used in various projects. I
try to avoid editorializing in articles, so I wrote my opinions about
Make in The Make Dilemma
blog entry. In that blog entry, I talked about using Python to script commands and
lamented that “library” code would need to be copied between projects if
the scripts do not make use of external libraries. Thinking about how I
would design an external library for this purpose, I discovered that it
already exists! Invoke is a task
invocation utility that might be a suitable alternative to Make.
Over ten years ago, I used a library called Fabric to script execution of commands on servers. I stopped using it only because it was very slow to switch to Python 3, and I had completely stopped using Python 2. If I were to create a new library to use instead of Make, I would incorporate some of the design of Fabric. Looking it up, I discovered that it is still maintained, and it is now built on top of a library called Invoke, which is sort of like Fabric without the networking support.
Invoke tasks are generally
written in a tasks.py
file, though other files can be used
in complex projects. Each task is defined as a function, and the
decorator can be used to specify metadata, including help text and
“pre-tasks” (the tasks that should be run beforehand). Keyword
parameters are exposed on the command line. Tasks can be implemented
using the full power of Python, making it much easier to
implement things than with Make/shell, with far fewer pitfalls. A task
named clean
is run using invoke clean
, for
example.
Invoke meets the constraints that I listed in The Make Dilemma. It is general-purpose and can be used to support developing software on many different systems. Python is more portable than Make/shell. It adds a build dependency to projects, but the dependency is readily available in Debian, Fedora, and Arch.
Perhaps the most difficult aspect of using Invoke would be maintaining
backwards-compatibility with old versions. It is actively developed, but
using new features would result in failure when used with old versions
of the software. Perhaps targeting the version used by Debian would be
appropriate. (Note that Make is very old and changes little, so one
generally does not have to worry about such issues when writing
Makefile
s.)
Invoke seems promising, but I will not know how suitable it is until I try it. Perhaps I will try it out with PhatSort.