Skip to content

Commit 06c827b

Browse files
authored
chore: update golangci-lint to v2.11.4 (#230)
1 parent 9d9ff85 commit 06c827b

29 files changed

Lines changed: 178 additions & 152 deletions

.github/workflows/main.yml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,13 @@ jobs:
4545
- name: Download dependencies
4646
run: go mod download
4747

48+
- name: Install linters
49+
run: make install-lint-tools
50+
4851
- name: Lint
49-
uses: golangci/golangci-lint-action@55c2c1448f86e01eaae002a5a3a9624417608d84 # v6
52+
uses: golangci/golangci-lint-action@0a35821d5c230e903fcfe077583637dea1b27b47 # v9
5053
with:
51-
install-mode: goinstall
52-
version: v1.64.8
54+
install-mode: "none"
5355

5456
test:
5557
name: Test

.golangci.yml

Lines changed: 50 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,59 @@
1+
version: "2"
12
run:
2-
timeout: 5m
33
modules-download-mode: readonly
4-
5-
linters-settings:
6-
gci:
7-
sections:
8-
- standard
9-
- default
10-
- prefix(github.com/Use-Tusk/tusk-cli)
11-
gofmt:
12-
simplify: true
13-
goimports:
14-
local-prefixes: github.com/Use-Tusk/tusk-cli
15-
gocritic:
16-
disabled-checks:
17-
- singleCaseSwitch
18-
revive:
19-
rules:
20-
- name: exported
21-
disabled: true
22-
234
linters:
24-
enable-all: false
25-
disable-all: true
5+
default: none
266
enable:
27-
- staticcheck
287
- errcheck
29-
- gosimple
8+
- gocritic
9+
- gosec
3010
- govet
31-
- unused
3211
- ineffassign
33-
- gosec
34-
- gocritic
12+
- misspell
3513
- revive
14+
- staticcheck
15+
- unused
16+
settings:
17+
gocritic:
18+
disabled-checks:
19+
- singleCaseSwitch
20+
staticcheck:
21+
checks:
22+
- all
23+
- -ST1000
24+
- -ST1003
25+
- -ST1005
26+
- -ST1016
27+
- -ST1020
28+
- -ST1021
29+
- -ST1022
30+
revive:
31+
rules:
32+
- name: exported
33+
disabled: true
34+
exclusions:
35+
generated: lax
36+
paths:
37+
- third_party$
38+
- builtin$
39+
- examples$
40+
formatters:
41+
enable:
3642
- gofumpt
37-
- ineffassign
38-
- misspell
39-
40-
issues:
41-
exclude-use-default: false
43+
settings:
44+
gci:
45+
sections:
46+
- standard
47+
- default
48+
- prefix(github.com/Use-Tusk/tusk-cli)
49+
gofmt:
50+
simplify: true
51+
goimports:
52+
local-prefixes:
53+
- github.com/Use-Tusk/tusk-cli
54+
exclusions:
55+
generated: lax
56+
paths:
57+
- third_party$
58+
- builtin$
59+
- examples$

Makefile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ GOMOD=$(GOCMD) mod
77
BINARY_NAME=tusk
88
BINARY_UNIX=$(BINARY_NAME)_unix
99

10+
# Tool versions
11+
GOLANGCI_LINT_VERSION=v2.11.4
12+
1013

1114
.PHONY: all build build-ci build-linux test test-ci clean deps install-buf install-lint-tools setup setup-ci run fmt lint help
1215

@@ -54,7 +57,7 @@ install-buf:
5457
install-lint-tools:
5558
@echo "📦 Installing linting tools..."
5659
GOTOOLCHAIN=local go install mvdan.cc/gofumpt@latest
57-
GOTOOLCHAIN=local go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
60+
GOTOOLCHAIN=local go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@$(GOLANGCI_LINT_VERSION)
5861
@echo "✅ Linting tools installed"
5962

6063
setup: install-buf deps install-lint-tools

cmd/setup.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ func getAnthropicAPIConfig() (*APIConfig, error) {
9595

9696
if envKey := os.Getenv("ANTHROPIC_API_KEY"); envKey != "" {
9797
// In non-interactive mode (CI/scripts), default to BYOK to avoid hanging
98-
if !term.IsTerminal(int(os.Stdin.Fd())) {
98+
if !term.IsTerminal(int(os.Stdin.Fd())) { //nolint:gosec // file descriptor fits in int
9999
return &APIConfig{
100100
Mode: agent.APIModeDirect,
101101
APIKey: envKey,

internal/agent/agent.go

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ func (a *Agent) trackInterrupted(phaseName string, phasesCompleted int) {
200200
// Run executes the agent with TUI or in headless mode
201201
func (a *Agent) Run(parentCtx context.Context) error {
202202
// Create cancellable context
203-
a.ctx, a.cancel = context.WithCancel(parentCtx)
203+
a.ctx, a.cancel = context.WithCancel(parentCtx) //nolint:gosec // cancel is invoked via defer below
204204
defer a.cancel()
205205

206206
if a.logger != nil {
@@ -1659,31 +1659,31 @@ func (a *Agent) saveProgress(completedPhases []string, currentPhase string, note
16591659
sb.WriteString("## Discovered Information\n\n")
16601660
if state != nil && (state.ProjectType != "" || state.PackageManager != "" || state.EntryPoint != "") {
16611661
if state.ServiceName != "" {
1662-
sb.WriteString(fmt.Sprintf("- **Service Name**: %s\n", state.ServiceName))
1662+
fmt.Fprintf(&sb, "- **Service Name**: %s\n", state.ServiceName)
16631663
}
16641664
if state.ProjectType != "" {
1665-
sb.WriteString(fmt.Sprintf("- **Project Type**: %s\n", state.ProjectType))
1665+
fmt.Fprintf(&sb, "- **Project Type**: %s\n", state.ProjectType)
16661666
}
16671667
if state.PackageManager != "" {
1668-
sb.WriteString(fmt.Sprintf("- **Package Manager**: %s\n", state.PackageManager))
1668+
fmt.Fprintf(&sb, "- **Package Manager**: %s\n", state.PackageManager)
16691669
}
16701670
if state.ModuleSystem != "" {
1671-
sb.WriteString(fmt.Sprintf("- **Module System**: %s\n", state.ModuleSystem))
1671+
fmt.Fprintf(&sb, "- **Module System**: %s\n", state.ModuleSystem)
16721672
}
16731673
if state.EntryPoint != "" {
1674-
sb.WriteString(fmt.Sprintf("- **Entry Point**: %s\n", state.EntryPoint))
1674+
fmt.Fprintf(&sb, "- **Entry Point**: %s\n", state.EntryPoint)
16751675
}
16761676
if state.StartCommand != "" {
1677-
sb.WriteString(fmt.Sprintf("- **Start Command**: `%s`\n", state.StartCommand))
1677+
fmt.Fprintf(&sb, "- **Start Command**: `%s`\n", state.StartCommand)
16781678
}
16791679
if state.Port != "" {
1680-
sb.WriteString(fmt.Sprintf("- **Port**: %s\n", state.Port))
1680+
fmt.Fprintf(&sb, "- **Port**: %s\n", state.Port)
16811681
}
16821682
if state.HealthEndpoint != "" {
1683-
sb.WriteString(fmt.Sprintf("- **Health Endpoint**: %s\n", state.HealthEndpoint))
1683+
fmt.Fprintf(&sb, "- **Health Endpoint**: %s\n", state.HealthEndpoint)
16841684
}
16851685
if state.DockerType != "" && state.DockerType != "none" {
1686-
sb.WriteString(fmt.Sprintf("- **Docker**: %s\n", state.DockerType))
1686+
fmt.Fprintf(&sb, "- **Docker**: %s\n", state.DockerType)
16871687
}
16881688
sb.WriteString("\n")
16891689
} else {
@@ -1695,7 +1695,7 @@ func (a *Agent) saveProgress(completedPhases []string, currentPhase string, note
16951695
sb.WriteString("The following packages are used but not instrumented by the SDK.\n")
16961696
sb.WriteString("Recording/replay may not capture these calls:\n\n")
16971697
for _, warning := range state.CompatibilityWarnings {
1698-
sb.WriteString(fmt.Sprintf("- ⚠️ %s\n", warning))
1698+
fmt.Fprintf(&sb, "- ⚠️ %s\n", warning)
16991699
}
17001700
sb.WriteString("\n")
17011701
}
@@ -1725,10 +1725,10 @@ func (a *Agent) saveProgress(completedPhases []string, currentPhase string, note
17251725
sb.WriteString("- ✓ Authenticated with Tusk Cloud\n")
17261726
}
17271727
if state.GitRepoOwner != "" && state.GitRepoName != "" {
1728-
sb.WriteString(fmt.Sprintf("- ✓ Repository detected: %s/%s\n", state.GitRepoOwner, state.GitRepoName))
1728+
fmt.Fprintf(&sb, "- ✓ Repository detected: %s/%s\n", state.GitRepoOwner, state.GitRepoName)
17291729
}
17301730
if state.CloudServiceID != "" {
1731-
sb.WriteString(fmt.Sprintf("- ✓ Cloud service created (ID: %s)\n", state.CloudServiceID))
1731+
fmt.Fprintf(&sb, "- ✓ Cloud service created (ID: %s)\n", state.CloudServiceID)
17321732
}
17331733
if state.ApiKeyCreated {
17341734
sb.WriteString("- ✓ API key created\n")
@@ -1741,31 +1741,31 @@ func (a *Agent) saveProgress(completedPhases []string, currentPhase string, note
17411741
sb.WriteString("None yet.\n\n")
17421742
} else {
17431743
for _, phase := range completedPhases {
1744-
sb.WriteString(fmt.Sprintf("- ✓ %s\n", phase))
1744+
fmt.Fprintf(&sb, "- ✓ %s\n", phase)
17451745
}
17461746
sb.WriteString("\n")
17471747
}
17481748

17491749
if currentPhase != "" {
1750-
sb.WriteString(fmt.Sprintf("## Current Phase\n\n%s (in progress)\n\n", currentPhase))
1750+
fmt.Fprintf(&sb, "## Current Phase\n\n%s (in progress)\n\n", currentPhase)
17511751
}
17521752

17531753
if state != nil && (len(state.Errors) > 0 || len(state.Warnings) > 0) {
17541754
if len(state.Errors) > 0 {
17551755
sb.WriteString("## Errors Encountered\n\n")
17561756
for _, err := range state.Errors {
17571757
if err.Fatal {
1758-
sb.WriteString(fmt.Sprintf("- ❌ [%s] %s (fatal)\n", err.Phase, err.Message))
1758+
fmt.Fprintf(&sb, "- ❌ [%s] %s (fatal)\n", err.Phase, err.Message)
17591759
} else {
1760-
sb.WriteString(fmt.Sprintf("- ⚠️ [%s] %s\n", err.Phase, err.Message))
1760+
fmt.Fprintf(&sb, "- ⚠️ [%s] %s\n", err.Phase, err.Message)
17611761
}
17621762
}
17631763
sb.WriteString("\n")
17641764
}
17651765
if len(state.Warnings) > 0 {
17661766
sb.WriteString("## Warnings\n\n")
17671767
for _, w := range state.Warnings {
1768-
sb.WriteString(fmt.Sprintf("- %s\n", w))
1768+
fmt.Fprintf(&sb, "- %s\n", w)
17691769
}
17701770
sb.WriteString("\n")
17711771
}
@@ -1777,7 +1777,7 @@ func (a *Agent) saveProgress(completedPhases []string, currentPhase string, note
17771777
sb.WriteString("\n\n")
17781778
}
17791779

1780-
sb.WriteString(fmt.Sprintf("---\nLast updated: %s\n", time.Now().Format(time.RFC3339)))
1780+
fmt.Fprintf(&sb, "---\nLast updated: %s\n", time.Now().Format(time.RFC3339))
17811781

17821782
return os.WriteFile(a.progressFilePath(), []byte(sb.String()), 0o600)
17831783
}

internal/agent/phases.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ func (pm *PhaseManager) UpdateState(results map[string]interface{}) {
228228

229229
// StateAsContext returns the current state as a string for the prompt
230230
func (pm *PhaseManager) StateAsContext() string {
231-
data, _ := json.MarshalIndent(pm.state, "", " ")
231+
data, _ := json.MarshalIndent(pm.state, "", " ") //nolint:gosec // intentional serialization of agent state
232232
result := string(data)
233233

234234
// Include previous progress if available
@@ -1027,10 +1027,10 @@ func eligibilityCheckPhase() *Phase {
10271027
}
10281028
manifest, err := tools.FetchManifestFromURL(url)
10291029
if err != nil {
1030-
extra.WriteString(fmt.Sprintf("**%s**: Failed to fetch manifest - %s\n\n", lang, err))
1030+
fmt.Fprintf(&extra, "**%s**: Failed to fetch manifest - %s\n\n", lang, err)
10311031
continue
10321032
}
1033-
extra.WriteString(fmt.Sprintf("**%s Manifest**:\n```json\n%s\n```\n\n", lang, manifest))
1033+
fmt.Fprintf(&extra, "**%s Manifest**:\n```json\n%s\n```\n\n", lang, manifest)
10341034
}
10351035

10361036
// Add user guidance if provided

internal/agent/tools/abort.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ func ResetPhaseProgress(workDir string) func(json.RawMessage) (string, error) {
104104
}
105105

106106
newContent := strings.Join(newLines, "\n")
107-
if err := os.WriteFile(progressPath, []byte(newContent), 0o600); err != nil {
107+
if err := os.WriteFile(progressPath, []byte(newContent), 0o600); err != nil { //nolint:gosec // path is constructed internally for agent progress tracking
108108
return "", err
109109
}
110110

internal/agent/tools/filesystem.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ func (ft *FilesystemTools) PatchFile(input json.RawMessage) (string, error) {
225225
modified += "\n"
226226
}
227227

228-
if err := os.WriteFile(fullPath, []byte(modified), 0o600); err != nil {
228+
if err := os.WriteFile(fullPath, []byte(modified), 0o600); err != nil { //nolint:gosec // agent tool deliberately writes to user-specified paths
229229
return "", fmt.Errorf("failed to write file: %w", err)
230230
}
231231

internal/agent/ui_headless.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ func (u *HeadlessUI) AgentText(text string, streaming bool) {
102102
if strings.TrimSpace(text) != "" {
103103
width := 90
104104
if utils.IsTerminal() {
105-
if w, _, err := term.GetSize(int(os.Stdout.Fd())); err == nil && w > 0 {
105+
if w, _, err := term.GetSize(int(os.Stdout.Fd())); err == nil && w > 0 { //nolint:gosec // file descriptor fits in int
106106
width = max(w-4, 40)
107107
}
108108
}

internal/analytics/notice.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ func ShowFirstRunNotice(cmd *cobra.Command) bool {
2929
}
3030

3131
// Skip if not a TTY (piped output)
32-
if !term.IsTerminal(int(os.Stdout.Fd())) {
32+
if !term.IsTerminal(int(os.Stdout.Fd())) { //nolint:gosec // file descriptor fits in int
3333
return false
3434
}
3535

0 commit comments

Comments
 (0)