Golang Tips and Tricks

The following are some basics on GoLang.

How to

Quick start

  1. Install Go: brew install go

  2. You may want to use docker which is what build systems will use

    docker pull golang:1.15.4
    docker run -rm -v "$PWD":/code -w "/code" golang:1.15.4 go build -v
  3. Install Go plugin to your favorite Editor (e.g., go-plus for Atom)

  4. Setup your repo

  5. If a library then it should be in $GOPATH/src/<url path>

General project layout

GitHub - golang-standards/project-layout: Standard Go Project Layout

Universal files:

  1. README.md - Every project should have one
  2. LICENSE.md - Every project should have one
  3. run - A script to easily build or test the code
  4. go.mod - initialize as a module go mod init <name>
  5. go.sum - commit this if it exists.

/cmd/<name>

This is the place for the main package.  It should build into an executable.  <name> should be the name of the command you want to build.  You will build it via go build cmd/<name>.

Not much code should be here.  Just a means to load stuff from /internal, or /pkg.

/internal

Private code should be here.  This is enforced by the compiler

/pkg

Library code that is ok for others to use.

/vendor (managed)

This directory is (or should be) managed by your dependency manager and not by you directly.

/build

Not universally recommended, but if your build system takes scripts then it should be /build/ci and then linked to whatever location the build system wants it to actually be.  Where possible it is just a thing wrapper around run.

Tools

  1. go - The general tool for go
  2. devel - Go debugger
  3. GitHub - tsliwowicz/go-wrk: go-wrk - a HTTP benchmarking tool based in spirit on the excellent wrk tool
  4. goimports - An improved fmt tool that also handls imports

Libraries

Command Tools

GitHub - spf13/cobra: A Commander for modern Go CLI interactions

Configuration Loading

Database

Examples:

  1. concourse/atc/db - Does not use an ORM or Migration library, example of how to do it manually

DB Drivers

DB ORMs

  1. https://gorm.io - A Rails-type ORM similar to ActiveRecord.
  2. https://github.com/go-pg/pg - Golang ORM with focus on PostgreSQL features and performance
  3. https://godoc.org/github.com/Masterminds/structable - Simple Struct to DB mapper / recorder

DB Migrations

  1. https://github.com/golang-migrate/migrate - Database migrations. CLI and Golang library. This is library agnostic.
    1. It has a BinData source driver that allows SQL migration files to be loaded directly into binary.
  2. https://gorm.io - A Rails-type ORM similar to ActiveRecord, with a similar migration style
    1. WARNING: in practice these style migration are fragile as there is a tight coupling to the record.

Git

https://pkg.go.dev/github.com/go-git/go-git/v5 - A pure Golang implementation of Git

Gerrit

Note

As a Google maintained project all Golang code is maintained in public version of their GitOnBorg system which uses Gerrit as the review system. To contribute to the main golang code base you have to understand Gerrit.

Gerrit is the code review system used by Google’s Public GoLang team.

Changes (cls) are created by pushing to a special branch called refs/for/<target branch>. This opens the Equivalent of a GitHub PR. With the difference being that in Gerrit a commit is the unit of work, and in GitHub the branch is.

Topics are a way of associating changes across multiple repos. It is interfaced by using the config push.pushOption = topic=<name>, or doing it via an option during the push: git push ... -o topic=<name>, or git push origin HEAD:refs/for/main%topic=<name>.

https://github.com/andygrunwald/go-gerrit - Gerrit API client

Graphs

  1. https://github.com/dominikbraun/graph - Generic graph data-structure

HTTP

  1. http - The Go Programming Language

  2. GitHub - justinas/alice: Painless middleware chaining for Go - Allows Middlewares

  3. GitHub - throttled/throttled: Package throttled implements rate limiting access to resources such as HTTP endpoints.

  4. GitHub - justinas/nosurf: CSRF protection middleware for Go.

HTTP Router / MUX

  1. GitHub - vmihailenco/treemux: Fast and flexible HTTP router

Logging

  1. log - The logging package is enough if all you want to do is add a date

Structured Logging

In most cases structured logging is what you want.

  1. slog - slog augments log by adding levels, and fields. It is usually enough.

  2. GitHub - sirupsen/logrus: Structured, pluggable logging for Go. - Dead project as of 2020-11

  3. GitHub - rs/zerolog: Zero Allocation JSON Logger

  4. GitHub - uber-go/zap: Blazing fast, structured, leveled logging in Go.

  5. GitHub - apex/log: Structured logging package for Go.

Merging Objects

GitHub - imdario/mergo: Mergo: merging Go structs and maps since 2013.

Metrics (prometheus)

prometheus · pkg.go.dev


Parsing

YAML

  1. https://gopkg.in/yaml.v2 - Built-in yaml.v2
  2. sigs.k8s.io/yaml - YAML parser from K8s / Helm
    1. Use this one when YAML and JSON inter-opt is needed.
// Reading unstructured yaml
data := map[string]interface{}{}

bytes, err := yaml.Parse(fileBytes,&data)
if err != nil {
  return nil, err
}

Static Files

GitHub - markbates/pkger: Embed static files in Go binaries (replacement for gobuffalo/packr)

Testing

BDD

TDD

https://github.com/smartystreets/goconvey - A nicer testing framework, more TDD like