Files
gh-geoffjay-claude-plugins-…/commands/review.md
2025-11-29 18:28:04 +08:00

9.4 KiB

name, description
name description
golang-development:review Review Go code for idiomatic patterns, performance issues, security vulnerabilities, and common pitfalls with actionable suggestions

Golang Development Review Command

Comprehensive Go code review focusing on idiomatic patterns, performance, security, and best practices.

Usage

/golang-development:review [file-path-or-directory] [focus-area]

Arguments

  • $1 - File path or directory to review (optional, defaults to current directory)
  • $2 - Focus area: all, idioms, performance, security, concurrency, errors (optional, defaults to all)

Examples

# Review all files in current directory
/golang-development:review

# Review specific file
/golang-development:review internal/service/user.go

# Focus on performance issues
/golang-development:review . performance

# Focus on security
/golang-development:review ./handlers security

# Review concurrency patterns
/golang-development:review . concurrency

Review Categories

1. Idiomatic Go (idioms)

Checks:

  • Naming conventions (camelCase, capitalization)
  • Error handling patterns
  • Interface usage and design
  • Struct composition over inheritance
  • Receiver naming and types
  • Exported vs. unexported identifiers
  • Go proverbs adherence

Example Issues:

// ❌ BAD: Non-idiomatic error handling
func getUser(id string) (*User, string) {
    if id == "" {
        return nil, "invalid ID"
    }
    // ...
}

// ✅ GOOD: Idiomatic error handling
func GetUser(id string) (*User, error) {
    if id == "" {
        return nil, fmt.Errorf("invalid ID: %s", id)
    }
    // ...
}

// ❌ BAD: Getter naming
func (u *User) GetName() string {
    return u.name
}

// ✅ GOOD: Idiomatic getter
func (u *User) Name() string {
    return u.name
}

// ❌ BAD: Setter without validation
func (u *User) SetAge(age int) {
    u.age = age
}

// ✅ GOOD: Validated setter with error
func (u *User) SetAge(age int) error {
    if age < 0 || age > 150 {
        return fmt.Errorf("invalid age: %d", age)
    }
    u.age = age
    return nil
}

2. Performance (performance)

Checks:

  • Unnecessary allocations
  • String concatenation in loops
  • Slice pre-allocation
  • Map pre-allocation
  • Defer in loops
  • Inefficient algorithms
  • Memory leaks
  • Goroutine leaks

Example Issues:

// ❌ BAD: String concatenation in loop
func concat(strs []string) string {
    result := ""
    for _, s := range strs {
        result += s  // Allocates new string each time
    }
    return result
}

// ✅ GOOD: Use strings.Builder
func concat(strs []string) string {
    var sb strings.Builder
    for _, s := range strs {
        sb.WriteString(s)
    }
    return sb.String()
}

// ❌ BAD: Growing slice
func process(n int) []int {
    var result []int
    for i := 0; i < n; i++ {
        result = append(result, i)
    }
    return result
}

// ✅ GOOD: Pre-allocate
func process(n int) []int {
    result := make([]int, 0, n)
    for i := 0; i < n; i++ {
        result = append(result, i)
    }
    return result
}

// ❌ BAD: Defer in tight loop
for i := 0; i < 10000; i++ {
    mu.Lock()
    defer mu.Unlock()  // Defers accumulate
    // ...
}

// ✅ GOOD: Explicit unlock
for i := 0; i < 10000; i++ {
    mu.Lock()
    // ...
    mu.Unlock()
}

3. Security (security)

Checks:

  • SQL injection vulnerabilities
  • Command injection
  • Path traversal
  • Hardcoded credentials
  • Weak cryptography
  • Unsafe operations
  • Input validation
  • XSS vulnerabilities

Example Issues:

// ❌ BAD: SQL injection
func getUser(db *sql.DB, username string) (*User, error) {
    query := fmt.Sprintf("SELECT * FROM users WHERE username = '%s'", username)
    return db.Query(query)
}

// ✅ GOOD: Parameterized query
func getUser(db *sql.DB, username string) (*User, error) {
    query := "SELECT * FROM users WHERE username = $1"
    return db.Query(query, username)
}

// ❌ BAD: Hardcoded credentials
const apiKey = "sk_live_1234567890"

// ✅ GOOD: Environment variables
apiKey := os.Getenv("API_KEY")

// ❌ BAD: Weak random
func generateToken() string {
    return fmt.Sprintf("%d", rand.Int())
}

// ✅ GOOD: Cryptographically secure random
func generateToken() (string, error) {
    b := make([]byte, 32)
    if _, err := rand.Read(b); err != nil {
        return "", err
    }
    return base64.URLEncoding.EncodeToString(b), nil
}

4. Concurrency (concurrency)

Checks:

  • Race conditions
  • Deadlock potential
  • Missing mutex protection
  • Channel misuse
  • Context propagation
  • Goroutine leaks
  • Improper synchronization
  • Lock contention

Example Issues:

// ❌ BAD: Race condition
type Counter struct {
    count int
}

func (c *Counter) Increment() {
    c.count++  // Not thread-safe
}

// ✅ GOOD: Protected with mutex
type Counter struct {
    mu    sync.Mutex
    count int
}

func (c *Counter) Increment() {
    c.mu.Lock()
    defer c.mu.Unlock()
    c.count++
}

// ❌ BAD: Goroutine leak
func fetchData(url string) <-chan Result {
    ch := make(chan Result)
    go func() {
        // If this fails, goroutine leaks
        data := fetch(url)
        ch <- data
    }()
    return ch
}

// ✅ GOOD: Context for cancellation
func fetchData(ctx context.Context, url string) <-chan Result {
    ch := make(chan Result)
    go func() {
        defer close(ch)
        select {
        case <-ctx.Done():
            return
        default:
            data := fetch(url)
            select {
            case ch <- data:
            case <-ctx.Done():
            }
        }
    }()
    return ch
}

5. Error Handling (errors)

Checks:

  • Ignored errors
  • Error wrapping
  • Sentinel errors
  • Custom error types
  • Error messages
  • Panic usage
  • Recover usage

Example Issues:

// ❌ BAD: Ignored error
file, _ := os.Open("file.txt")

// ✅ GOOD: Handle error
file, err := os.Open("file.txt")
if err != nil {
    return fmt.Errorf("open file: %w", err)
}

// ❌ BAD: Lost error context
func process() error {
    if err := doSomething(); err != nil {
        return err
    }
    return nil
}

// ✅ GOOD: Wrapped error
func process() error {
    if err := doSomething(); err != nil {
        return fmt.Errorf("process failed: %w", err)
    }
    return nil
}

// ❌ BAD: Panic for normal errors
func getConfig() *Config {
    cfg, err := loadConfig()
    if err != nil {
        panic(err)  // Don't panic
    }
    return cfg
}

// ✅ GOOD: Return error
func getConfig() (*Config, error) {
    cfg, err := loadConfig()
    if err != nil {
        return nil, fmt.Errorf("load config: %w", err)
    }
    return cfg, nil
}

Review Output Format

📝 Code Review Results
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

📂 File: internal/service/user.go

⚠️  HIGH: SQL Injection Vulnerability (line 45)
   ├─ Issue: Unsanitized user input in SQL query
   ├─ Risk: Database compromise
   └─ Fix: Use parameterized queries

💡 MEDIUM: Non-Idiomatic Error Handling (line 67)
   ├─ Issue: Returning string error instead of error type
   ├─ Impact: Type safety, error wrapping
   └─ Suggestion: Return error type

⚡ LOW: Performance - Missing Pre-allocation (line 89)
   ├─ Issue: Slice growing without capacity hint
   ├─ Impact: Multiple allocations
   └─ Optimization: make([]Type, 0, expectedSize)

✅ GOOD: Proper context propagation (line 23)
✅ GOOD: Thread-safe cache implementation (line 112)

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Summary:
  High: 1 | Medium: 1 | Low: 1 | Good: 2
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Automated Checks

The review includes automated checks using:

  • go vet - Official Go static analysis
  • staticcheck - Advanced static analysis
  • gosec - Security-focused linter
  • golangci-lint - Comprehensive linter suite
  • Custom pattern matching for Go-specific issues

Manual Review Areas

For complex code, the command performs manual review of:

  • Architecture and design patterns
  • API design and interfaces
  • Test coverage and quality
  • Documentation completeness
  • Code complexity and maintainability

Actionable Suggestions

Each issue includes:

  1. Location: Exact file and line number
  2. Severity: HIGH, MEDIUM, LOW
  3. Description: What the issue is
  4. Impact: Why it matters
  5. Fix: How to resolve it
  6. Example: Code snippet showing the fix

Integration with Tools

The command can integrate with:

  • GitHub PR comments
  • GitLab merge request notes
  • Bitbucket PR feedback
  • Slack notifications
  • Email reports

Configuration

Create .go-review.yml in project root:

ignore:
  - vendor/
  - mocks/
  - ".*_test.go"

severity:
  min_level: MEDIUM

focus:
  - security
  - performance
  - concurrency

custom_rules:
  - pattern: "fmt.Print"
    message: "Use structured logging"
    severity: LOW

When to Use

Use this command:

  • Before creating pull requests
  • During code reviews
  • After major refactoring
  • When onboarding new team members
  • As part of CI/CD pipeline
  • When learning Go best practices
  • Before production deployment

Best Practices

The review checks compliance with:

  • Effective Go guidelines
  • Go Code Review Comments
  • Go proverbs
  • Industry best practices
  • Security standards (OWASP)
  • Performance optimization patterns