go-template/CLAUDE.md

4.4 KiB

CLAUDE.md — Agent Instructions

This file is read automatically by Claude Code at the start of every session. Keep it concise — the agent needs signal, not essays.


Project overview

Go 1.24 template / PoC starter. Demonstrates: structured logging (zap), config (viper), interfaces + mocks (mockery), linting (golangci-lint), security scanning (gosec, govulncheck), git hooks, devcontainer, VSCode tasks.

Module: gitea.djmil.dev/djmil/go-template — update this when you fork.


Project structure

cmd/app/main.go          composition root — wires deps, no logic here
internal/config/         Viper config loader (config.Load)
internal/logger/         Zap wrapper with WithField / WithFields
internal/greeter/        Example domain package (delete or repurpose)
mocks/greeter/           Generated mocks — regenerate with `make mocks`
config/dev.yaml          Local dev config (committed, no secrets)
tools.go                 Tool version pinning (build tag: tools)
.golangci.yml            Linter rules
.mockery.yaml            Mockery code-gen config
.githooks/pre-commit     Runs gofmt + golangci-lint + gosec before commit

Project rules

  • Module imports — always use the full module path gitea.djmil.dev/djmil/go-template/...
  • Packages — keep cmd/ thin (wiring only); business logic belongs in internal/
  • Interfaces — define interfaces where they are used, not where they are implemented
  • Errors — wrap with fmt.Errorf("context: %w", err); never swallow errors silently
  • Logging — use log.WithField("key", val) for structured context, never fmt.Sprintf in log messages
  • Config — all configuration through internal/config; no hard-coded values in logic packages
  • Secrets — never commit .env files or credentials; use env var overrides of config keys

Code style

  • Follow gofmt + goimports formatting (enforced by linter and git hook)
  • Imports: stdlib → blank line → external → blank line → internal (goimports handles this)
  • Error variables: err for local, ErrFoo for package-level sentinels
  • Constructors: New(deps...) *Type pattern
  • Comment every exported symbol (golangci-lint will warn if missing)
  • Max line length: 120 chars (configured in .golangci.yml)
  • Prefer explicit over clever; PoC code should be readable first

Testing rules

  • All tests use testify (assert for soft checks, require for stop-on-fail)
  • Test files: package foo_test (black-box) unless white-box access is needed
  • Mock dependencies via mockery-generated mocks with EXPECT() chains
  • Use logger.NewNop() when the test doesn't care about log output
  • Table-driven tests with t.Run("description", ...) for multiple cases
  • The race detector is enabled in CI (make test-race); don't introduce data races
  • Never use time.Sleep in tests; use channels or require.Eventually

Development commands

make init          # first-time setup: fetch deps, install tools, git hooks
make build         # compile to ./bin/app
make run           # go run with config/dev.yaml
make test          # run all tests
make test-race     # tests + race detector
make lint          # golangci-lint
make lint-fix      # auto-fix lint issues
make security      # gosec + govulncheck
make mocks         # regenerate all mocks
make generate      # run all //go:generate directives
make clean         # remove bin/ and mocks/

VSCode: Ctrl+Shift+B = build, Ctrl+Shift+T = test. Debug: use launch config "Debug: app" (F5).


Adding new features (checklist)

  1. Define the interface in internal/<domain>/
  2. Write the implementation and its unit tests
  3. Add the interface to .mockery.yaml and run make mocks
  4. Wire it in cmd/app/main.go
  5. Run make lint test before committing

Known pitfalls

  • mocks/ are committed intentionally — regenerate after interface changes
  • govulncheck makes network calls; excluded from pre-commit hook (run manually)
  • config/dev.yaml is committed but never add real credentials here
  • tools.go has //go:build tools — it won't compile into the binary

Recent work

  • 2026-03-05 — Initial template scaffolded: config, logger, greeter example, mocks, git hooks, devcontainer, VSCode tasks, golangci-lint, Makefile.