Using Pre Commit on Golang Project
Are you using Git to manage your code? Have you ever heard of hooks? pre-commit hook?
Git is one of many version control that exist nowadays. Git helps developer, programmer, engineer to manage their code, versioning their project, library or even just as file storage.
Hook is an operation that could be executed before, or after our main operation.
So pre-commit is an operation that executed right before the commit processed on git. We can use pre-commit to do things like linter/formatter, or automatic testing.
I used Go in my projects, and i wrote test script to automatically testing the project itself.
As your information, my go projects use glide to manage dependencies. Its created a directory called vendor to store all of my dependencies.
Why use glide instead of go get or govendor? Well, such a long story. Maybe another time.
So, how do i run my test?
go test ./...
Above command will running go test into every sub-directory/sub-packages on active directory or active project.
But, because i’m using glide (govendor will got this too) an error occured because it test the dependencies too.
So i need to exclude the vendor directory.
Unfortunately, go test doesn’t have such parameters to exclude directory/package (as my experience).
But, that’s not a problem since we have go list command and grep command.
Go list is a command that provided by go itself to print list of packages. (go list -h) And Grep is an utility to search from any input, it could be text, or files. And grep have a lot of search options.
go list ./...
With the command above, we can see all of our packages within the active directory including sub packages. And of course my vendor package.
go list ./... | grep -v /vendor/
With above command, the output from go list becoming an input on grep command. Parameter -v means that we are going to select any lines that aren’t match with the parameter value. Which is in this case is /vendor/.
So with this command, i’ll get any of my packages and sub packages without any vendor package. Lets integrate with go test command
go test $(go list ./... | grep -v /vendor/)
With above command, our test will be running only through our packages and not vendor packages.
So, lets write our pre-commit script. pre-commit script will be written in bash/sh language.
The original file is listed on gosample app from tokopedia, here.
The only changes that i’ve made is the go test command.
How to use the pre-commit script that we wrote?
-
I simply put the file into my main project, with the name pre-commit.sh
-
Give an executable permission to that file
-
And link the file into the .git/hooks directory
ln -s $(pwd)/pre-commit.sh $(pwd)/.git/hooks/pre-commit
Examples when i’m running git commit, the pre-commit running before committing the changes.
If the test failed, the commit itself will be canceled.
But, what if we need to do the commit even the test failed?
git commit -m 'message' --no-verify
There you go!