Skip to content

Commit bef07ea

Browse files
committed
Add Go code style guide.
1 parent 669965a commit bef07ea

1 file changed

Lines changed: 47 additions & 0 deletions

File tree

docs/code-style-guide.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Code Style Guide
2+
3+
Go conventions for this repository — written for humans and coding agents
4+
alike. The [API style guide](api-style-guide.md) governs the proto surface;
5+
this document governs the Go code behind it. Repository layout is covered by
6+
[code layout](dev/code-layout.md).
7+
8+
The baseline is [Effective Go](https://go.dev/doc/effective_go), the
9+
[Google Go style guide](https://google.github.io/styleguide/go/), and `gofmt`.
10+
This document records only decisions that are specific to this project.
11+
12+
## Proto field access: check presence, don't default it
13+
14+
Generated getters (e.g. `req.GetActor().GetName()`) return zero values when any
15+
message in the chain is nil. That is convenient and dangerous: a required
16+
message the caller forgot to set silently becomes `""`, and the bug surfaces
17+
far from its cause.
18+
19+
- A getter chain must never stand in for a presence check. Whenever a field
20+
is required at this point in the code, check it explicitly and fail loudly:
21+
`INVALID_ARGUMENT` at the API boundary, a real error (not a guessed zero
22+
value) elsewhere.
23+
- Once the boundary has validated presence, getters downstream are fine, as is
24+
the guarded form for optional messages:
25+
26+
```go
27+
if wass := worker.Assignment; wass != nil {
28+
// Fields of wass were validated on write; use them directly.
29+
}
30+
```
31+
32+
- Absence of a group of fields that are set and cleared together is
33+
represented by a nil message (`worker.Assignment == nil`), never by probing
34+
a scalar field inside it for its zero value.
35+
36+
## Testing
37+
38+
- Standard library `testing` only — no assertion or mocking frameworks.
39+
- Table-driven tests with `t.Run` subtests are the default shape.
40+
- Prefer a real fake when one exists: `miniredis` for the store, `envtest` for
41+
the Kubernetes API. Release
42+
resources with `t.Cleanup`.
43+
44+
## TODOs
45+
46+
Deferred decisions are recorded in code as `TODO(username): ...`, placed where
47+
the decision will eventually have to be made.

0 commit comments

Comments
 (0)