Files
2025-11-29 18:28:04 +08:00

444 lines
9.4 KiB
Markdown

---
name: golang-development:review
description: 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
```bash
/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
```bash
# 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:**
```go
// ❌ 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:**
```go
// ❌ 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:**
```go
// ❌ 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:**
```go
// ❌ 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:**
```go
// ❌ 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:
```yaml
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