Top Reference Material
Here’s the reference material I use to help guide me on basic style, design, and general idiomatic Go practices.
|Go Style Guide||A guide to writing Go code.|
|Uber Go Styleguide||A thorough stylistic guide (opinionated, but great explanations on why)|
|Practical Go - Dave Cheney||A great practical guide from a well-respected authority in the Go community|
I saved this as a snippet for vscode to get up and running quickly with something better than the defaults for handling
func main isolation. I’ve been working on modifying this a bit as I don’t really like using args, but am trying not to overcomplicate things as a new gopher.
I tend to like better flag parsing than using args, but it’s still a better pattern to get functions isolated from main to easily test.
The gist that I’ve taken from this and discussions in the community is ensure that
main is where program termination is dedicated instead of handling this in your functions. This isolation of logic from main ensures you can more easily setup your tests as well, since
func main() isn’t testable.
- Go test will automatically ignore directories and files starting with
_, see go command - cmd/go - pkg.go.dev.
What are Go Modules?
Go Modules are primarily a dependency management solution.
Is primarily a dependency management tool, not a project organization tool.
Is imported to get access to public exported members in your own project.
One module can have
A module can be used in a monorepo or single CLI tool.
A module doesn’t:
- Handle build or binary path metadata.
- Have any relationship to the produced artifacts.
Use canconical import path (aka)
github.com/sheldonhull/mygomodif you want to support
mymod.localif no need to support remote imports or installs.
- This allows
gofumptand tooling to correctly sort the imports from standard library apart from your own imports, without requiring canonical name format.
- This allows
Stick with one module in the repo if possible, to simplify tooling, linting, and testing. This is important in monorepos as much of the tooling that uses paths like
go test ./...will not work with multi-module repos in a project.
Project & Build Tooling
devtools.goto create a list of cli tools that should be installed with Mage.
_ "remotemodulename"in, and identify clearly that a tool such as Stringer or linters are not dependencies for the primary module, but instead are tooling dependencies.
Using Pre-Commit Tooling
Here’s how to setup pre-commit for Go projects.
- Install pre-commit for macOS:
brew install pre-commitor see directions for curl/other options for WSL, Windows, Linux, etc.
- Use the template from TekWizely/pre-commit-golang: Pre-Commit hooks for Golang with support for Modules
- Several options are provided for
fmtoriented commands. Comment out any duplicates that don’t apply.
- Several options are provided for
- Finally initialize the pre-commit hooks in your repo by running:
Validate everything is working by running:
pre-commit run --all-files
Periodically, you can run
pre-commit autoupdate to ensure the latest version of the pre-commit hooks are upgraded.
At this stage, I’m using zerolog as I found it very easy to get moving with structured logs.
The output of this demo looks pretty good!
Here’s a functional demo that can be used to bootstrap a new project with this.
Code Coverage Report
original post: 1
![gopherbadger-tag-do-not-edit]()in the readme, and then this gets replaced with a code coverage percentage badge.
- Generate the required code coverage reports using:
This can ensure default behavior is processed on each OS, customizing the shell to use.
Add this to your
.vscode/tasks.json file and you’ll get the full linting output in your problems pane.
By default, the
golangci-lint config should include
--fast to avoid impact to your editing.
This will ensure all tasks that a pre-commit check or CI check will be run and provided in the problems panel.
Run Nicely Formatted Test Output
While the testing extension is great, sometimes I just want to see a console summary. This task uses Tparse and provides a nicely formatted summary (including coverage numbers, cached tests, and more).
Install tparse with:
go install github.com/mfridman/[email protected].
Run manually like this:
GOTESTS='slow' go test ./... -v -cover -json | tparse -all
go install gotest.tools/[email protected].
Then run like this:
gotestsum or try the alternative formats like:
gotestsum --format dots-v2 or
--format pkgname, or
Principles I’ve gleaned over-time and am quoting or bookmarking.
Don’t hide the cost
Source: Bill Kennedy in Ultimate Go 3
If we are doing construction to a variable, we use value construction. Avoid pointer semantic construction if not in the return.
Making cost obvious and visible is a big priority for readable maintainable code with a team.