Cory LaNou
Sun, 17 Mar 2019

Don’t Commit Improperly Formatted Go (golang) Code

Overview

This article will outline how in just a few easy steps using git hooks how to ensure you never commit improperly formatted code.

I work on a lot of Go (golang) projects, and I still see simple things going wrong. One of them is improperly formatted Go code. I also include in the category of improperly formatted to mean any code that didn’t use go imports to sort the import statements.

On the surface, many people might think this is me being a little over-critical of the code quality. In part, that is true. However, the real issue is the fact that it creates unnecessary code-churn in your commits and code diffs. For instance, if I edit a file and make a one line change, but the code wasn’t formatted properly when I got to it, it may result in 10 lines of code changing that have nothing to do with my actual change. This leads to confusion in PR reviews, changes the blame on a line of code that shouldn’t have changed, etc.

All of this is very avoidable if you are using a technology like git and employ a hook.

You’ll find a directory in your git project at the root in .git/hooks. In there will already be some .sample hooks for you to look at. We are interested in the pre-commit hook.

This is what my pre-commit hook looks like for all of my Go projects:

#!/usr/bin/env bash

fmtcount=`git ls-files | grep '.go$' | xargs gofmt -l 2>&1 | wc -l`
if [ $fmtcount -gt 0 ]; then
    echo "Some files aren't formatted, please run 'go fmt ./...' to format your source code before committing"
    exit 1
fi

vetcount=`go vet ./... 2>&1  | wc -l`
if [ $vetcount -gt 0 ]; then
    echo "Some files aren't passing vet heuristics, please run 'go vet ./...' to see the errors it flags and correct your source code before committing"
    exit 1
fi
Note: I didn’t come up with this pre-commit file. I learned this trick working with the great developers at Influx Data.

I have this in a gist as well. To install this gist in a pre-commit hook for your project, run these commands (be sure to be in the root of your project first):

# from the root of your project:
curl -o .git/hooks/pre-commit https://gist.githubusercontent.com/corylanou/3639c901965922d5507ce4acf539de4a/raw/e535b525c408b5b145fed5d17c854c2a6dc90216/pre-commit
chmod +x .git/hooks/pre-commit

And that’s it! Now, the next time you try to commit code that doesn’t pass go fmt or go vet you will get an error like this:

$ commit 'test'
Some files aren't formatted, please run 'go fmt ./...' to format your source code before committing

Feel free to contact me with suggestions and feedback on this article on twitter.

More Articles

The Training Paradox: Why AI Makes Expert Training More Important, Not Less

Overview

Here's the counterintuitive truth emerging from two years of AI coding assistants: the better you already are at programming, the more AI helps you. The worse you are, the more it can hurt. This is creating a widening skills gap in software development, and it's exactly the opposite of what everyone predicted when ChatGPT launched. Training isn't becoming obsolete. It's becoming the difference between thriving with AI and drowning in AI-generated technical debt.

Learn more

Expert Go Training, Now in Your AI Assistant

Overview

What if your AI coding assistant had instant access to 30+ years of Go training expertise? Not the jumbled mess of Stack Overflow and GitHub repos it usually learns from, but actual, curated, battle-tested best practices from thousands of hours teaching Go in production environments. We're building that. It's in beta now, and if you've ever trained with Gopher Guides, you get free access.

Learn more

A Smoother Path to Go Mastery: What's New in Our Training Platform

Overview

Over the past three months, we've been obsessively focused on eliminating friction in the learning experience. The result? A training platform where you can download entire courses with one click, jump from course material directly into your editor, and navigate content that feels like it was built for how developers actually learn. These aren't flashy features. They're thoughtful improvements that get out of your way so you can focus on mastering Go.

Learn more