Skip to content

Commit 4b21532

Browse files
authored
chore(relint): relint code base (#461)
* strengthen golangci rules: closer to full alignment with other go-openapi repos * relint all * readability: refactor complex methods & functions Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
1 parent 0c4edba commit 4b21532

40 files changed

Lines changed: 786 additions & 483 deletions

‎.golangci.yml‎

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ version: "2"
22
linters:
33
default: all
44
disable:
5-
- cyclop
5+
#- cyclop
66
- depguard
77
- err113 # disabled temporarily: there are just too many issues to address
8-
- errchkjson
9-
- errorlint
8+
#- errchkjson
9+
#- errorlint
1010
- exhaustruct
11-
- forcetypeassert
11+
#- forcetypeassert
1212
- funlen
1313
- gochecknoglobals
1414
- gochecknoinits
@@ -18,10 +18,10 @@ linters:
1818
- gomoddirectives # moved to mono-repo, multi-modules, so replace directives are needed
1919
- gosmopolitan
2020
- inamedparam
21-
- ireturn
22-
- lll
21+
- ireturn # this repo adopted a pattern where there are quite many returned interfaces. To be challenged with v2
22+
#- lll
2323
- musttag
24-
- nestif
24+
#- nestif
2525
- nilerr # nilerr crashes on this repo
2626
- nlreturn
2727
- noinlineerr
@@ -31,7 +31,7 @@ linters:
3131
- testpackage
3232
- thelper
3333
- tparallel
34-
- unparam
34+
#- unparam
3535
- varnamelen
3636
- whitespace
3737
- wrapcheck
@@ -43,8 +43,17 @@ linters:
4343
goconst:
4444
min-len: 2
4545
min-occurrences: 3
46+
cyclop:
47+
max-complexity: 25
4648
gocyclo:
47-
min-complexity: 45
49+
min-complexity: 25
50+
gocognit:
51+
min-complexity: 35
52+
exhaustive:
53+
default-signifies-exhaustive: true
54+
default-case-required: true
55+
lll:
56+
line-length: 180
4857
exclusions:
4958
generated: lax
5059
presets:
@@ -61,13 +70,17 @@ formatters:
6170
enable:
6271
- gofmt
6372
- goimports
73+
settings:
74+
# local prefixes regroup imports from these packages
75+
goimports:
76+
local-prefixes:
77+
- github.com/go-openapi
6478
exclusions:
6579
generated: lax
6680
paths:
6781
- .worktrees
6882
- third_party$
6983
- builtin$
70-
- examples$
7184
issues:
7285
# Maximum issues count per one linter.
7386
# Set to 0 to disable.

‎client-middleware/opentracing/opentracing.go‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@ import (
77
"fmt"
88
"net/http"
99

10-
"github.com/go-openapi/strfmt"
1110
"github.com/opentracing/opentracing-go"
1211
"github.com/opentracing/opentracing-go/ext"
1312
"github.com/opentracing/opentracing-go/log"
1413

14+
"github.com/go-openapi/strfmt"
15+
1516
"github.com/go-openapi/runtime"
1617
)
1718

‎client/content_negotiation_test.go‎

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -238,9 +238,9 @@ func writerSetBody(payload any) runtime.ClientRequestWriter {
238238
})
239239
}
240240

241-
func writerSetHeader(name, value string) runtime.ClientRequestWriter {
241+
func writerSetContentType(value string) runtime.ClientRequestWriter {
242242
return runtime.ClientRequestWriterFunc(func(r runtime.ClientRequest, _ strfmt.Registry) error {
243-
return r.SetHeaderParam(name, value)
243+
return r.SetHeaderParam("Content-Type", value)
244244
})
245245
}
246246

@@ -250,9 +250,9 @@ func writerSetForm(name string, values ...string) runtime.ClientRequestWriter {
250250
})
251251
}
252252

253-
func writerSetFile(name string, files ...runtime.NamedReadCloser) runtime.ClientRequestWriter {
253+
func writerSetFileToUpload(files ...runtime.NamedReadCloser) runtime.ClientRequestWriter {
254254
return runtime.ClientRequestWriterFunc(func(r runtime.ClientRequest, _ strfmt.Registry) error {
255-
return r.SetFileParam(name, files...)
255+
return r.SetFileParam("upload", files...)
256256
})
257257
}
258258

@@ -303,8 +303,8 @@ type staticFileWithCT struct{ *staticFile }
303303

304304
func (f *staticFileWithCT) ContentType() string { return f.ct }
305305

306-
func newFile(name, data string) runtime.NamedReadCloser {
307-
return &staticFile{name: name, r: strings.NewReader(data)}
306+
func newFile(data string) runtime.NamedReadCloser {
307+
return &staticFile{name: "doc.txt", r: strings.NewReader(data)}
308308
}
309309

310310
func newFileWithCT(name, data, ct string) runtime.NamedReadCloser {
@@ -374,7 +374,7 @@ func payloadStructCases() iter.Seq[buildHTTPCase] {
374374
name: "struct + SetHeader Content-Type is ignored — picker wins",
375375
mediaType: runtime.JSONMime,
376376
writer: writerCompose(
377-
writerSetHeader("Content-Type", "application/x-ignored"),
377+
writerSetContentType("application/x-ignored"),
378378
writerSetBody(task{Content: "y"}),
379379
),
380380
wantContentType: runtime.JSONMime,
@@ -509,7 +509,7 @@ func payloadReaderCases() iter.Seq[buildHTTPCase] {
509509
name: "io.Reader + SetHeader Content-Type wins over picker",
510510
mediaType: runtime.JSONMime,
511511
writer: writerCompose(
512-
writerSetHeader("Content-Type", vendorMime),
512+
writerSetContentType(vendorMime),
513513
writerSetBody(bytes.NewReader([]byte("v"))),
514514
),
515515
wantContentType: vendorMime,
@@ -520,7 +520,7 @@ func payloadReaderCases() iter.Seq[buildHTTPCase] {
520520
name: "io.Reader + SetHeader wins over payload ContentType()",
521521
mediaType: runtime.JSONMime,
522522
writer: writerCompose(
523-
writerSetHeader("Content-Type", "application/x-explicit"),
523+
writerSetContentType("application/x-explicit"),
524524
writerSetBody(&readerWithCT{
525525
Reader: strings.NewReader("body"),
526526
ct: ndjsonMime,
@@ -535,7 +535,7 @@ func payloadReaderCases() iter.Seq[buildHTTPCase] {
535535
mediaType: runtime.JSONMime,
536536
consumes: []string{runtime.JSONMime, runtime.DefaultMime},
537537
writer: writerCompose(
538-
writerSetHeader("Content-Type", "application/x-explicit"),
538+
writerSetContentType("application/x-explicit"),
539539
writerSetBody(bytes.NewReader([]byte("v"))),
540540
),
541541
wantContentType: "application/x-explicit",
@@ -546,7 +546,7 @@ func payloadReaderCases() iter.Seq[buildHTTPCase] {
546546
name: "io.ReadCloser + SetHeader Content-Type wins",
547547
mediaType: runtime.TextMime,
548548
writer: writerCompose(
549-
writerSetHeader("Content-Type", vendorMime),
549+
writerSetContentType(vendorMime),
550550
writerSetBody(io.NopCloser(strings.NewReader("data"))),
551551
),
552552
wantContentType: vendorMime,
@@ -615,7 +615,7 @@ func fileFieldCases() iter.Seq[buildHTTPCase] {
615615
{
616616
name: "file field + multipart mime",
617617
mediaType: runtime.MultipartFormMime,
618-
writer: writerSetFile("upload", newFile("doc.txt", "filebody")),
618+
writer: writerSetFileToUpload(newFile("filebody")),
619619
wantContentTypePrefix: runtime.MultipartFormMime + "; boundary=",
620620
wantBody: bodyContainsAll(`name="upload"`, `filename="doc.txt"`, "filebody"),
621621
},
@@ -624,14 +624,14 @@ func fileFieldCases() iter.Seq[buildHTTPCase] {
624624
// the file content travels as a regular form value.
625625
name: "file field + urlencoded mime — file inlined as form value",
626626
mediaType: runtime.URLencodedFormMime,
627-
writer: writerSetFile("upload", newFile("doc.txt", "abc")),
627+
writer: writerSetFileToUpload(newFile("abc")),
628628
wantContentType: runtime.URLencodedFormMime,
629629
wantBody: bodyContainsAll("upload=abc"),
630630
},
631631
{
632632
name: "file with declared ContentType()",
633633
mediaType: runtime.MultipartFormMime,
634-
writer: writerSetFile("upload", newFileWithCT("doc.txt", "x", "application/json")),
634+
writer: writerSetFileToUpload(newFileWithCT("doc.txt", "x", "application/json")),
635635
wantContentTypePrefix: runtime.MultipartFormMime + "; boundary=",
636636
wantBody: bodyContainsAll("application/json"),
637637
},
@@ -646,7 +646,7 @@ func formAndFileFieldCases() iter.Seq[buildHTTPCase] {
646646
mediaType: runtime.MultipartFormMime,
647647
writer: writerCompose(
648648
writerSetForm("name", "fido"),
649-
writerSetFile("upload", newFile("doc.txt", "filebody")),
649+
writerSetFileToUpload(newFile("filebody")),
650650
),
651651
wantContentTypePrefix: runtime.MultipartFormMime + "; boundary=",
652652
wantBody: bodyContainsAll(`name="name"`, "fido", `filename="doc.txt"`, "filebody"),
@@ -656,7 +656,7 @@ func formAndFileFieldCases() iter.Seq[buildHTTPCase] {
656656
mediaType: runtime.URLencodedFormMime,
657657
writer: writerCompose(
658658
writerSetForm("name", "fido"),
659-
writerSetFile("upload", newFile("doc.txt", "abc")),
659+
writerSetFileToUpload(newFile("abc")),
660660
),
661661
wantContentType: runtime.URLencodedFormMime,
662662
wantBody: bodyContainsAll("name=fido", "upload=abc"),
@@ -748,7 +748,7 @@ func submitWiringCases() iter.Seq[submitCase] {
748748
name: "consumes [json] + SetHeader Content-Type — escape hatch wins",
749749
consumes: []string{runtime.JSONMime},
750750
writer: writerCompose(
751-
writerSetHeader("Content-Type", vendorMime),
751+
writerSetContentType(vendorMime),
752752
writerSetBody(bytes.NewReader([]byte("data"))),
753753
),
754754
wantContentType: vendorMime,

‎client/httptrace_tls.go‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ func introspectTLSConfig(client *http.Client) *tls.Config {
7171
func (s *traceSession) emitTLSDiagnostic(state tls.ConnectionState, err error) {
7272
s.emitf("# TLS DIAGNOSTIC")
7373

74-
//nolint:exhaustive // tlsAxisGeneric is handled by the default branch.
74+
// tlsAxisGeneric is handled by the default branch.
7575
switch axis := classifyTLSError(err); axis {
7676
case tlsAxisProtocolVersion:
7777
s.diagnoseProtocolVersion(state, err)
@@ -215,7 +215,6 @@ func (s *traceSession) diagnoseCertInvalid(certInvalid x509.CertificateInvalidEr
215215
cert := certInvalid.Cert
216216
s.emitf("# reason: %s", certInvalidReasonName(certInvalid.Reason))
217217

218-
//nolint:exhaustive // Less-common reasons render via the default branch (issuer + NotAfter dump).
219218
switch certInvalid.Reason {
220219
case x509.Expired:
221220
s.emitf("# leaf: subject=%s", cert.Subject)
@@ -231,6 +230,7 @@ func (s *traceSession) diagnoseCertInvalid(certInvalid x509.CertificateInvalidEr
231230
s.emitf("# suggested: set TLSClientOptions.ServerName to match")
232231
s.emitf("# one of the cert SANs, or fix the cert.")
233232
default:
233+
// Less-common reasons render via the default branch (issuer + NotAfter dump).
234234
s.emitf("# leaf: subject=%s, issuer=%s", cert.Subject, cert.Issuer)
235235
s.emitf("# NotBefore=%s", cert.NotBefore.UTC().Format(time.RFC3339))
236236
s.emitf("# NotAfter=%s", cert.NotAfter.UTC().Format(time.RFC3339))
@@ -326,7 +326,7 @@ func cipherSuiteNames(ids []uint16) []string {
326326
// human-readable label. The stdlib does not expose a String()
327327
// method for these, so we keep a small table.
328328
//
329-
//nolint:exhaustive // Anything outside the listed cases falls through to the numeric default.
329+
// Anything outside the listed cases falls through to the numeric default.
330330
func certInvalidReasonName(r x509.InvalidReason) string {
331331
switch r {
332332
case x509.NotAuthorizedToSign:

‎client/internal/request/request.go‎

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package request
66
import (
77
"bytes"
88
"context"
9+
"errors"
910
"fmt"
1011
"io"
1112
"log"
@@ -82,7 +83,7 @@ var _ runtime.ClientRequest = new(Request) // ensure compliance to the interface
8283
// [Request.SetHeaderParam] during WriteToRequest, and we treat that as an intentional escape hatch
8384
// 2. use payload's [runtime.ContentTyper] declaration (in this case, the produced payload knows its content type)
8485
// 3. use `application/octet-stream` if it is available in the registered producers
85-
// 4. otherwise ser the picker's mediaType
86+
// 4. otherwise set the picker's mediaType
8687
//
8788
// For multi-part requests, the content type of each part is auto-detected using the following sequence:
8889
//
@@ -316,7 +317,9 @@ func (r *Request) SetConsumes(consumers []string) {
316317
//
317318
// On error the cancel is invoked internally and a no-op cancel is returned,
318319
// so callers can defer cancel unconditionally.
319-
func (r *Request) BuildHTTPContext(parentCtx context.Context, mediaType, basePath string, producers map[string]runtime.Producer, registry strfmt.Registry, auth runtime.ClientAuthInfoWriter) (*http.Request, context.CancelFunc, error) {
320+
func (r *Request) BuildHTTPContext(parentCtx context.Context, mediaType, basePath string,
321+
producers map[string]runtime.Producer, registry strfmt.Registry, auth runtime.ClientAuthInfoWriter,
322+
) (*http.Request, context.CancelFunc, error) {
320323
if err := r.writer.WriteToRequest(r, registry); err != nil {
321324
return nil, noop, err
322325
}
@@ -362,11 +365,13 @@ func (r *Request) usesStreamingBody(mediaType string) bool {
362365
if (len(r.formFields) > 0 || len(r.fileFields) > 0) && r.isMultipart(mediaType) {
363366
return true
364367
}
368+
365369
if r.payload != nil {
366370
if _, ok := r.payload.(io.Reader); ok {
367371
return true
368372
}
369373
}
374+
370375
return false
371376
}
372377

@@ -409,7 +414,9 @@ func (r *Request) isMultipart(mediaType string) bool {
409414
//
410415
// Auth is trivial in this flow because the buffer is already populated when the auth helper
411416
// asks for the body via r.GetBody().
412-
func (r *Request) buildBufferedRequest(ctx context.Context, mediaType, basePath string, producers map[string]runtime.Producer, registry strfmt.Registry, auth runtime.ClientAuthInfoWriter) (*http.Request, error) {
417+
func (r *Request) buildBufferedRequest(ctx context.Context, mediaType, basePath string,
418+
producers map[string]runtime.Producer, registry strfmt.Registry, auth runtime.ClientAuthInfoWriter,
419+
) (*http.Request, error) {
413420
var body io.Reader
414421
var err error
415422

@@ -450,7 +457,9 @@ func (r *Request) buildBufferedRequest(ctx context.Context, mediaType, basePath
450457
// (it would otherwise park forever on pw.Write with no reader).
451458
//
452459
// For stream payloads it closes the user-provided io.ReadCloser.
453-
func (r *Request) buildStreamingRequest(ctx context.Context, mediaType, basePath string, producers map[string]runtime.Producer, registry strfmt.Registry, auth runtime.ClientAuthInfoWriter) (req *http.Request, retErr error) {
460+
func (r *Request) buildStreamingRequest(ctx context.Context, mediaType, basePath string,
461+
producers map[string]runtime.Producer, registry strfmt.Registry, auth runtime.ClientAuthInfoWriter,
462+
) (req *http.Request, retErr error) {
454463
var body io.Reader
455464
if len(r.formFields) > 0 || len(r.fileFields) > 0 {
456465
body = r.writeMultipartBody(ctx, mediaType)
@@ -603,7 +612,7 @@ func (r *Request) applyAuthWithBodyCopy(auth runtime.ClientAuthInfoWriter, body
603612
// underlying pipe/stream. Caller treats body as ignorable when
604613
// err != nil per Go convention; the defer reads it via closure.
605614
if copyErr != nil {
606-
return body, fmt.Errorf("error retrieving the response body: %v", copyErr)
615+
return body, fmt.Errorf("error copying the request body: %w", copyErr)
607616
}
608617

609618
if authErr != nil {
@@ -731,7 +740,7 @@ func (r *Request) streamMultipartParts(ctx context.Context, mp *multipart.Writer
731740
const contentTypeBufferSize = 512
732741
buf := make([]byte, contentTypeBufferSize)
733742
size, err := fi.Read(buf)
734-
if err != nil && err != io.EOF {
743+
if err != nil && !errors.Is(err, io.EOF) {
735744
logClose(err, pw)
736745
return
737746
}
@@ -789,7 +798,13 @@ func (r *Request) writeStreamPayload(mediaType string, producers map[string]runt
789798
if rdr, ok := r.payload.(io.ReadCloser); ok {
790799
return rdr
791800
}
792-
return r.payload.(io.Reader)
801+
802+
rdr, ok := r.payload.(io.Reader)
803+
if !ok {
804+
panic("internal error: payload expected to be an io.Reader") // guaranteed by earlier checks
805+
}
806+
807+
return rdr
793808
}
794809

795810
// writeNonStreamPayload runs the producer registered for mediaType
@@ -903,7 +918,8 @@ func logClose(err error, pw *io.PipeWriter) {
903918
}
904919
}
905920

906-
func mangleContentType(_, boundary string) string {
921+
func mangleContentType(mediaType, boundary string) string {
922+
_ = mediaType // reserved for future enhancement: honor caller-provided media type
907923
// Proposal for enhancement: honor caller's boundary if specified
908924
return "multipart/form-data; boundary=" + boundary
909925
}

‎client/internal/request/request_test.go‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ func TestBuildRequest_BuildHTTP_XMLPayload(t *testing.T) {
304304
}
305305

306306
func TestBuildRequest_BuildHTTP_TextPayload(t *testing.T) {
307-
const bd = "Tom: Organ trail; John: Bird watching"
307+
const bd = "Tom: Oregon trail; John: Bird watching"
308308

309309
reqWrtr := runtime.ClientRequestWriterFunc(func(req runtime.ClientRequest, _ strfmt.Registry) error {
310310
_ = req.SetBodyParam(bd)

‎client/opentelemetry.go‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,15 @@ import (
88
"net/http"
99
"strings"
1010

11-
"github.com/go-openapi/runtime"
12-
"github.com/go-openapi/strfmt"
1311
"go.opentelemetry.io/otel"
1412
"go.opentelemetry.io/otel/attribute"
1513
"go.opentelemetry.io/otel/codes"
1614
"go.opentelemetry.io/otel/propagation"
1715
semconv "go.opentelemetry.io/otel/semconv/v1.37.0"
1816
"go.opentelemetry.io/otel/trace"
17+
18+
"github.com/go-openapi/runtime"
19+
"github.com/go-openapi/strfmt"
1920
)
2021

2122
const (

0 commit comments

Comments
 (0)