Skip to main content

go

Idiomatic Go 1.25 practices: errors, interfaces, concurrency, generics, testing, security, tooling. Use when writing or reviewing Go code.

Informations de source

Dépôt
SumonMSelim/agentguard
Dernière activité de la source
22 mai 2026 à 01:53
Langue détectée de SKILL.md
anglais
Étoiles
54
Forks
10

Options d'installation

Le prompt qui vérifie d'abord la source est sélectionné par défaut. Vous pouvez passer à une commande directe ou télécharger une copie locale.

Vérifiez les fichiers source

Lisez SKILL.md et les fichiers associés affichés par SkillsMP avant de décider de l'installer.

Affichage de SKILL.md

SKILL.md
Instructions source · Aperçu en lecture seule
name
go
description
Idiomatic Go 1.25 practices: errors, interfaces, concurrency, generics, testing, security, tooling. Use when writing or reviewing Go code.
# Go ## Project structure - `go.mod` at repo root. Module path matches repo URL: `module github.com/org/repo` - Pin Go version in `go.mod`: `go 1.25`. Toolchain auto-selects via `toolchain` directive - Tool dependencies via `go.mod` `tool` directives (1.24+). `go get -tool golang.org/x/tools/cmd/stringer` - Standard layout: `cmd/` for binaries, `internal/` for private packages, `pkg/` only if genuinely public - No circular imports. `internal/` enforces package boundaries - `go.sum` committed. Never manually edited ## Errors - Errors are values. Return `error` as last return value - Wrap with context: `fmt.Errorf("op failed: %w", err)`. Always `%w`, not `%v`, when caller may inspect - Sentinel errors: `var ErrNotFound = errors.New("not found")`. Use `errors.Is` to check, not `==` - Custom error types: implement `Error() string`. Use `errors.As` to extract - Never ignore errors. `_ = f()` only with explicit justification in comment - No `panic` in library code. Reserve for truly unrecoverable states in `main` - Check errors immediately after call. No deferred error checks buried in logic ## Interfaces - Define interfaces at point of use (consumer), not point of implementation - Small interfaces. Prefer single-method interfaces: `io.Reader`, `io.Writer` - Accept interfaces, return concrete types - No interface for a single implementation unless testing or future extensibility is clear - `interface{}` → `any` (Go 1.18+). Use `any` everywhere - Embed interfaces to compose: `type ReadWriter interface { Reader; Writer }` ## Generics - Use generics to eliminate identical logic across types. Not for premature abstraction - Constrain tightly: `[T int | int64]` over `[T any]` when type matters - `comparable` constraint for map keys and equality checks - `golang.org/x/exp/slices` and `maps` patterns now in stdlib (`slices`, `maps` packages, 1.21+) - Range over func iterators (1.22+): use `iter.Seq` and `iter.Seq2` for custom iterables - Generic type aliases fully supported (1.24+): `type Set[T comparable] = map[T]struct{}` ## Concurrency - Share memory by communicating. Channels for ownership transfer, `sync` for shared state - Always specify goroutine lifecycle: who starts it, who stops it, how caller knows it's done - `context.Context` as first arg to every blocking or long-running function. Respect cancellation - `select` with `ctx.Done()` in every goroutine that blocks on channel or I/O - `sync.WaitGroup` to wait for goroutine group. `errgroup.Group` when any error should cancel all - `sync.Mutex` over channels for protecting shared state. Embed mutex with the data it protects - Race detector always on in tests and CI: `go test -race ./...` - No goroutine leaks. Profile with `goleak` in tests for long-running services - Buffered channels: document capacity rationale. Default to unbuffered - GOMAXPROCS defaults to cgroup CPU limit on Linux (1.25+) — container deployments no longer need manual tuning ## Context - `context.Background()` at program entry only (`main`, top-level server handler, test root) - Never store context in struct. Pass explicitly - Cancel functions always deferred: `ctx, cancel := context.WithTimeout(...); defer cancel()` - Propagate deadlines from inbound requests to all outbound calls (HTTP, DB, gRPC) - `context.WithValue` only for request-scoped metadata (trace ID, auth token). Not for optional function params. Key type must be unexported to avoid collisions ## HTTP and networking - `net/http`: always set `ReadTimeout`, `WriteTimeout`, `IdleTimeout` on `http.Server`. No default server - Close response bodies: `defer resp.Body.Close()` immediately after nil error check - Use `http.NewRequestWithContext` — never `http.NewRequest` in production code - Validate and sanitize all inbound data. Use `net/url` for URL construction, not string concat - TLS: `tls.Config` with `MinVersion: tls.VersionTLS12`. Prefer TLS 1.3 ## Security - Never construct SQL with string concat. Use parameterized queries or an ORM that does - `crypto/rand` for all random tokens, IDs, secrets. Never `math/rand` - Hash passwords with `bcrypt` or `argon2`. Never `sha256` or `md5` for passwords - Avoid `html/template` bypass (`template.HTML`, `template.JS`). Auto-escaping is the point - `os/exec`: never pass user input directly to shell. Use arg list form, not string form - `filepath.Clean` and `filepath.Join` for all path construction. Validate result stays within allowed root - `govulncheck ./...` in CI. Scans modules and call graph for known CVEs - Secrets from env or secret manager at startup. Never hardcoded or in config files committed to git ## Testing - Table-driven tests as default pattern. `t.Run` per case - `t.Parallel()` in all unit tests that don't share mutable state - `testify/assert` or stdlib `cmp` for assertions. Avoid rolling custom diff logic - Use `t.TempDir()` for temp files — auto-cleaned. Never `os.TempDir()` directly in tests - Fuzz tests (`func FuzzX(f *testing.F)`) for parsers, decoders, untrusted input handlers - Benchmarks (`func BenchmarkX(b *testing.B)`) for hot paths. Run with `-benchmem` - `httptest.NewRecorder` and `httptest.NewServer` for HTTP handler tests. No real network in unit tests - Coverage: `go test -cover ./...`. Track but don't cargo-cult 100% - Integration and unit tests separated via build tags: `//go:build integration` ## Tooling - Format: `gofmt` or `goimports` on save. No style debates - Lint: `golangci-lint` with at minimum `errcheck`, `govet`, `staticcheck`, `gosec` enabled - `go vet ./...` in CI. Catches real bugs, not style - `govulncheck ./...` in CI for supply chain security - `go mod tidy` before every commit. Keeps `go.sum` clean - `go build -trimpath` for reproducible builds. Removes local paths from binaries - Multi-platform: `GOOS=linux GOARCH=amd64 go build`. Test on target arch in CI - `go tool pprof` for CPU/memory profiling. `net/http/pprof` endpoint in long-running services (behind auth) ## Performance - Preallocate slices and maps when length known: `make([]T, 0, n)`, `make(map[K]V, n)` - Avoid allocations in hot paths. Benchmark before optimizing. `go test -benchmem` - `sync.Pool` for frequently allocated short-lived objects (e.g. buffers) - String builder: `strings.Builder` for loops. Never `+=` string concat in loops - `io.Reader`/`io.Writer` chains over loading full content into memory - Profile first. `pprof` before any micro-optimization
Voir sur GitHub