From 2f1c382a6ddb988cf968c0eac1c2c0884826e214 Mon Sep 17 00:00:00 2001
From: Sebastiaan van Stijn <github@gone.nl>
Date: Sat, 3 Sep 2022 23:20:23 +0200
Subject: [PATCH] golangci-lint: update to v1.49.0

Remove the "deadcode", "structcheck", and "varcheck" linters, as they are
deprecated:

    WARN [runner] The linter 'deadcode' is deprecated (since v1.49.0) due to: The owner seems to have abandoned the linter.  Replaced by unused.
    WARN [runner] The linter 'structcheck' is deprecated (since v1.49.0) due to: The owner seems to have abandoned the linter.  Replaced by unused.
    WARN [runner] The linter 'varcheck' is deprecated (since v1.49.0) due to: The owner seems to have abandoned the linter.  Replaced by unused.
    WARN [linters context] structcheck is disabled because of generics. You can track the evolution of the generics support by following the https://github.com/golangci/golangci-lint/issues/2649.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
---
 Dockerfile                                    |  3 ++-
 daemon/graphdriver/vfs/quota_linux.go         |  1 -
 .../journald/internal/sdjournal/sdjournal.go  |  2 +-
 daemon/logger/journald/journald.go            |  2 +-
 hack/validate/golangci-lint.yml               | 21 ++++------------
 libnetwork/network.go                         |  2 +-
 libnetwork/options/options_test.go            | 17 +++++++++----
 libnetwork/sandbox.go                         | 24 +++++++++----------
 pkg/devicemapper/devmapper.go                 |  2 +-
 volume/drivers/extpoint.go                    |  2 +-
 10 files changed, 37 insertions(+), 39 deletions(-)

diff --git a/Dockerfile b/Dockerfile
index 918310796e..ba825c41e4 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -202,7 +202,8 @@ RUN --mount=type=cache,target=/root/.cache/go-build \
         PREFIX=/build /install.sh containerd
 
 FROM base AS golangci_lint
-ARG GOLANGCI_LINT_VERSION=v1.46.2
+# FIXME: when updating golangci-lint, remove the temporary "nolint" in https://github.com/moby/moby/blob/7860686a8df15eea9def9e6189c6f9eca031bb6f/libnetwork/networkdb/cluster.go#L246
+ARG GOLANGCI_LINT_VERSION=v1.49.0
 RUN --mount=type=cache,target=/root/.cache/go-build \
     --mount=type=cache,target=/go/pkg/mod \
         GOBIN=/build/ GO111MODULE=on go install "github.com/golangci/golangci-lint/cmd/golangci-lint@${GOLANGCI_LINT_VERSION}" \
diff --git a/daemon/graphdriver/vfs/quota_linux.go b/daemon/graphdriver/vfs/quota_linux.go
index 372cbbb769..0a5caa754b 100644
--- a/daemon/graphdriver/vfs/quota_linux.go
+++ b/daemon/graphdriver/vfs/quota_linux.go
@@ -5,7 +5,6 @@ import (
 	"github.com/sirupsen/logrus"
 )
 
-//nolint:structcheck
 type driverQuota struct {
 	quotaCtl *quota.Control
 	quotaOpt quota.Quota
diff --git a/daemon/logger/journald/internal/sdjournal/sdjournal.go b/daemon/logger/journald/internal/sdjournal/sdjournal.go
index af2b532670..c1f3c8ee3c 100644
--- a/daemon/logger/journald/internal/sdjournal/sdjournal.go
+++ b/daemon/logger/journald/internal/sdjournal/sdjournal.go
@@ -39,7 +39,7 @@ const (
 // Journal is a handle to an open journald journal.
 type Journal struct {
 	j      *C.sd_journal
-	noCopy noCopy //nolint:structcheck,unused // Exists only to mark values uncopyable for `go vet`.
+	noCopy noCopy //nolint:unused // Exists only to mark values uncopyable for `go vet`.
 }
 
 // Open opens the log journal for reading.
diff --git a/daemon/logger/journald/journald.go b/daemon/logger/journald/journald.go
index a8b96b278a..4d4e2c0019 100644
--- a/daemon/logger/journald/journald.go
+++ b/daemon/logger/journald/journald.go
@@ -63,7 +63,7 @@ type journald struct {
 	// Overrides for unit tests.
 
 	sendToJournal   func(message string, priority journal.Priority, vars map[string]string) error
-	journalReadDir  string //nolint:structcheck,unused // Referenced in read.go, which has more restrictive build constraints.
+	journalReadDir  string //nolint:unused // Referenced in read.go, which has more restrictive build constraints.
 	readSyncTimeout time.Duration
 }
 
diff --git a/hack/validate/golangci-lint.yml b/hack/validate/golangci-lint.yml
index 1b8d385eab..7ca17133ea 100644
--- a/hack/validate/golangci-lint.yml
+++ b/hack/validate/golangci-lint.yml
@@ -1,6 +1,5 @@
 linters:
   enable:
-    - deadcode
     - depguard
     - goimports
     - gosec
@@ -10,11 +9,9 @@ linters:
     - misspell
     - revive
     - staticcheck
-    - structcheck
     - typecheck
     - unconvert
     - unused
-    - varcheck
 
   disable:
     - errcheck
@@ -36,6 +33,11 @@ linters-settings:
       # The io/ioutil package has been deprecated.
       # https://go.dev/doc/go1.16#ioutil
       - io/ioutil
+  revive:
+    rules:
+      # FIXME make sure all packages have a description. Currently, there's many packages without.
+      - name: package-comments
+        disabled: true
 issues:
   # The default exclusion rules are a bit too permissive, so copying the relevant ones below
   exclude-use-default: false
@@ -111,19 +113,6 @@ issues:
     - text: "SA1019: httputil.ErrPersistEOF"
       linters:
         - staticcheck
-    # This code is doing some fun stuff with reflect and it trips up the linter.
-    - text: "field `foo` is unused"
-      path: "libnetwork/options/options_test.go"
-      linters:
-        - structcheck
-        - unused
-    # This field is only used on windows but is defined in a platform agnostic file.
-    # The linter doesn't understand that the field is used.
-    - text: "`resolverOnce` is unused"
-      path: libnetwork/network.go
-      linters:
-        - structcheck
-        - unused
 
   # Maximum issues count per one linter. Set to 0 to disable. Default is 50.
   max-issues-per-linter: 0
diff --git a/libnetwork/network.go b/libnetwork/network.go
index 94ca8d785b..0e4b60cbcd 100644
--- a/libnetwork/network.go
+++ b/libnetwork/network.go
@@ -222,7 +222,7 @@ type network struct {
 	dbExists         bool
 	persist          bool
 	drvOnce          *sync.Once
-	resolverOnce     sync.Once
+	resolverOnce     sync.Once //nolint:nolintlint,unused // only used on windows
 	resolver         []Resolver
 	internal         bool
 	attachable       bool
diff --git a/libnetwork/options/options_test.go b/libnetwork/options/options_test.go
index 4542a83a04..d18fa8bcc0 100644
--- a/libnetwork/options/options_test.go
+++ b/libnetwork/options/options_test.go
@@ -78,18 +78,24 @@ func TestGenerateMissingField(t *testing.T) {
 
 	if _, ok := err.(NoSuchFieldError); !ok {
 		t.Fatalf("expected NoSuchFieldError, got %#v", err)
-	} else if expected := "no field"; !strings.Contains(err.Error(), expected) {
+	}
+
+	const expected = "no field"
+	if !strings.Contains(err.Error(), expected) {
 		t.Fatalf("expected %q in error message, got %s", expected, err.Error())
 	}
 }
 
 func TestFieldCannotBeSet(t *testing.T) {
-	type Model struct{ foo int } //nolint:structcheck
+	type Model struct{ foo int } //nolint:nolintlint,unused // un-exported field is used to test error-handling
 	_, err := GenerateFromModel(Generic{"foo": "bar"}, Model{})
 
 	if _, ok := err.(CannotSetFieldError); !ok {
 		t.Fatalf("expected CannotSetFieldError, got %#v", err)
-	} else if expected := "cannot set field"; !strings.Contains(err.Error(), expected) {
+	}
+
+	const expected = "cannot set field"
+	if !strings.Contains(err.Error(), expected) {
 		t.Fatalf("expected %q in error message, got %s", expected, err.Error())
 	}
 }
@@ -100,7 +106,10 @@ func TestTypeMismatchError(t *testing.T) {
 
 	if _, ok := err.(TypeMismatchError); !ok {
 		t.Fatalf("expected TypeMismatchError, got %#v", err)
-	} else if expected := "type mismatch"; !strings.Contains(err.Error(), expected) {
+	}
+
+	const expected = "type mismatch"
+	if !strings.Contains(err.Error(), expected) {
 		t.Fatalf("expected %q in error message, got %s", expected, err.Error())
 	}
 }
diff --git a/libnetwork/sandbox.go b/libnetwork/sandbox.go
index 6ae21e27c5..d755c6f504 100644
--- a/libnetwork/sandbox.go
+++ b/libnetwork/sandbox.go
@@ -93,12 +93,12 @@ type sandbox struct {
 // These are the container configs used to customize container /etc/hosts file.
 type hostsPathConfig struct {
 	// Note(cpuguy83): The linter is drunk and says none of these fields are used while they are
-	hostName        string         //nolint:structcheck
-	domainName      string         //nolint:structcheck
-	hostsPath       string         //nolint:structcheck
-	originHostsPath string         //nolint:structcheck
-	extraHosts      []extraHost    //nolint:structcheck
-	parentUpdates   []parentUpdate //nolint:structcheck
+	hostName        string
+	domainName      string
+	hostsPath       string
+	originHostsPath string
+	extraHosts      []extraHost
+	parentUpdates   []parentUpdate
 }
 
 type parentUpdate struct {
@@ -115,12 +115,12 @@ type extraHost struct {
 // These are the container configs used to customize container /etc/resolv.conf file.
 type resolvConfPathConfig struct {
 	// Note(cpuguy83): The linter is drunk and says none of these fields are used while they are
-	resolvConfPath       string   //nolint:structcheck
-	originResolvConfPath string   //nolint:structcheck
-	resolvConfHashFile   string   //nolint:structcheck
-	dnsList              []string //nolint:structcheck
-	dnsSearchList        []string //nolint:structcheck
-	dnsOptionsList       []string //nolint:structcheck
+	resolvConfPath       string
+	originResolvConfPath string
+	resolvConfHashFile   string
+	dnsList              []string
+	dnsSearchList        []string
+	dnsOptionsList       []string
 }
 
 type containerConfig struct {
diff --git a/pkg/devicemapper/devmapper.go b/pkg/devicemapper/devmapper.go
index 034d6c2075..38cba829d0 100644
--- a/pkg/devicemapper/devmapper.go
+++ b/pkg/devicemapper/devmapper.go
@@ -16,7 +16,7 @@ import (
 
 // Same as DM_DEVICE_* enum values from libdevmapper.h
 //
-//nolint:deadcode,unused,varcheck
+//nolint:unused
 const (
 	deviceCreate TaskType = iota
 	deviceReload
diff --git a/volume/drivers/extpoint.go b/volume/drivers/extpoint.go
index 7a909130df..46a438612e 100644
--- a/volume/drivers/extpoint.go
+++ b/volume/drivers/extpoint.go
@@ -22,7 +22,7 @@ const extName = "VolumeDriver"
 // This interface is only defined to generate the proxy objects.
 // It's not intended to be public or reused.
 //
-//nolint:deadcode,unused,varcheck
+//nolint:unused
 type volumeDriver interface {
 	// Create a volume with the given name
 	Create(name string, opts map[string]string) (err error)