con un clic
gopher
Use this skill when planning/writing or reviewing Go code.
Instalar con Codex o Claude Copia este prompt, pégalo en Codex, Claude u otro asistente, y deja que revise la página de la skill y la instale por ti.
Menú
Use this skill when planning/writing or reviewing Go code.
Instalar con Codex o Claude Copia este prompt, pégalo en Codex, Claude u otro asistente, y deja que revise la página de la skill y la instale por ti.
Basado en la clasificación ocupacional SOC
| name | gopher |
| description | Use this skill when planning/writing or reviewing Go code. |
Use with project docs. This skill is not a substitute for the repository’s own rules. Always read the nearest AGENTS.md (or your project’s equivalent: CONTRIBUTING.md, team wiki, Cursor rules) for:
Nearest project instructions win when they conflict with anything below.
log/slog (or the project’s logging facade) as an injected dependency — avoid global loggers unless the project already standardized on them.fmt.Errorf("context: %w", err) (or the project’s error helpers).type FooOption func(*Foo) (or *fooConfig), WithBar(...) functions that set fields, and NewFoo(opts ...FooOption) applying them in order. Avoid a separate NewFooWithOpts when the zero-arg NewFoo() case is the default.makeSomething or MakeSomething - returns valuenewSomething or NewSomething - returns pointerEach building block (e.g Struct, Interface, Function or similar) must have a clear purpose and named accordingly. This means helper, utils, common, shared, support or similar "god" naming patterns are banned. This also applies to package names. Such names are only accepted if they express a domain concept, for example "support request", or "shared device"
Sometimes underlying implementation may vary (e.g DB storage and in-memory storage). It is tempting to make two constructors returning an interface and violate the rule. However there is an elegant solution, see below and don't take it literally, adjust naming and logic as needed, understand concept.
// Consumer needs SomeService
type SomeService interface {
DoSomething() error
}
// We have two implementations
type SomeServiceVariationA struct { ..... }
type SomeServiceVariationB struct { ..... }
// Figure-out the best name for the selector, this is just example
type SomeServiceSelector struct {
SomeService // e.g just embed the interface
}
// Finally the constructor for the selector
func NewSomeServiceSelector(params SomeServiceParams) *SomeServiceSelector {
if(params.UseVariationA) {
return &SomeServiceSelector{SomeService: &SomeServiceVariationA{}}
}
return &SomeServiceSelector{SomeService: &SomeServiceVariationB{}}
}
More detail is in Testing best practices below. Common points:
github.com/jaswdr/faker/v2) for variable test data, typically via a local fake := faker.New() or direct faker.New() calls matching the surrounding migrated tests. This is a MUST. It may only justified to use fixed literals that are explicitly present in the actual code, otherwise all inputs must be randomized.faker.Word() (or similar single faker outputs) are unique or length-safe. When you need multiple distinct random strings, add deterministic disambiguation (e.g. "case1-" + faker.Word(), "case2-" + faker.Word()") or enforce uniqueness/length explicitly._test package if the project prefers that for black-box tests).t.Run for methods and scenarios.makeMockDeps or fixture constructor if the project uses that pattern); avoid copy-pasted setup.TestComponentName and nested t.Run per API surface, avoid separate TestComponentNameFunctionName functions per method.expected vs actual struct)require.Error / require.ErrorIs (or equivalents) for error assertions.t.Context() over context.Background() / context.TODO() in tests when the Go version supports it.TestXxx (e.g. as a closure used by nested t.Run blocks) or inside a single t.Run when only that case needs them.If project documents specific mocking strategy, follow it. If you have to create mock manually, follow these principles: