Toolchain Commands
Lookup sheet for lessons 7, 28 through 33.
Everyday
go run ./cmd/svc # build and run, no binary kept
go build ./... # compile everything
go test ./... # run every test
go vet ./... # static checks the compiler does not make
go fmt ./... # canonical formatting; not negotiable
go fix ./... # modernise to current idioms (rebuilt in Go 1.26)
go doc net/http Server # docs for one identifier
go doc -src sync.Once Do # its source, in the terminal
go env GOROOT # where the standard library lives
Modules
go mod init github.com/you/svc
go mod tidy # add what is imported, drop what is not
go mod why example.com/pkg # why is this in the graph
go mod graph # the whole requirement graph
go get example.com/pkg@v1.5.0 # change a requirement
go get -u ./... # upgrade, deliberately
Minimal version selection picks the highest of the required minimums, not the newest published. Builds are reproducible without a lockfile; go.sum is a tamper check, and belongs in version control.
Module at v2 or above needs /v2 in the module path and in imports.
GOPRIVATE=github.com/yourorg/* for internal modules, which skips the public proxy and checksum database.
The go directive sets language semantics (loop variables, timer behaviour). The toolchain directive sets which toolchain builds it.
Testing
go test ./... # cached
go test -count=1 ./... # defeat the cache
go test -v -run 'TestParse/empty' # one subtest
go test -race ./... # data race detector
go test -cover ./... # coverage
go test -fuzz=FuzzRoundTrip # open-ended fuzzing
| Helper | Does |
|---|---|
t.Run(name, fn) | subtest, independent failure, selectable by name |
t.Parallel() | run with other parallel subtests |
t.Helper() | report failures at the caller's line |
t.Cleanup(fn) | teardown that works with subtests and parallel tests |
t.Fatalf / t.Errorf | stop this test / record and continue |
Message convention: Parse(%q) = %v, want %v.
Golden files live in testdata/, which the go tool ignores when building.
Benchmarks
func BenchmarkParse(b *testing.B) {
for b.Loop() { // Go 1.24; setup runs once, results kept alive
Parse("1h30m")
}
}
go test -bench=. -benchmem -count=10 ./... > old.txt
go test -bench=. -benchmem -count=10 ./... > new.txt
benchstat old.txt new.txt
go install golang.org/x/perf/cmd/benchstat@latest
allocs/op is the metric that reproduces across machines. One run is not a measurement.
Profiling
go test -bench=. -cpuprofile=cpu.out -memprofile=mem.out ./...
go tool pprof cpu.out
go tool pprof -http=:8080 cpu.out # flame graph in the browser
go tool pprof http://localhost:6060/debug/pprof/profile?seconds=30
Import _ "net/http/pprof" and serve on localhost only.
| Endpoint | Shows |
|---|---|
/debug/pprof/profile?seconds=30 | CPU |
/debug/pprof/heap | memory (inuse_space by default) |
/debug/pprof/goroutine?debug=2 | every goroutine stack, with block duration |
/debug/pprof/goroutineleak | provably unblockable goroutines (Go 1.27) |
/debug/pprof/block, /mutex | waiting and contention, must be enabled first |
Inside pprof: top, top -cum, list Func, web.
flat = time in this function's own code. cum = including callees.
Heap views: inuse_space for a leak, alloc_space for GC pressure.
Escape analysis
go build -gcflags='-m' ./... 2>&1 | grep escapes
go build -gcflags='-m -m' ./... # the reasoning chain
Common causes: returning a pointer to a local, storing in something that escapes, assigning to an interface, capture by an escaping closure, unbounded make size.
Release build
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build \
-trimpath \
-ldflags="-s -w -X main.version=$(git describe --tags --always)" \
-o bin/svc ./cmd/svc
| Flag | Does |
|---|---|
CGO_ENABLED=0 | static binary, runs in scratch/distroless |
-trimpath | strips local paths, so builds are reproducible and no home directory leaks |
-ldflags="-s -w" | strips symbols and DWARF; drop these if you need readable crashes |
-X pkg.Var=value | sets a string variable at link time |
Security
go install golang.org/x/vuln/cmd/govulncheck@latest
govulncheck ./... # reachability-aware, so the output is short enough to act on
Supported releases: the two most recent major versions. Older toolchains get no security fixes.