Skip to content

fix linting and add golangci-lint#108

Draft
thaJeztah wants to merge 15 commits intomoby:mainfrom
thaJeztah:fix_linting
Draft

fix linting and add golangci-lint#108
thaJeztah wants to merge 15 commits intomoby:mainfrom
thaJeztah:fix_linting

Conversation

@thaJeztah
Copy link
Copy Markdown
Member

No description provided.

@thaJeztah thaJeztah marked this pull request as ready for review March 16, 2026 13:05
@thaJeztah thaJeztah requested a review from Copilot March 16, 2026 13:09
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces golangci-lint to the repository (config + CI job) and updates Go code/tests to satisfy the newly-enabled linters (error handling, type-assert linting, header canonicalization, comment/style tweaks).

Changes:

  • Add .golangci.yml and a new GitHub Actions lint job running golangci-lint.
  • Refactor various functions to avoid naked returns, improve error comparisons (errors.Is/As), and make error strings/comment text linter-friendly.
  • Update tests/benchmarks to properly ignore checked errors, use canonical HTTP header keys, and add helper markers (t.Helper/b.Helper).

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
utils.go Simplifies DEBUG var declaration (now a single var).
stream.go Removes var block, removes naked returns, tweaks docs and error creation.
spdy_test.go Canonicalizes header keys, switches to errors.Is, and explicitly ignores returned errors.
spdy_bench_test.go Adds b.Helper(), reorders helper args, and explicitly ignores returned errors.
spdy/write.go Removes named returns/naked returns and adds explicit error returns; refactors header block writer signature.
spdy/types.go Fixes/aligns doc comments and removes redundant []byte(...) conversions for header dictionary.
spdy/spdy_test.go Uses errors.Is/As, ignores unused return values, and adds t.Helper().
spdy/read.go Uses errors.Is for EOF checks and removes redundant []byte(...) conversions.
priority_test.go Adds forcetypeassert suppression and avoids repeated type assertions.
priority.go Adds forcetypeassert suppression and minor increment simplification.
handlers.go Explicitly ignores io.Copy/Close errors; fixes handler comment casing.
connection.go Normalizes error strings, improves EOF checking, explicitly ignores some return values, and updates docs.
.golangci.yml Adds golangci-lint configuration (enabled linters, exclusions, formatter).
.github/workflows/ci.yaml Adds a new lint job that runs golangci-lint in CI.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread utils.go
Comment thread stream.go
Comment thread spdy/write.go
Comment thread spdy/read.go Outdated
Comment thread spdy/read.go Outdated
Comment thread spdy/read.go Outdated
Comment thread .github/workflows/ci.yaml

This comment was marked as outdated.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds golangci-lint to CI and updates the Go codebase to satisfy stricter linting rules (error handling, doc comments, formatting, and test robustness).

Changes:

  • Add .golangci.yml and a new CI lint job running golangci-lint.
  • Refactor multiple code paths to avoid naked returns, use errors.Is/As, and address errcheck/forcetypeassert findings.
  • Improve/standardize GoDoc and comments for exported identifiers and public-facing behavior.

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
utils.go Simplifies DEBUG var declaration (lint-related cleanup).
stream.go Adds GoDoc for ErrUnreadPartialData and removes naked returns.
spdy_test.go Updates tests for canonical headers and stronger error comparisons; addresses unchecked errors.
spdy_bench_test.go Cleans up benchmarks (helper usage, unchecked errors, signature changes).
spdy/write.go Refactors many writers to return explicit errors (avoid naked returns, appease linters).
spdy/types.go Fixes comments/identifiers and removes unnecessary []byte() conversions.
spdy/spdy_test.go Improves test error matching (errors.Is/As) and marks helpers.
spdy/read.go Uses errors.Is for EOF comparisons and removes redundant conversions.
priority_test.go Tightens type assertions (with linter suppression where appropriate).
priority.go Addresses forcetypeassert and simplifies increment logic.
handlers.go Checks/ignores return values explicitly and fixes NoOp naming in comment.
connection.go Refines error strings/comments; replaces some error comparisons with errors.Is; avoids naked returns.
.golangci.yml Introduces golangci-lint configuration and enabled linters/formatters.
.github/workflows/ci.yaml Adds a new lint job running golangci-lint in CI.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread spdy/write.go
Comment thread spdy/write.go Outdated
Comment thread utils.go
Comment thread connection.go
Comment thread spdy/write.go Outdated
@thaJeztah thaJeztah marked this pull request as draft April 13, 2026 17:37
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Some of these should probably be looked at, but removing error returns
from the signature results in code-churn that may have to be changed
if these should produce errors.

    connection.go:517:66: (*Connection).handleReplyFrame - result 0 (error) is always nil (unparam)
    func (s *Connection) handleReplyFrame(frame *spdy.SynReplyFrame) error {
                                                                     ^
    connection.go:541:67: (*Connection).handleResetFrame - result 0 (error) is always nil (unparam)
    func (s *Connection) handleResetFrame(frame *spdy.RstStreamFrame) error {
                                                                      ^
    connection.go:563:66: (*Connection).handleHeaderFrame - result 0 (error) is always nil (unparam)
    func (s *Connection) handleHeaderFrame(frame *spdy.HeadersFrame) error {
                                                                     ^
    connection.go:634:65: (*Connection).handleGoAwayFrame - result 0 (error) is always nil (unparam)
    func (s *Connection) handleGoAwayFrame(frame *spdy.GoAwayFrame) error {
                                                                    ^
    spdy/write.go:155:57: writeHeaderValueBlock - result n is never used (unparam)
    func writeHeaderValueBlock(w io.Writer, h http.Header) (n int, err error) {
                                                            ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces golangci-lint to CI and applies a set of code/test adjustments across the repository to satisfy new linting and formatting rules (e.g., errcheck, errorlint, forcetypeassert, nakedret, header canonicalization).

Changes:

  • Add golangci-lint configuration and a dedicated CI “lint” job.
  • Refactor production Go code to remove naked returns, improve error handling patterns, and satisfy type-assertion lint rules.
  • Update tests/benchmarks to check/ignore errors consistently, use errors.Is/As, and follow canonical header key conventions.

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
utils.go Simplifies DEBUG declaration to satisfy style/lint expectations.
stream.go Improves docs and replaces naked returns with explicit returns / errors.New.
spdy_test.go Updates tests for errors.Is, header canonicalization, errcheck compliance, and safer hijacking.
spdy_bench_test.go Bench helper signature cleanup, adds b.Helper(), and errcheck compliance.
spdy/write.go Refactors multiple write methods to avoid naked returns; adjusts header block writer signature/returns.
spdy/types.go Fixes comments/typos, aligns terminology, and removes redundant []byte() conversions.
spdy/spdy_test.go Updates assertions to errors.As/Is and marks helper functions appropriately.
spdy/read.go Uses errors.Is for EOF comparisons and removes redundant dictionary conversions.
priority_test.go Adjusts type assertions to satisfy forcetypeassert.
priority.go Adds checked type assertions to satisfy forcetypeassert; minor increment simplification.
handlers.go Errcheck compliance for io.Copy, Close, and SendReply; fixes GoDoc name.
connection.go Error string normalization, errcheck cleanups, errors.Is/As usage, and minor style fixes.
.golangci.yml Adds golangci-lint v2 config enabling specific linters/formatters and exclusions.
.github/workflows/ci.yaml Adds a CI lint job running golangci-lint alongside tests.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread priority.go
Comment on lines +108 to 113
var frame spdy.Frame
if f, ok := heap.Pop(q.queue).(*prioritizedFrame); ok {
frame = f.frame
}
q.c.Signal()
return frame
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PriorityFrameQueue.Pop() silently returns a nil frame if the heap.Pop() result isn't a *prioritizedFrame. Returning nil here is risky because callers treat nil as the drain/stop signal (see frameHandler), so an unexpected type would make workers exit early and drop frames. Consider failing fast (e.g., panic like frameQueue.Push does) or otherwise handling the impossible case explicitly rather than returning nil.

Suggested change
var frame spdy.Frame
if f, ok := heap.Pop(q.queue).(*prioritizedFrame); ok {
frame = f.frame
}
q.c.Signal()
return frame
f, ok := heap.Pop(q.queue).(*prioritizedFrame)
if !ok || f == nil {
panic("PriorityFrameQueue.Pop: unexpected value")
}
q.c.Signal()
return f.frame

Copilot uses AI. Check for mistakes.
Comment thread priority_test.go
Comment on lines +65 to +70
var sid spdy.StreamId
if frame, ok := queue.Pop().(*spdy.DataFrame); ok {
sid = frame.StreamId
}
if sid != i {
t.Fatalf("Wrong frame\nActual: %d\nExpecting: %d", sid, i)
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this test, the type assertion result is ignored when queue.Pop() doesn't return *spdy.DataFrame (it just leaves sid at 0). If the queue returns an unexpected type, this will produce a misleading ordering failure (or could even pass for i==0) rather than clearly indicating the wrong type. Consider failing the test immediately when the assertion fails (or use t.Helper() + a small helper) so the failure message points to the real issue.

Copilot uses AI. Check for mistakes.
Comment thread priority_test.go
Comment on lines +91 to +96
var sid spdy.StreamId
if frame, ok := queue.Pop().(*spdy.DataFrame); ok {
sid = frame.StreamId
}
if sid != i {
t.Fatalf("Wrong frame\nActual: %d\nExpecting: %d", sid, i)
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same issue as above: if queue.Pop() doesn't return *spdy.DataFrame, the test silently proceeds with sid == 0, which can hide the actual problem and give a confusing failure. Prefer failing immediately when the type assertion fails so the test reports an unexpected type rather than an ordering mismatch.

Copilot uses AI. Check for mistakes.
Comment thread spdy/write.go Outdated
}
if !f.headerCompressionDisabled {
f.headerCompressor.Flush()
_ = f.headerCompressor.Flush()
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

zlib.Writer.Flush() can return an error. Assigning it to _ satisfies errcheck but discards potentially important write/compression failures, which could lead to corrupted frames being sent without reporting an error. Consider returning the flush error (or wrapping it) so WriteFrame callers can handle it.

Suggested change
_ = f.headerCompressor.Flush()
if err := f.headerCompressor.Flush(); err != nil {
return err
}

Copilot uses AI. Check for mistakes.
Comment thread spdy/write.go Outdated
Comment thread spdy/write.go Outdated
Comment thread spdy_test.go
Comment on lines +847 to +854
hj, ok := w.(http.Hijacker)
if !ok {
t.Fatal("ResponseWriter should be a http.Hijacker")
}
netconn, _, err := hj.Hijack()
if err != nil {
t.Fatal(err)
}
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This HTTP handler runs in its own goroutine, so calling t.Fatal here can cause the handler goroutine to exit without unblocking the main test (e.g., stream := <-streamCh), potentially hanging the test. Prefer reporting the error back to the main goroutine via a channel (and failing the test there), or use t.Error plus closing/signaling channels so the test can terminate cleanly.

Copilot uses AI. Check for mistakes.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
    connection.go:282:3: assignOp: replace `s.pingId = s.pingId - 0x7ffffffe` with `s.pingId -= 0x7ffffffe` (gocritic)
            s.pingId = s.pingId - 0x7ffffffe
            ^
    connection.go:284:3: assignOp: replace `s.pingId = s.pingId + 2` with `s.pingId += 2` (gocritic)
            s.pingId = s.pingId + 2
            ^
    connection.go:934:2: assignOp: replace `s.nextStreamId = s.nextStreamId + 2` with `s.nextStreamId += 2` (gocritic)
        s.nextStreamId = s.nextStreamId + 2
        ^
    priority.go:90:2: assignOp: replace `q.nextInsertId = q.nextInsertId + 1` with `q.nextInsertId++` (gocritic)
        q.nextInsertId = q.nextInsertId + 1
        ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
    priority.go:50:2: right hand must be only type assertion (forcetypeassert)
        *fq = append(*fq, x.(*prioritizedFrame))
        ^
    priority.go:104:2: type assertion must be checked (forcetypeassert)
        frame := heap.Pop(q.queue).(*prioritizedFrame).frame
        ^
    priority_test.go:66:6: type assertion must be checked (forcetypeassert)
            if frame.(*spdy.DataFrame).StreamId != i {
               ^
    priority_test.go:67:55: type assertion must be checked (forcetypeassert)
                t.Fatalf("Wrong frame\nActual: %d\nExpecting: %d", frame.(*spdy.DataFrame).StreamId, i)
                                                                   ^
    priority_test.go:89:6: type assertion must be checked (forcetypeassert)
            if frame.(*spdy.DataFrame).StreamId != i {
               ^
    priority_test.go:90:55: type assertion must be checked (forcetypeassert)
                t.Fatalf("Wrong frame\nActual: %d\nExpecting: %d", frame.(*spdy.DataFrame).StreamId, i)
                                                                   ^
    spdy_test.go:847:3: right hand must be only type assertion (forcetypeassert)
            netconn, _, _ := w.(http.Hijacker).Hijack()
            ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
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.

3 participants