/ GoLang

MAKE me a gopher

I mostly work on Linux (ubuntu) or OS-X hence about 99% of what I do (apart from coding) happens on the cli, chores like running the program that I just wrote or launching the testing stack in watch-mode for faster feedbacks. But sometimes these commands can get handful and you find yourself writing long paragraphs to do simple things. To get around this specific problem I tend to define aliases for various tasks in my .zshrc, these are more generic in nature and not address/target a specific project, chores like committing, pushing, cleaning docker images or getting tree view of changes (commit logs) fall into this category.

Today I'd like to show you what I do to manage project specific commands. During the long stretches of day and night on my trusty computer, I discovered that I usually do following on (almost) all of my (recent) projects. (In no specific order)

  • test (one shot -- used mostly by the CI)
  • test (watch -- used mostly during development)
  • run
  • compile
  • build a docker image
  • push the docker image
  • CI related build and release commands

To accomplish above mentioned tasks I use a utility called make. Make is actually an ancient and battle tested tool used to build (as the name suggests) targets (usually files). In a nutshell, we can tell to build a target by invoking something like make <target>, as I just said make assumes that target is a file on disk, and it will only run commands associated to that target if and only if the target is non-existent or the file's last updated timestamp has changed since the last run. Our purpose here is a bit different, we just want to tie some commands to an alias and use that to take care of our chores. Following example uses a term called .PHONY, this term tells make that the target is actually a phony and just run the target each and every time it's invoked.

I usually just use above mentioned constructs to get things done. As an exercise, let's create a Makefile for dockerized whose code is available at github.

This Makefile builds and pushes docker images. Please read through static linking, versioning and docker articles to understand how and why the statically linked executable is generated, how version is embeded in the binary, and how the docker image is generated using a multi-stage Dockerfile.

Following Makefile is well commented and self explanatory, I'll still try and explain the basic flow.

Firstly, we define all the go commands as constants, it makes life easy during maintenance of the file. Then we detect the OS, we do this because we want the script to be able to run on linux as well as OS-X. Typical go run command would not need OS but we are actually building a statically linked binary which would require OS for which to create the binary. It would enable us to invoke make run or make bin on any OS (linux / OS-X; I don't really care about windows), it would just work. Then we define testing and docker related targets. And thats it. Please read through docker to understand how to write Dockerfile for a typical project. (Below is a typical Dockerfile for a golang project)

try running make docker or make bin or make run.

Thats it!

Dave Amit

Dave Amit

Howdy folks! I am Dave Amit, an accidental programmer, father to a lab puppy, hubby to a beautiful wife, addicted to puzzles & a noob blogger. This is my effort to simplify odd codes from the wild.

Read More