fix(lint): address gosec, misspell, and unparam warnings
- gate.go: fix "cancelled" → "canceled" misspelling, add #nosec for validated GitHub IDs in exec.Command, mark checkTimer escalated as intentionally false, rename unused ctx param - sync_divergence.go: add #nosec for git commands with validated paths, mark unused path param - sync_branch.go: add #nosec for .git/info/exclude permissions - setup.go: add #nosec for config file permissions - recipes.go: add #nosec for validated config file paths - external_deps.go: add #nosec for SQL with generated placeholders 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
committed by
Steve Yegge
parent
ee179f5b6d
commit
7b0f398f11
@@ -339,7 +339,7 @@ func addToGitExclude(path, pattern string) error {
|
||||
}
|
||||
|
||||
// Append pattern
|
||||
f, err := os.OpenFile(excludePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||
f, err := os.OpenFile(excludePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) // #nosec G302 -- .git/info/exclude needs to be readable
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to open exclude file: %w", err)
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ func checkJSONLGitDivergence(path, beadsDir string) *SyncDivergenceIssue {
|
||||
}
|
||||
|
||||
// Check if file is tracked by git
|
||||
cmd := exec.Command("git", "ls-files", "--error-unmatch", relPath)
|
||||
cmd := exec.Command("git", "ls-files", "--error-unmatch", relPath) // #nosec G204 -- relPath is derived from validated file path
|
||||
cmd.Dir = path
|
||||
if err := cmd.Run(); err != nil {
|
||||
// File not tracked by git
|
||||
@@ -132,7 +132,7 @@ func checkJSONLGitDivergence(path, beadsDir string) *SyncDivergenceIssue {
|
||||
}
|
||||
|
||||
// Compare current file with HEAD
|
||||
cmd = exec.Command("git", "diff", "--quiet", "HEAD", "--", relPath)
|
||||
cmd = exec.Command("git", "diff", "--quiet", "HEAD", "--", relPath) // #nosec G204 -- relPath is derived from validated file path
|
||||
cmd.Dir = path
|
||||
if err := cmd.Run(); err != nil {
|
||||
// Exit code non-zero means there are differences
|
||||
@@ -147,7 +147,7 @@ func checkJSONLGitDivergence(path, beadsDir string) *SyncDivergenceIssue {
|
||||
}
|
||||
|
||||
// checkSQLiteMtimeDivergence checks if SQLite last_import_time matches JSONL mtime.
|
||||
func checkSQLiteMtimeDivergence(path, beadsDir string) *SyncDivergenceIssue {
|
||||
func checkSQLiteMtimeDivergence(_, beadsDir string) *SyncDivergenceIssue { //nolint:unparam // path reserved for future use
|
||||
// Get database path
|
||||
dbPath := filepath.Join(beadsDir, beads.CanonicalDatabaseName)
|
||||
if cfg, err := configfile.Load(beadsDir); err == nil && cfg != nil && cfg.Database != "" {
|
||||
@@ -235,7 +235,7 @@ func checkUncommittedBeadsChanges(path, beadsDir string) *SyncDivergenceIssue {
|
||||
}
|
||||
|
||||
// Check for uncommitted changes in .beads/
|
||||
cmd := exec.Command("git", "status", "--porcelain", "--", relBeadsDir)
|
||||
cmd := exec.Command("git", "status", "--porcelain", "--", relBeadsDir) // #nosec G204 -- relBeadsDir is derived from validated path
|
||||
cmd.Dir = path
|
||||
out, err := cmd.Output()
|
||||
if err != nil {
|
||||
|
||||
@@ -442,7 +442,7 @@ A gate is resolved when:
|
||||
- bead: target bead status=closed
|
||||
|
||||
A gate is escalated when:
|
||||
- gh:run: status=completed AND conclusion in (failure, cancelled)
|
||||
- gh:run: status=completed AND conclusion in (failure, canceled)
|
||||
- gh:pr: state=CLOSED AND merged=false
|
||||
|
||||
Examples:
|
||||
@@ -645,7 +645,7 @@ func checkGHRun(gate *types.Issue) (resolved, escalated bool, reason string, err
|
||||
}
|
||||
|
||||
// Run: gh run view <id> --json status,conclusion,name
|
||||
cmd := exec.Command("gh", "run", "view", gate.AwaitID, "--json", "status,conclusion,name")
|
||||
cmd := exec.Command("gh", "run", "view", gate.AwaitID, "--json", "status,conclusion,name") // #nosec G204 -- gate.AwaitID is a validated GitHub run ID
|
||||
var stdout, stderr bytes.Buffer
|
||||
cmd.Stdout = &stdout
|
||||
cmd.Stderr = &stderr
|
||||
@@ -676,8 +676,8 @@ func checkGHRun(gate *types.Issue) (resolved, escalated bool, reason string, err
|
||||
return true, false, fmt.Sprintf("workflow '%s' succeeded", status.Name), nil
|
||||
case "failure":
|
||||
return false, true, fmt.Sprintf("workflow '%s' failed", status.Name), nil
|
||||
case "cancelled":
|
||||
return false, true, fmt.Sprintf("workflow '%s' was cancelled", status.Name), nil
|
||||
case "cancelled", "canceled":
|
||||
return false, true, fmt.Sprintf("workflow '%s' was canceled", status.Name), nil
|
||||
case "skipped":
|
||||
return true, false, fmt.Sprintf("workflow '%s' was skipped", status.Name), nil
|
||||
default:
|
||||
@@ -697,7 +697,7 @@ func checkGHPR(gate *types.Issue) (resolved, escalated bool, reason string, err
|
||||
}
|
||||
|
||||
// Run: gh pr view <id> --json state,merged,title
|
||||
cmd := exec.Command("gh", "pr", "view", gate.AwaitID, "--json", "state,merged,title")
|
||||
cmd := exec.Command("gh", "pr", "view", gate.AwaitID, "--json", "state,merged,title") // #nosec G204 -- gate.AwaitID is a validated GitHub PR number
|
||||
var stdout, stderr bytes.Buffer
|
||||
cmd.Stdout = &stdout
|
||||
cmd.Stderr = &stderr
|
||||
@@ -737,7 +737,8 @@ func checkGHPR(gate *types.Issue) (resolved, escalated bool, reason string, err
|
||||
}
|
||||
|
||||
// checkTimer checks a timer gate for expiration
|
||||
func checkTimer(gate *types.Issue, now time.Time) (resolved, escalated bool, reason string, err error) {
|
||||
// Note: timers resolve but never escalate (escalated is always false by design)
|
||||
func checkTimer(gate *types.Issue, now time.Time) (resolved, escalated bool, reason string, err error) { //nolint:unparam // escalated intentionally always false
|
||||
if gate.Timeout == 0 {
|
||||
return false, false, "timer gate without timeout configured", fmt.Errorf("no timeout set")
|
||||
}
|
||||
@@ -815,7 +816,7 @@ func checkBeadGate(ctx context.Context, awaitID string) (bool, string) {
|
||||
}
|
||||
|
||||
// closeGate closes a gate issue with the given reason
|
||||
func closeGate(ctx interface{}, gateID, reason string) error {
|
||||
func closeGate(_ interface{}, gateID, reason string) error {
|
||||
if daemonClient != nil {
|
||||
closeArgs := &rpc.CloseArgs{
|
||||
ID: gateID,
|
||||
|
||||
@@ -131,7 +131,7 @@ func writeToPath(path string) error {
|
||||
}
|
||||
}
|
||||
|
||||
if err := os.WriteFile(path, []byte(recipes.Template), 0o644); err != nil {
|
||||
if err := os.WriteFile(path, []byte(recipes.Template), 0o644); err != nil { // #nosec G306 -- config files need to be readable
|
||||
return fmt.Errorf("write file: %w", err)
|
||||
}
|
||||
return nil
|
||||
@@ -225,7 +225,7 @@ func runRecipe(name string) {
|
||||
}
|
||||
}
|
||||
|
||||
if err := os.WriteFile(recipe.Path, []byte(recipes.Template), 0o644); err != nil {
|
||||
if err := os.WriteFile(recipe.Path, []byte(recipes.Template), 0o644); err != nil { // #nosec G306 -- config files need to be readable
|
||||
fmt.Fprintf(os.Stderr, "Error: write file: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user