Skip to content

fix: clean up 15 lint violations and the events test data race#2

Merged
davidfic merged 1 commit intomainfrom
fix/lint-and-events-race
Apr 15, 2026
Merged

fix: clean up 15 lint violations and the events test data race#2
davidfic merged 1 commit intomainfrom
fix/lint-and-events-race

Conversation

@davidfic
Copy link
Copy Markdown
Contributor

Summary

First green-CI pass on pulse. Clears every pre-existing issue the freshly-added CI surfaced when it ran against main for the first time. No functional changes to production code.

errcheck (12 violations → 0)

  • internal/torznab/types.go — `MarshalXML` now properly propagates `xml.Encoder.EncodeToken` errors via early-return. `writeElement` internal calls are explicitly unchecked with a comment explaining why (the outer `MarshalXML` surfaces a broken encoder at its next checked call anyway).
  • internal/api/v1/torznab.go — 6 handler-side `w.Write` / `xml.Encode` / `io.Copy` / `json.Encode` calls use `_ =`. Nothing meaningful to do with a response-side error once `WriteHeader` has fired.
  • internal/core/indexer/tester.go — `io.Copy` drain in defer uses `_ =`.
  • internal/core/health/checker.go — same drain pattern.
  • pkg/sdk/client_test.go — `sqlDB.Exec` cleanup loop uses `_, _ =`.

ineffassign (1 → 0)

  • internal/core/indexer/tester.go — dropped the dead trailing-slash branch above `capsURL`. The next line overwrote the value anyway, so nothing actually changes at runtime.

unused (2 → 0)

  • internal/core/indexer/prowlarr.go — removed the inline `result` type that used to be populated by the per-file loop but has been unreferenced since `fetchAllViaZip` / `fetchIndividual` replaced it.
  • internal/api/v1/download_clients.go — removed `toDLClientBody`, a no-op stub with a comment explaining it's handled inline.

data race (1 → 0)

  • internal/events/bus_test.go — `TestBusPublishSetsTimestamp` had a shared `var received Event` that the handler goroutine wrote to and the main goroutine read without synchronization (`bus_test.go:43` vs `bus.go:87`). Replaced with a buffered channel + `select`, which is race-free and also drops the brittle 50ms sleep in favour of a 1s deadline. The other two tests in the file already use `atomic.Int32` correctly.

Verification

```
go test -race -timeout 120s ./... # all packages pass
golangci-lint run ./... # zero findings
```

Test plan

  • CI lint job green
  • CI test job green under `-race`
  • CI build job produces a valid pulse binary
  • Docker job (runs only on merge to main) publishes a fresh `ghcr.io/beacon-stack/pulse:latest`

Follow-ups (not in scope)

None on pulse. Sibling PRs on pilot/prism/haul will clear each app's own pre-existing test failures.

Brings pulse to a green lint and race-test state. The fixes are all
pre-existing issues that surfaced the first time CI ran against main.

errcheck:
- internal/torznab/types.go — MarshalXML now propagates EncodeToken
  errors via early-return. writeElement's internal EncodeToken calls
  are explicitly unchecked with `_ =` since the outer MarshalXML will
  surface a broken encoder at its next checked call.
- internal/api/v1/torznab.go — 6 handler-side Write/Encode/Copy calls
  now use `_ =` since there's nothing meaningful to do with a
  response-side error after WriteHeader has fired.
- internal/core/indexer/tester.go — io.Copy drain in defer uses `_ =`.
- internal/core/health/checker.go — same drain pattern.
- pkg/sdk/client_test.go — sqlDB.Exec cleanup loop uses `_, _ =`.

ineffassign:
- internal/core/indexer/tester.go — dropped the dead trailing-slash
  branch above capsURL. The next line overwrote the value anyway, so
  nothing actually changes at runtime.

unused:
- internal/core/indexer/prowlarr.go — removed the inline `result` type
  that used to be populated by the per-file loop but has been
  unreferenced since fetchAllViaZip / fetchIndividual replaced it.
- internal/api/v1/download_clients.go — removed toDLClientBody, a
  no-op stub with a comment explaining it's handled inline.

data race:
- internal/events/bus_test.go — TestBusPublishSetsTimestamp used a
  shared `var received Event` that the handler goroutine wrote to and
  the main goroutine read without synchronization (bus_test.go:43 vs
  bus.go:87). Replaced with a buffered channel + select, which is
  race-free and also drops the brittle 50ms sleep.

Verified with `go test -race ./...` and `golangci-lint run ./...` —
both clean.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@davidfic davidfic merged commit 6734207 into main Apr 15, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant