一键导入
go-quality
Go code quality rules and standards for kattle project. Apply when writing or reviewing Go code.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Go code quality rules and standards for kattle project. Apply when writing or reviewing Go code.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Create a git worktree for a new TASK. Use when starting a new feature, fix, or refactor task that requires isolated development.
macOS native memory analysis tools (leaks, heap, vmmap, Instruments). Use for native app memory debugging.
Memory profile snapshot capture and baseline comparison. Use for verification after memory optimization.
Go application memory profiling and analysis. Use when investigating memory leaks or high memory usage.
React/TypeScript code quality rules for kattle frontend. Apply when writing or reviewing frontend code.
Run Go and frontend tests for kattle project. Use after code changes to verify correctness.
| name | go-quality |
| description | Go code quality rules and standards for kattle project. Apply when writing or reviewing Go code. |
| disable-model-invocation | true |
| user-invocable | false |
| allowed-tools | Read, Edit, Write, Grep, Glob |
These rules apply to all Go code in the kattle project. Use this skill when writing, reviewing, or refactoring Go code.
Always check and handle errors explicitly. Never ignore errors with _.
// ❌ BAD
data, _ := os.ReadFile(path)
// ✅ GOOD
data, err := os.ReadFile(path)
if err != nil {
return fmt.Errorf("failed to read file %s: %w", path, err)
}
Use %w for error wrapping (Go 1.13+). This allows error chain inspection with errors.Is() and errors.As().
// ❌ BAD
return fmt.Errorf("failed to create client: %v", err)
// ✅ GOOD
return fmt.Errorf("failed to create client: %w", err)
Never panic in library code. Only panic in main() or init() functions.
Only export what's needed by external packages. Check usage before exporting:
internal/ package? Use lowercase (unexported)cmd/ or external consumers? Use uppercase (exported)// ❌ BAD: Unnecessarily exported
func InternalHelper() {}
// ✅ GOOD: Unexported when internal-only
func internalHelper() {}
// ✅ GOOD: Exported for external use
func ListContexts() ([]string, error) {}
Always use defer for cleanup. Lock/unlock, file closing, and resource release must use defer.
// ❌ BAD
mu.Lock()
doWork()
mu.Unlock()
// ✅ GOOD
mu.Lock()
defer mu.Unlock()
doWork()
// ✅ GOOD: Close resources with defer
f, err := os.Open(path)
if err != nil {
return err
}
defer f.Close()
Use sync.RWMutex for read-heavy workloads. Acquire read locks for queries, write locks for mutations.
// ✅ GOOD: Read lock for reads
clientSetsMu.RLock()
cs, exists := clientSets[contextName]
clientSetsMu.RUnlock()
// ✅ GOOD: Write lock for writes
clientSetsMu.Lock()
defer clientSetsMu.Unlock()
clientSets[contextName] = cs
Use double-check pattern for cached values to prevent race conditions:
// ✅ GOOD: Check without lock, then recheck after acquiring lock
mu.RLock()
if val, exists := cache[key]; exists {
mu.RUnlock()
return val, nil
}
mu.RUnlock()
mu.Lock()
defer mu.Unlock()
// Double-check after acquiring write lock
if val, exists := cache[key]; exists {
return val, nil
}
cache[key] = newValue
return newValue, nil
Prevent goroutine leaks: Use context for cancellation, never fire-and-forget goroutines.
// ✅ GOOD: Goroutine respects context cancellation
go func(ctx context.Context) {
for {
select {
case <-ctx.Done():
return
default:
doWork()
}
}
}(ctx)
Pass context.Context as the first parameter in functions that perform I/O or network operations.
// ✅ GOOD: Accept context parameter
func FetchData(ctx context.Context, url string) error {
req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
// ...
}
Pass context down the call stack. Never create a new context.Background() in the middle of execution.
// ❌ BAD: Creating new context
func handler() {
ctx := context.Background()
fetchData(ctx)
}
// ✅ GOOD: Using passed context
func handler(ctx context.Context) {
fetchData(ctx)
}
Always check for nil before dereferencing pointers or accessing map values.
// ❌ BAD: Potential nil dereference
result := config.Clusters[name].Server
// ✅ GOOD: Explicit nil check
cluster, exists := config.Clusters[name]
if !exists || cluster == nil {
return fmt.Errorf("cluster %s not found", name)
}
result := cluster.Server
Write table-driven tests for complex logic. Structure tests with clear test cases, inputs, and expected outputs.
func TestIndexesToRanges(t *testing.T) {
tests := []struct {
name string
input []int
expected [][2]int
wantErr bool
}{
{"empty", []int{}, [][2]int{}, false},
{"single", []int{0}, [][2]int{{0, 0}}, false},
{"consecutive", []int{0, 1, 2}, [][2]int{{0, 2}}, false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := indexesToRanges(tt.input)
if (result == nil) != tt.wantErr {
t.Errorf("got %v, want error=%v", result, tt.wantErr)
}
// Assert result == tt.expected
})
}
}
Before committing Go code, verify:
%wdefer used for all cleanup operations (locks, files, resources)defer unlockcontext.Context passed down call stack (not created in middle of execution)gofmt, golint, go vet, and go testApply this skill when: