Go itself has a built-in set of tools for building go programs and running them. The dependencies and configuration are mostly handled automatically. This makes initial development fast and easy, but eventually, more complex requirements surface and require soome type of automation. I’ve seens lots of different approaches:

  • My work uses a custom-built tool written in go to manage packaging, deployment, signing, etc.
    This works well but is a lot of effort to write and maintain for a small project, especially multiple small ptojects doing the same thing.

  • Make is the “traditional” C-language tool, but most of its features are already in go. It does offer the ability to specify targets and efficiently rebuild only steps that have changed.

  • Using shell scripts makes integration with shell tools (often needed for signing or building packages) easy. But the developer needs to remember all the scripts and their dependencies.

I ran across a promising go tool called Mage. The idea is to write your “magefile” (one character from a makefile) as a go program, with a thin application wrapper that finds the right magefile, builds and runs it, then invokes funcs from it based on the command line targets specified. It can even extract inline comments from the magefile as help for the command line. A very promising approach!

I was needing a script of some kind to package up a project into a deb, so I played around with mage. It was easy to handle invoking dependencies prior to steps that needed them. I didn’t see any built in handling for dependency tree checking, so users would need to roll their own. Also missing were utility functions for moving and copying files around in bulk. The go libraries provide some for individual files, but tasks like creating a build directory and copying a whole tree into it would have to be implemented individually in each magefile.

My overall impression was a promising tool that still had some significant gaps. The final straw was running into a panifc when testing the magefile I was working on; mage eats the stack track, making debugging unnecessarily difficult. A little searching revealed it was a known bug with a PR open to fix it – and the PR had been open for about a year. That suggests the project has been abandoned. Which is a shame, it looked interesting and useful.

I ended up writing a shell script to do the packaging, which was simple and convenient. I was able to reuse the same script on a different project with only a few minor changes. Next time I need to do that, I’ll look at nfpm.