Tools to Help you Go

Write Maintainable Golang Code

Tom Maiaroto
Serif & Semaphore
4 min readApr 9, 2016

--

We’re all guilty of it — we sometimes don’t follow style guidelines, we pull in a dependency and then fail to really “depend” on it, or we end up with a bit more complexity in our code than we’d like.

I’ll be the first to admit that I do this all the time. I see writing software like sculpting. There’s two primary ways to go about it; 1. you can either start with a block and remove material (subtractive) or, 2. you can add more material to create the work (additive).

Perhaps not a perfect analogy, but my point is that coding is as much a creative process as it is a technical one. Creative processes are subject to change and a little mess and that’s ok.

Though this process leaves us with technical debt and maintenance challenges. Code readability is as important as test cases; especially when working with teams or in an open-source context.

I’ve always found Node.js to have good tools to help with this. Perhaps it’s due to static typing and gofmt that Go has less tools to help with code quality than Node.js. Or maybe it’s just because Node.js currently has a larger community.

I’m happy that there’s been more tooling for Go over the past year or so. Maybe this is a sign of adoption, maturity, and a growing community.

I’ve come up with a new practice for all of my Go code (and I’ll try to do a good job practicing what I preach). I use the following tools in a Git hook.

Linting & Style Guidelines

Golint
Go already comes with gofmt and govet which are wonderful tools, but they simply format your code and make sure it runs. Honestly, that’s all they should do because we may want to adopt our own style guidelines.

Many editors and IDEs will automatically run gofmt for you upon file save anyway. So it makes little sense to run on a Git hook.

If you want to follow Golang’s community style guidelines, you’ll want to use Golint.

My very dirty code.

Cyclomatic Complexity

Gocyclo
This one always escapes me! I realize later on that I could have reduced complexity or broke things into separate functions, but it’s always been something I looked at later on.

Code Climate is a wonderful service and it does support Golang! However, it doesn’t show you cyclomatic complexity (which it does for other languages like JavaScript). It only runs gofmt, govet, and golint (above).

There are actually several packages that give you the tools for this. I prefer gocyclo. Your tolerance for this will likely be to taste.

Dependencies & Redundancy

Depscheck
Interfacer
A very important component of writing maintainable code if your project’s dependencies.

You can “vendor” packages and avoid leftpad syndrome — it’s a common thing for Gophers to do. However, maybe you could’ve simplified things and simply put what you needed from the dependency into your own code (license depending).

It’s very easy to find a package and want to use it because it’s awesome. The problem is when you then only end up using a very small portion of it. Sometimes for a single function. Maybe it’s still awesome, but just more awesome for someone else’s code.

Depscheck is a great tool to help you determine when you might not be so dependent upon a dependency.

How about unnecessary interfaces? How many times have you wrote an interface with good intentions, but then later realized it wasn’t necessary? There’s a tool for this too, it’s called interfacer.

Unused Code

check
errcheck

Aside from pointless interfaces, I think a bigger culprit of maintenance woes is unused code. Don’t allow variables, struct fields, and constants to become orphans! It can really confuse people (and you, a few months later).

Check and errcheck both help tremendously with this. Check can even find inefficiently packed structs.

SQL Injection

safesql

This one is a bit of a bonus, but certainly noteworthy if you use SQL. It’s not so much a concern of maintenance, but security is related to code quality.

Trust Yourself

With all of these tools, it’s important to note that there can be some false positives. Treat all of these as suggestions, but I feel that they do a good job and will help lead you to making good decisions. Don’t forget to trust your own best judgement.

I’m sure I’m missing a few handy tools; however, I feel that these are among the most common tools needed to ensure code quality and help reduce technical debt.

Gitting Hooked

What good are all these tools if they are a pain in the neck to use? You’ll forget them all, really.

To help me form a good habit, I’ve added all of the above tools to a Git hook that you can find here (also seen below). You’re more than welcome to use it yourself of course. You may wish to edit it a bit first if you don’t want or need all of the tools listed above. You might also want to add a few.

A few coloring decisions have been made. You can remove those by easily commenting and uncommenting specific lines. It should be fairly straight forward.

Remember, these tools take a while to run. You may want to put this on a pre-push hook so you aren’t slowed down by every commit. That is, of course, if you like to make frequent commits.

You should even be able to run this script through your favorite CI tool.

I hope this helps you write better Go code, like it helped me!

--

--