We use Go (golang) a lot at CoreOS, and we’ve built up a lot of internal knowledge about how best to develop Go projects.
This document serves as a best practices and style guide for how to work on new and existing CoreOS projects written in Go.
- Wherever possible, use the latest official release of go
- Any software shipped in the CoreOS image should be developed against the version shipped in the CoreOS image
Go style at CoreOS essentially just means following the upstream conventions:
It's recommended to set a save hook in your editor of choice that runs goimports
against your code.
- Always run goimports (which transitively calls
gofmt
) andgo vet
- Use table-driven tests wherever possible (example)
- Use travis to run unit/integration tests against the project repository (example)
- Use SemaphoreCI to run functional tests where possible (example)
- Use GoDebug
pretty.Compare
to compare objects (structs, maps, slices, etc.) ([example] godebug-compare-example)
- Carefully consider adding dependencies to your project: Do you really need it?
- Manage third-party dependencies with godep
Idiomatic golang generally eschews creating generic utility packages in favour of implementing the necessary code as locally as possible to its use case.
In cases where generic, utility code makes sense, though, move it to github.com/coreos/pkg
.
Use this repository as a first port of call when the need for generic code seems to arise.
When creating Docker images from Go projects, use a combination of a .godir
file and the golang:onbuild
base image to produce the most simple Dockerfile for a Go project.
The .godir
file must contain the import path of the package being written (i.e. etcd's .godir contains "github.com/coreos/etcd").
When in need of more sophisticated logging than the stdlib log package provides, use the shared CoreOS Log package (aka capnslog
)
In anything other than the most basic CLI cases (i.e. where the stdlib flag package suffices), use Cobra to construct command-line tools.
- Use
gvm
to manage multiple versions of golang and multiple GOPATHs