149 lines
3.8 KiB
Markdown
149 lines
3.8 KiB
Markdown
|
|
---
|
|||
|
|
description: 對 Go 程式碼進行全面的審查,包含慣用法、並發安全、錯誤處理與安全性。此指令會呼叫 go-reviewer agent。
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# Go 程式碼審查 (Go Code Review)
|
|||
|
|
|
|||
|
|
此指令會呼叫 **go-reviewer** agent 來進行針對 Go 語言特性的全面審查。
|
|||
|
|
|
|||
|
|
## 此指令的功能
|
|||
|
|
|
|||
|
|
1. **識別 Go 變更**:透過 `git diff` 找出修改過的 `.go` 檔案。
|
|||
|
|
2. **執行靜態分析**:執行 `go vet`, `staticcheck` 和 `golangci-lint`。
|
|||
|
|
3. **安全掃描**:檢查是否存在 SQL 注入、指令注入、競態條件 (Race conditions)。
|
|||
|
|
4. **並發審查 (Concurrency Review)**:分析 Goroutine 安全性、Channel 使用方式、Mutex 模式。
|
|||
|
|
5. **慣用法檢查 (Idiomatic Go Check)**:驗證程式碼是否遵循 Go 慣例與最佳實踐。
|
|||
|
|
6. **產生報告**:按嚴重程度對問題進行分類。
|
|||
|
|
|
|||
|
|
## 何時使用
|
|||
|
|
|
|||
|
|
在以下情況使用 `/go-review`:
|
|||
|
|
- 撰寫或修改 Go 程式碼後。
|
|||
|
|
- 提交 Go 變更前。
|
|||
|
|
- 審查包含 Go 程式碼的 Pull Request 時。
|
|||
|
|
- 進入新的 Go 專案庫時。
|
|||
|
|
- 學習 Go 慣用模式時。
|
|||
|
|
|
|||
|
|
## 審查類別
|
|||
|
|
|
|||
|
|
### 關鍵問題 (CRITICAL - 必須修復)
|
|||
|
|
- SQL/指令注入漏洞。
|
|||
|
|
- 無同步機制的競態條件。
|
|||
|
|
- Goroutine 洩漏 (Leaks)。
|
|||
|
|
- 硬編碼的憑據。
|
|||
|
|
- 不安全的指標 (Unsafe pointer) 使用。
|
|||
|
|
- 在關鍵路徑中忽略錯誤 (Ignored errors)。
|
|||
|
|
|
|||
|
|
### 高優先級 (HIGH - 建議修復)
|
|||
|
|
- 缺少帶有上下文 (Context) 的錯誤包裝。
|
|||
|
|
- 使用 Panic 代替返回錯誤。
|
|||
|
|
- Context 未進行傳播。
|
|||
|
|
- 無緩衝 Channel 導致死結 (Deadlocks)。
|
|||
|
|
- 介面未滿足 (Interface not satisfied) 錯誤。
|
|||
|
|
- 缺少 Mutex 保護。
|
|||
|
|
|
|||
|
|
### 中優先級 (MEDIUM - 考慮調整)
|
|||
|
|
- 非慣用性的程式碼模式。
|
|||
|
|
- 公共匯出項目缺少 Godoc 註釋。
|
|||
|
|
- 低效的字串拼接。
|
|||
|
|
- Slice 未預先分配空間。
|
|||
|
|
- 未使用表格驅動測試 (Table-driven tests)。
|
|||
|
|
|
|||
|
|
## 執行的自動化檢查
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# 靜態分析
|
|||
|
|
go vet ./...
|
|||
|
|
|
|||
|
|
# 進階檢查 (如果已安裝)
|
|||
|
|
staticcheck ./...
|
|||
|
|
golangci-lint run
|
|||
|
|
|
|||
|
|
# 競態偵測
|
|||
|
|
go build -race ./...
|
|||
|
|
|
|||
|
|
# 安全漏洞掃描
|
|||
|
|
govulncheck ./...
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 使用範例
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
使用者:/go-review
|
|||
|
|
|
|||
|
|
Agent:
|
|||
|
|
# Go 程式碼審查報告
|
|||
|
|
|
|||
|
|
## 審查檔案
|
|||
|
|
- internal/handler/user.go (已修改)
|
|||
|
|
- internal/service/auth.go (已修改)
|
|||
|
|
|
|||
|
|
## 靜態分析結果
|
|||
|
|
✓ go vet: 無問題
|
|||
|
|
✓ staticcheck: 無問題
|
|||
|
|
|
|||
|
|
## 發現問題
|
|||
|
|
|
|||
|
|
[CRITICAL] 競態條件 (Race Condition)
|
|||
|
|
檔案: internal/service/auth.go:45
|
|||
|
|
問題: 在無同步機制的情況下訪問共享 Map
|
|||
|
|
```go
|
|||
|
|
var cache = map[string]*Session{} // 並發訪問危險!
|
|||
|
|
|
|||
|
|
func GetSession(id string) *Session {
|
|||
|
|
return cache[id] // 競態條件
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
修復方案: 使用 sync.RWMutex 或 sync.Map
|
|||
|
|
```go
|
|||
|
|
var (
|
|||
|
|
cache = map[string]*Session{}
|
|||
|
|
cacheMu sync.RWMutex
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
func GetSession(id string) *Session {
|
|||
|
|
cacheMu.RLock()
|
|||
|
|
defer cacheMu.RUnlock()
|
|||
|
|
return cache[id]
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
[HIGH] 缺少錯誤上下文 (Missing Error Context)
|
|||
|
|
檔案: internal/handler/user.go:28
|
|||
|
|
問題: 返回錯誤時未附帶上下文資訊
|
|||
|
|
```go
|
|||
|
|
return err // 缺少上下文
|
|||
|
|
```
|
|||
|
|
修復方案: 使用文字或包裝來提供上下文
|
|||
|
|
```go
|
|||
|
|
return fmt.Errorf("get user %s: %w", userID, err)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 摘要
|
|||
|
|
- CRITICAL: 1
|
|||
|
|
- HIGH: 1
|
|||
|
|
- MEDIUM: 0
|
|||
|
|
|
|||
|
|
建議: ❌ 在修復 CRITICAL 問題前,禁止合併 (Block merge)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 核准標準
|
|||
|
|
|
|||
|
|
| 狀態 | 條件 |
|
|||
|
|
|--------|-----------|
|
|||
|
|
| ✅ 核准 (Approve) | 無 CRITICAL 或 HIGH 問題 |
|
|||
|
|
| ⚠️ 警告 (Warning) | 僅存在 MEDIUM 問題 (謹慎合併) |
|
|||
|
|
| ❌ 阻斷 (Block) | 發現 CRITICAL 或 HIGH 問題 |
|
|||
|
|
|
|||
|
|
## 與其他指令的整合
|
|||
|
|
|
|||
|
|
- 先使用 `/go-test` 確保測試通過。
|
|||
|
|
- 如果發生建置錯誤,請使用 `/go-build`。
|
|||
|
|
- 在提交前使用 `/go-review`。
|
|||
|
|
- 對於非 Go 特有的通用問題,請使用 `/code-review`。
|
|||
|
|
|
|||
|
|
## 相關參考
|
|||
|
|
|
|||
|
|
- Agent: `agents/go-reviewer.md`
|
|||
|
|
- 技能: `skills/golang-patterns/`, `skills/golang-testing/`
|