$npx -y skills add softspark/ai-toolkit --skill golang-rulesGo coding rules: style, patterns, security, testing. Triggers: .go, go.mod, go.sum, Gin, Echo, Gorilla, testing, gofmt.
| 1 | # Go Rules |
| 2 | |
| 3 | These rules come from `app/rules/golang/` in ai-toolkit. They cover |
| 4 | the project's standards for coding style, frameworks, patterns, |
| 5 | security, and testing in Go. Apply them when writing or |
| 6 | reviewing Go code. |
| 7 | |
| 8 | # Go Coding Style |
| 9 | |
| 10 | ## Naming |
| 11 | - MixedCaps/mixedCaps only. No underscores in Go names (except test functions). |
| 12 | - Exported: `PascalCase`. Unexported: `camelCase`. Acronyms: `HTTPClient`, `userID`. |
| 13 | - Short variable names in small scopes: `i`, `r`, `w`, `ctx`, `err`. |
| 14 | - Descriptive names in larger scopes: `userRepository`, `requestTimeout`. |
| 15 | - Package names: short, lowercase, singular (`auth`, `user`, not `utils`, `helpers`). |
| 16 | |
| 17 | ## Packages |
| 18 | - One package per directory. Package name = directory name. |
| 19 | - Avoid `util`, `common`, `helpers` packages. Name by what it provides. |
| 20 | - Keep package APIs small. Export only what consumers need. |
| 21 | - Use `internal/` directory for packages not meant for external consumption. |
| 22 | |
| 23 | ## Functions |
| 24 | - Accept interfaces, return structs. |
| 25 | - First parameter `ctx context.Context` if the function does I/O or may be cancelled. |
| 26 | - Return `(result, error)` tuple. Error is always last return value. |
| 27 | - Use named return values only for documentation, not for naked returns. |
| 28 | - Keep functions short. If >40 lines, consider splitting. |
| 29 | |
| 30 | ## Error Handling |
| 31 | - Always check errors. Never use `_` to discard errors silently. |
| 32 | - Wrap errors with context: `fmt.Errorf("fetching user %s: %w", id, err)`. |
| 33 | - Use sentinel errors (`var ErrNotFound = errors.New(...)`) for expected conditions. |
| 34 | - Use `errors.Is()` and `errors.As()` for error checking, not type assertions. |
| 35 | |
| 36 | ## Formatting |
| 37 | - Use `gofmt` / `goimports`. No formatting debates in Go. |
| 38 | - Use `golangci-lint` with a `.golangci.yml` config in CI. |
| 39 | - Use `go vet` as minimum static analysis. |
| 40 | |
| 41 | ## Struct Design |
| 42 | - Use struct embedding for composition, not inheritance. |
| 43 | - Prefer value receivers for small structs, pointer receivers for large or mutable. |
| 44 | - Be consistent: all methods on a type use the same receiver type. |
| 45 | - Use struct literals with field names: `User{Name: "Ada", Age: 30}`. |
| 46 | |
| 47 | ## Concurrency |
| 48 | - Do not start goroutines without a plan to stop them. |
| 49 | - Use `sync.WaitGroup` or `errgroup.Group` to coordinate goroutines. |
| 50 | - Use channels for communication, mutexes for state protection. |
| 51 | - Prefer `context.Context` for cancellation and timeouts over manual signaling. |
| 52 | |
| 53 | # Go Frameworks |
| 54 | |
| 55 | ## Standard Library HTTP |
| 56 | - Use `http.NewServeMux()` (Go 1.22+ with method patterns) for simple APIs. |
| 57 | - Use `http.HandlerFunc` for handlers. Compose with middleware pattern. |
| 58 | - Use `context.Context` from `r.Context()` in all handlers. |
| 59 | - Use `http.TimeoutHandler` to prevent slow handlers from hanging. |
| 60 | |
| 61 | ## Chi / Gorilla Mux |
| 62 | - Use Chi for routing with middleware chains and URL params. |
| 63 | - Use `chi.URLParam(r, "id")` to extract path parameters. |
| 64 | - Use middleware groups: `r.Group(func(r chi.Router) { r.Use(authMiddleware) })`. |
| 65 | - Prefer Chi over Gorilla Mux (Gorilla was archived, Chi actively maintained). |
| 66 | |
| 67 | ## Gin / Echo |
| 68 | - Use Gin for high-performance APIs with built-in validation. |
| 69 | - Use binding tags: `binding:"required,email"` on struct fields. |
| 70 | - Use middleware for cross-cutting: logging, recovery, CORS, auth. |
| 71 | - Use `c.ShouldBindJSON()` over `c.BindJSON()` to handle errors yourself. |
| 72 | |
| 73 | ## GORM / sqlx / pgx |
| 74 | - Use `sqlx` for SQL-first with struct scanning (lightweight). |
| 75 | - Use `pgx` directly for PostgreSQL-specific features and performance. |
| 76 | - Use GORM only when rapid prototyping outweighs SQL control. |
| 77 | - Always use prepared statements or parameterized queries. |
| 78 | - Use `sqlx.In()` for dynamic IN clauses safely. |
| 79 | |
| 80 | ## gRPC |
| 81 | - Define services in `.proto` files. Generate Go code with `protoc`. |
| 82 | - Use interceptors for auth, logging, and tracing (equivalent to middleware). |
| 83 | - Use deadlines (context timeout) on every RPC call. |
| 84 | - Use streaming RPCs for real-time data, unary for request-response. |
| 85 | |
| 86 | ## Configuration |
| 87 | - Use `envconfig` or `viper` for configuration from env/files. |
| 88 | - Use struct tags for env mapping: `envconfig:"DATABASE_URL"`. |
| 89 | - Validate config at startup. Fail fast on invalid configuration. |
| 90 | - Use `flag` package for CLI arguments in tools and utilities. |
| 91 | |
| 92 | ## Observability |
| 93 | - Use `slog` (Go 1.21+) for structured logging. Replace `log` package. |
| 94 | - Use OpenTelemetry for distributed tracing and metrics. |
| 95 | - Export metrics via Prometheus endpoint. |
| 96 | - Use `pprof` for CPU and memory profiling in development. |
| 97 | |
| 98 | ## Project Layout |
| 99 | - Follow Standard Go Project Layout: `cmd/`, `internal/`, `pkg/`. |
| 100 | - Entry points in `cmd/appname/main.go`. |
| 101 | - Business logic in `internal/`. Shared libraries in `pkg/`. |
| 102 | - Use `Makefile` for common tasks: build, test, lint, run. |
| 103 | |
| 104 | # Go Patterns |
| 105 | |
| 106 | ## Error Handling |
| 107 | - Wrap errors with context at each call site: `fmt.Errorf("loading config: %w", err)`. |
| 108 | - Define domain error types with `errors.New() |