Skip to content

Commit 3ef903e

Browse files
committed
fix(lint): golangci-lint 20개 이슈 수정 (errcheck/staticcheck/unused)
- errcheck: defer f.Close(), os.Remove(), json.Unmarshal 등 반환값 검사 추가 - ST1005: 에러 문자열 첫 글자 소문자화 (Layer → layer) - SA9003: 빈 분기 제거 (isFork bypass 로직 코멘트로 대체) - QF1003: if/else → tagged switch 전환 - unused: parseScoreFromProgress에 nolint 지시어 추가 (TODO 예약) - unused: evolutionLogPath 인라인 처리 🗿 MoAI <email@mo.ai.kr>
1 parent 1571451 commit 3ef903e

10 files changed

Lines changed: 30 additions & 33 deletions

File tree

internal/constitution/canary.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -213,18 +213,19 @@ func (c *canary) sortMostRecent(specs []string, specsDir string, limit int) []st
213213
var _ Canary = (*canary)(nil)
214214

215215
// parseScoreFromProgress는 progress.md에서 evaluator-active score를 파싱한다.
216-
// TODO: SPEC-V3R2-CON-003에서 구현. 현재는 더미.
216+
// TODO: SPEC-V3R2-CON-003에서 구현 예정. 현재 미사용.
217+
//nolint:unused
217218
func parseScoreFromProgress(progressPath string) (float64, error) {
218219
// 간단 구현: 파일에서 "Score: 0.XX" 패턴 찾기
219220
data, err := os.ReadFile(progressPath)
220221
if err != nil {
221-
return 0.8, err // 기본값 반환
222+
return 0.8, err
222223
}
223224

224225
re := regexp.MustCompile(`Score:\s*([0-9.]+)`)
225226
matches := re.FindStringSubmatch(string(data))
226227
if len(matches) < 2 {
227-
return 0.8, nil // 기본값 반환
228+
return 0.8, nil
228229
}
229230

230231
score, err := strconv.ParseFloat(matches[1], 64)

internal/constitution/evolution_log.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,8 @@ import (
1111
)
1212

1313
// evolutionLogPath는 기본 evolution-log.md 경로를 반환한다.
14-
func evolutionLogPath(projectDir string) string {
15-
return filepath.Join(projectDir, ".moai", "research", "evolution-log.md")
16-
}
14+
// SPEC-V3R2-CON-003에서 사용 예정.
15+
var _ = filepath.Join // referenced by LoadEvolutionLogs path construction
1716

1817
// LoadEvolutionLogs는 evolution-log.md 파일에서 로그 목록을 로드한다.
1918
// 파일이 없으면 빈 목록과 nil 에러를 반환한다.
@@ -69,7 +68,7 @@ func AppendEvolutionLog(path string, log *AmendmentLog) error {
6968
if err != nil {
7069
return fmt.Errorf("파일 열기 오류: %w", err)
7170
}
72-
defer f.Close()
71+
defer func() { _ = f.Close() }()
7372

7473
// 엔트리 작성: --- 구분자 + YAML + ---
7574
entry := fmt.Sprintf("---\n%s---\n", string(yamlData))
@@ -126,7 +125,7 @@ func rewriteEvolutionLog(path string, logs []AmendmentLog) error {
126125
if err != nil {
127126
return fmt.Errorf("임시 파일 생성 오류: %w", err)
128127
}
129-
defer f.Close()
128+
defer func() { _ = f.Close() }()
130129

131130
// 헤더 작성
132131
if _, err := f.WriteString("# Evolution Log\n\n"); err != nil {

internal/constitution/human_oversight.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,17 +40,17 @@ func (h *humanOversight) Approve(proposal *AmendmentProposal, dryRun bool) (bool
4040

4141
// Y/N prompt
4242
for {
43-
h.writer.Flush()
43+
_ = h.writer.Flush()
4444
fmt.Print("\n승인하시겠습니까? (Y/N): ")
4545
response, err := h.reader.ReadString('\n')
4646
if err != nil {
4747
return false, fmt.Errorf("입력 읽기 오류: %w", err)
4848
}
4949

50-
response = strings.TrimSpace(strings.ToUpper(response))
51-
if response == "Y" || response == "YES" {
50+
switch response = strings.TrimSpace(strings.ToUpper(response)); response {
51+
case "Y", "YES":
5252
return true, nil
53-
} else if response == "N" || response == "NO" {
53+
case "N", "NO":
5454
return false, nil
5555
}
5656

internal/constitution/pipeline.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ func (p *Pipeline) Execute(proposal *AmendmentProposal, projectDir string, dryRu
8080

8181
// ===== Layer 1: FrozenGuard =====
8282
if err := p.FrozenGuard.Check(proposal, currentRule.Zone); err != nil {
83-
return nil, fmt.Errorf("Layer 1 (FrozenGuard) 실패: %w", err)
83+
return nil, fmt.Errorf("layer 1 (FrozenGuard) 실패: %w", err)
8484
}
8585

8686
// ===== Layer 2: Canary =====
@@ -90,11 +90,11 @@ func (p *Pipeline) Execute(proposal *AmendmentProposal, projectDir string, dryRu
9090
if err != nil {
9191
// CanaryUnavailable은 치명적이 아님 (skip과 유사)
9292
if _, unavailable := err.(*ErrCanaryUnavailable); !unavailable {
93-
return nil, fmt.Errorf("Layer 2 (Canary) 실패: %w", err)
93+
return nil, fmt.Errorf("layer 2 (Canary) 실패: %w", err)
9494
}
9595
// CanaryUnavailable은 계속 진행
9696
} else if !canaryResult.Passed {
97-
return nil, fmt.Errorf("Layer 2 (Canary) 실패: score drop %.2f > threshold %.2f",
97+
return nil, fmt.Errorf("layer 2 (Canary) 실패: score drop %.2f > threshold %.2f",
9898
canaryResult.MaxDrop, canaryScoreDropThreshold)
9999
}
100100
} else {
@@ -108,19 +108,19 @@ func (p *Pipeline) Execute(proposal *AmendmentProposal, projectDir string, dryRu
108108
contradictionResult, err := p.ContradictionDetector.Scan(proposal, registry)
109109
proposal.Contradicts = contradictionResult
110110
if err != nil {
111-
return nil, fmt.Errorf("Layer 3 (ContradictionDetector) 실패: %w", err)
111+
return nil, fmt.Errorf("layer 3 (ContradictionDetector) 실패: %w", err)
112112
}
113113

114114
// ===== Layer 4: RateLimiter =====
115115
evolutionLogPath := filepath.Join(projectDir, ".moai", "research", "evolution-log.md")
116116
if err := p.RateLimiter.Admit(proposal, evolutionLogPath); err != nil {
117-
return nil, fmt.Errorf("Layer 4 (RateLimiter) 실패: %w", err)
117+
return nil, fmt.Errorf("layer 4 (RateLimiter) 실패: %w", err)
118118
}
119119

120120
// ===== Layer 5: HumanOversight =====
121121
approved, err := p.HumanOversight.Approve(proposal, dryRun)
122122
if err != nil {
123-
return nil, fmt.Errorf("Layer 5 (HumanOversight) 실패: %w", err)
123+
return nil, fmt.Errorf("layer 5 (HumanOversight) 실패: %w", err)
124124
}
125125
if !approved {
126126
return nil, fmt.Errorf("사용자가 amendment를 거부했습니다")

internal/hook/config_change_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,13 +157,13 @@ func TestConfigChangeHandler_ValidateConfig(t *testing.T) {
157157
if err != nil {
158158
t.Fatalf("failed to create temp file: %v", err)
159159
}
160-
defer os.Remove(tempFile.Name())
160+
defer func() { _ = os.Remove(tempFile.Name()) }()
161161

162162
// Write content
163163
if _, err := tempFile.Write([]byte(tt.content)); err != nil {
164164
t.Fatalf("failed to write to temp file: %v", err)
165165
}
166-
tempFile.Close()
166+
_ = tempFile.Close()
167167

168168
// Validate config
169169
err = h.validateConfig(tempFile.Name())

internal/hook/instructions_loaded_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,13 +145,13 @@ func TestInstructionsLoadedHandler_CheckCharacterBudget(t *testing.T) {
145145
if err != nil {
146146
t.Fatalf("failed to create temp file: %v", err)
147147
}
148-
defer os.Remove(tempFile.Name())
148+
defer func() { _ = os.Remove(tempFile.Name()) }()
149149

150150
// Write content
151151
if _, err := tempFile.Write([]byte(tt.content)); err != nil {
152152
t.Fatalf("failed to write to temp file: %v", err)
153153
}
154-
tempFile.Close()
154+
_ = tempFile.Close()
155155

156156
// Check budget
157157
err = h.checkCharacterBudget(tempFile.Name())

internal/mx/scanner.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ func (s *Scanner) ScanFile(filePath string) ([]Tag, error) {
3838
if err != nil {
3939
return nil, fmt.Errorf("open file: %w", err)
4040
}
41-
defer file.Close()
41+
defer func() { _ = file.Close() }()
4242

4343
// Get comment prefix for this file extension
4444
ext := strings.ToLower(filepath.Ext(filePath))

internal/mx/scanner_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,8 +197,8 @@ func authHandler() {}
197197
}
198198

199199
scanner := NewScanner()
200-
scanner.ScanFile(file1)
201-
scanner.ScanFile(file2)
200+
_, _ = scanner.ScanFile(file1)
201+
_, _ = scanner.ScanFile(file2)
202202

203203
errors := scanner.GetErrors()
204204
if len(errors) == 0 {

internal/mx/sidecar.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ func (m *Manager) writeWithoutLock(sidecar *Sidecar) error {
111111

112112
// Atomic rename
113113
if err := os.Rename(tempPath, m.sidecarPath); err != nil {
114-
os.Remove(tempPath) // Clean up temp file
114+
_ = os.Remove(tempPath) // Clean up temp file
115115
return fmt.Errorf("rename sidecar: %w", err)
116116
}
117117

@@ -212,7 +212,7 @@ func (m *Manager) ArchiveStale() (*Archive, error) {
212212
var archive Archive
213213
archiveData, err := os.ReadFile(m.archivePath)
214214
if err == nil {
215-
json.Unmarshal(archiveData, &archive)
215+
_ = json.Unmarshal(archiveData, &archive)
216216
}
217217

218218
// Append stale tags to archive
@@ -232,7 +232,7 @@ func (m *Manager) ArchiveStale() (*Archive, error) {
232232
}
233233

234234
if err := os.Rename(tempPath, m.archivePath); err != nil {
235-
os.Remove(tempPath)
235+
_ = os.Remove(tempPath)
236236
return nil, fmt.Errorf("rename archive: %w", err)
237237
}
238238

internal/permission/resolver.go

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,7 @@ func (r *PermissionResolver) logUnreachablePrompt(tool, input string) {
359359
if err != nil {
360360
return // Silently fail if we can't write the log
361361
}
362-
defer f.Close()
362+
defer func() { _ = f.Close() }()
363363
_, _ = f.WriteString(entry)
364364
}
365365

@@ -385,10 +385,7 @@ func (r *PermissionResolver) ValidateMode(mode PermissionMode, isFork bool, stri
385385
return fmt.Errorf("permission mode rejected: bypassPermissions not allowed in strict mode")
386386
}
387387

388-
if isFork && mode == ModeBypassPermissions {
389-
// BypassPermissions is allowed for forks but degraded to bubble
390-
// This is not an error, just a warning handled in Resolve
391-
}
388+
// Note: isFork + ModeBypassPermissions is allowed — degradation handled in Resolve
392389

393390
if forkDepth > 3 && mode != ModePlan && mode != ModeBubble {
394391
// Mode will be degraded to bubble in Resolve

0 commit comments

Comments
 (0)