Skip to content

Commit 602899a

Browse files
authored
chore: Go 1.27 toolchain, lint fixes, go fix modernization (#800)
## Description Full Go 1.27 update in four commits: 1. **Toolchain go1.26.6 → go1.27.0** — CI resolves its Go version from `go.mod` via the shared `netresearch/.github` go-check workflow. Also bumps the two Makefile `GOTOOLCHAIN` pins for the golangci-lint install, and corrects the prerequisite in `docs/DEVELOPMENT.md` and `CONTRIBUTING.md` from "Go 1.25+" to "Go 1.26+" (the `go` directive has required 1.26 already). 2. **Lint fixes under the 1.27 toolchain** — gofumpt's new closing-paren placement in one test file, and removal of six `//nolint:goconst` directives that nolintlint now reports as unused (goconst no longer fires there; all annotated literals sit below the config's `min-occurrences: 6`, and `.golangci.yml` is untouched by this PR). 3. **`go fix` modernization** across 14 files — `strings.Cut` (2 sites), `slices.Backward` (RemoveJobsByTag), `maps.Copy`, `errors.AsType[T]` (3 sites), `atomic.Int32` migrations in six test files, and inlining of the `durationPtr`/`uint64Ptr` test helpers to `new(expr)` with the now-unused helpers removed. 4. **Review-round comment fix** — the `slices.Backward` removal in RemoveJobsByTag is safe because of the `break` after the removal (the range form captures the slice header once); the comment now says so instead of describing the old index loop. The `go` directive stays at 1.26. ## Testing `go build ./...`, `go vet ./...`, `golangci-lint run` (0 issues) and `go test -race ./...` (14 packages, all pass) under go1.27.0; `go mod tidy` is a no-op. An independent review agent proved the `slices.Backward` rewrite equivalent for all inputs (including duplicate cron IDs), verified the goconst occurrence counts against the config, and found no weakened assertions. The advisory SonarCloud check is red on new-code duplication (5.3% vs 3%) — the mechanical `atomic.Int32` test rewrites count as "new code"; not in the required-checks ruleset. _Assisted by claude-code:claude-fable-5 — [Session](https://claude.ai/code/session_01L7tF9XuJfAfFk4yuY5KfPK)_
2 parents b2397a6 + e2b863b commit 602899a

24 files changed

Lines changed: 86 additions & 92 deletions

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ The project's lefthook `commit-msg` hook validates the presence of
5353

5454
### Prerequisites
5555

56-
- Go 1.25 or higher
56+
- Go 1.26 or higher
5757
- Docker (for integration and E2E tests)
5858
- Docker Swarm enabled (for service job tests)
5959

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,14 @@ tidy:
5454
.PHONY: lint
5555
lint:
5656
@mkdir -p $(BUILD_PATH)/.tools
57-
@GOTOOLCHAIN=go1.26.5 GOBIN=$(BUILD_PATH)/.tools go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@latest
57+
@GOTOOLCHAIN=go1.27.0 GOBIN=$(BUILD_PATH)/.tools go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@latest
5858
@$(BUILD_PATH)/.tools/golangci-lint version || true
5959
@$(BUILD_PATH)/.tools/golangci-lint run --timeout=5m
6060

6161
.PHONY: lint-fix
6262
lint-fix:
6363
@mkdir -p $(BUILD_PATH)/.tools
64-
@GOTOOLCHAIN=go1.26.5 GOBIN=$(BUILD_PATH)/.tools go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@latest
64+
@GOTOOLCHAIN=go1.27.0 GOBIN=$(BUILD_PATH)/.tools go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@latest
6565
@$(BUILD_PATH)/.tools/golangci-lint run --fix --timeout=5m
6666

6767
.PHONY: lint-full

cli/config_decode.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ func mapstructureKeyForField(field reflect.StructField) string {
168168
return ""
169169
}
170170
if tag != "" {
171-
if name := strings.SplitN(tag, ",", 2)[0]; name != "" && name != "-" {
171+
if name, _, _ := strings.Cut(tag, ","); name != "" && name != "-" {
172172
return name
173173
}
174174
}

cli/config_drift_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ func assertDocumented(t *testing.T, docs string, f reflect.StructField, containe
7676
if tag == "" {
7777
return
7878
}
79-
name := strings.SplitN(tag, ",", 2)[0]
79+
name, _, _ := strings.Cut(tag, ",")
8080
if name == "" || name == "-" {
8181
return // squash on the embed itself, or explicitly ignored
8282
}

cli/config_webhook.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,7 @@ func applyWebhookLabelParams(config *middlewares.WebhookConfig, params map[strin
405405
config.Preset = val
406406
case "id":
407407
config.ID = val
408-
case "secret": //nolint:goconst // matches gcfg:"secret" struct tag — Go syntax requires literal in tag
408+
case "secret":
409409
config.Secret = val
410410
case "url":
411411
config.URL = val

cli/docker-labels.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,7 @@ func (c *Config) filterGlobalLabelKey(key, value, containerName string, globalCo
527527

528528
func hasServiceLabel(labels map[string]string) bool {
529529
for k, v := range labels {
530-
if k == serviceLabel && v == "true" { //nolint:goconst // Docker labels are stringly-typed — value is the literal "true"
530+
if k == serviceLabel && v == "true" {
531531
return true
532532
}
533533
}

cli/doctor_docker_timeout_test.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,13 @@ func (h *hangingDoctorProvider) InspectExec(_ context.Context, _ string) (*domai
8686
func (h *hangingDoctorProvider) RunExec(_ context.Context, _ string, _ *domain.ExecConfig, _, _ io.Writer) (int, error) {
8787
return 0, nil
8888
}
89-
func (h *hangingDoctorProvider) PullImage(_ context.Context, _ string) error { return nil }
89+
90+
func (h *hangingDoctorProvider) PullImage(_ context.Context, _ string) error { return nil }
91+
9092
func (h *hangingDoctorProvider) EnsureImage(_ context.Context, _ string, _ bool) error { return nil }
91-
func (h *hangingDoctorProvider) ConnectNetwork(_ context.Context, _, _ string) error { return nil }
93+
94+
func (h *hangingDoctorProvider) ConnectNetwork(_ context.Context, _, _ string) error { return nil }
95+
9296
func (h *hangingDoctorProvider) FindNetworkByName(_ context.Context, _ string) ([]domain.Network, error) {
9397
return nil, nil
9498
}

config/validator.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -387,11 +387,11 @@ func (cv *Validator2) validateSpecificStringField(v *Validator, path string, str
387387
switch fieldKey(path) {
388388
case keySchedule, "cron":
389389
cv.validateCronField(v, path, str)
390-
case "email-to", "email-from": //nolint:goconst // see comment above switch
390+
case "email-to", "email-from":
391391
cv.validateEmailField(v, path, str)
392392
case "web-address", "pprof-address":
393393
cv.validateAddressField(v, path, str)
394-
case "log-level": //nolint:goconst // see comment above switch
394+
case "log-level":
395395
cv.validateLogLevelField(v, path, str)
396396
case keyCommand, "cmd":
397397
cv.validateCommandField(v, path, str)

core/adapters/docker/service_convert_test.go

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,9 @@ func TestConvertToSwarmSpec(t *testing.T) {
110110
ContainerSpec: domain.ContainerSpec{Image: "nginx"},
111111
RestartPolicy: &domain.ServiceRestartPolicy{
112112
Condition: domain.RestartConditionOnFailure,
113-
Delay: durationPtr(5 * time.Second),
114-
MaxAttempts: uint64Ptr(3),
115-
Window: durationPtr(2 * time.Minute),
113+
Delay: new(5 * time.Second),
114+
MaxAttempts: new(uint64(3)),
115+
Window: new(2 * time.Minute),
116116
},
117117
},
118118
},
@@ -219,7 +219,7 @@ func TestConvertToSwarmSpec(t *testing.T) {
219219
ContainerSpec: domain.ContainerSpec{Image: "nginx"},
220220
},
221221
Mode: domain.ServiceMode{
222-
Replicated: &domain.ReplicatedService{Replicas: uint64Ptr(3)},
222+
Replicated: &domain.ReplicatedService{Replicas: new(uint64(3))},
223223
},
224224
},
225225
validate: func(t *testing.T, result swarm.ServiceSpec) {
@@ -451,11 +451,3 @@ func TestConvertFromSwarmTask(t *testing.T) {
451451
}
452452

453453
// --- Helper functions ---
454-
455-
func durationPtr(d time.Duration) *time.Duration {
456-
return &d
457-
}
458-
459-
func uint64Ptr(v uint64) *uint64 {
460-
return &v
461-
}

core/adapters/docker/service_roundtrip_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -166,9 +166,9 @@ func TestServiceSpec_RoundTrip_RestartPolicy(t *testing.T) {
166166
},
167167
RestartPolicy: &domain.ServiceRestartPolicy{
168168
Condition: domain.RestartConditionOnFailure,
169-
Delay: durationPtr(10 * time.Second),
170-
MaxAttempts: uint64Ptr(5),
171-
Window: durationPtr(3 * time.Minute),
169+
Delay: new(10 * time.Second),
170+
MaxAttempts: new(uint64(5)),
171+
Window: new(3 * time.Minute),
172172
},
173173
},
174174
}
@@ -251,7 +251,7 @@ func TestServiceSpec_RoundTrip_ModeReplicated(t *testing.T) {
251251
},
252252
Mode: domain.ServiceMode{
253253
Replicated: &domain.ReplicatedService{
254-
Replicas: uint64Ptr(3),
254+
Replicas: new(uint64(3)),
255255
},
256256
},
257257
}

0 commit comments

Comments
 (0)