Repository: gomods/athens
Pull request #1828 (2023-02-22 13:30:40)

chore: lint code with golangci-lint
<!-- 
    Welcome, Athenian! Can you do us two quick favors before you submit your PR?
    
    1. Briefly fill out the sections below. It will make it easy for us to review your code
    2. Put "[WIP]" at the beginning of your PR title if you're not ready to have this merged yet (we have a bot that will tell everyone that it's a work in progress)
-->

## What is the problem I am trying to address?

To make the codebase more uniform, and to catch additional security issues, a static analyser should be used.

## How is the fix applied?

golangci-lint was configured, added to the workflow and any existing issues where fixed.

As it is no longer considered "safe" to cast errors directly, and as the `pkg/errors` package is used basically everywhere, the functions `errors.IsErr` and `errors.AsErr` where added that wrap the std lib functions. The `Err` postfix was added as `errors.Is` already exists. If prefered, `errors.Is` can be renamed, and the wrapper function can better mimic the std lib.

**Note:** It would be best to only merge this once the CI tests are fixed.

## What GitHub issue(s) does this PR fix or close?

<!--
    If it doesn't fix any GitHub Issues, that's ok. Can you please delete the below "Fixes #" line for us? It would help us out a lot. Thanks!

    Your PR might fix one or more GitHub issues. If so, please use the below "Fixes #<issue number>" notation below. If your PR fixes multiple issues, please put multiple lines of "Fixes #<issue number>", one for each issue. If you do that, when this PR is merged, it'll automatically close the issue(s) you reference.
-->

<!-- 
example: Fixes #123
-->


manugupt1: https://github.com/gomods/athens/pull/1823/files has a lint step in build; which one do we prefer?
manugupt1: Now lint is slower I made a mistake; sorry! but let's merge this PR.
Thanks a lot!

Patch:
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 3593c3b0..766492f0 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -3,6 +3,18 @@ on:
   - push
   - pull_request
 jobs:
+  lint:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3
+      - name: Set up Go
+        uses: actions/setup-go@v3
+        with:
+          go-version-file: 'go.mod'
+          cache: true
+      - name: Lint code
+        run: make lint-docker
+
   build:
     env:
       ATHENS_MONGO_STORAGE_URL: mongodb://localhost:27017
@@ -53,7 +65,7 @@ jobs:
         with:
           go-version-file: 'go.mod'
           cache: true
-      - name: Run linter
+      - name: Verify changes
         run: make verify
       - name: Unit tests
         run: go test -v -race ./...
diff --git a/.golangci.yml b/.golangci.yml
new file mode 100644
index 00000000..d757d9db
--- /dev/null
+++ b/.golangci.yml
@@ -0,0 +1,80 @@
+run:
+  tests: false
+  timeout: 5m
+
+linters-settings:
+  cyclop:
+    max-complexity: 12
+    skip-tests: true
+  gofumpt:
+    extra-rules: true
+
+linters:
+  enable-all: true
+  disable:
+    - interfacer # deprecated
+    - scopelint # deprecated
+    - maligned # deprecated
+    - golint # deprecated
+    - structcheck # deprecated
+    - deadcode # deprecated
+    - varcheck # deprecated
+    - nosnakecase # deprecated
+    - ifshort # deprecated
+    - errchkjson
+    - exhaustive
+    - exhaustivestruct
+    - exhaustruct
+    - forcetypeassert
+    - funlen
+    - gochecknoglobals
+    - gochecknoinits
+    - goconst
+    - godox
+    - goerr113
+    - gomnd
+    - ireturn
+    - lll
+    - musttag
+    - nilnil
+    - nlreturn
+    - nonamedreturns
+    - tagliatelle
+    - varnamelen
+    - wrapcheck
+    - wsl
+    - cyclop # TODO: turn this back on later
+    - gocognit # TODO: turn this back on later
+    - forbidigo # TODO: turn this back on later
+
+issues:
+  exclude-use-default: false
+  exclude:
+    - 'package-comments: should have a package comment'
+    - 'ST1000: at least one file in a package should have a package comment'
+    - 'G204: Subprocess launched with a potential tainted input or cmd arguments'
+    - 'G204: Subprocess launched with variable'
+    - 'G402: TLS MinVersion too low.'
+    - 'const `op` is unused'
+  exclude-rules:
+    - path: cmd/proxy/main.go
+      text: 'G108: Profiling endpoint is automatically exposed on /debug/pprof'
+    - path: pkg/stash/stasher.go
+      linters:
+        - contextcheck
+    - path: pkg/stash/with_azureblob.go # False positive
+      linters:
+        - bodyclose
+    - path: pkg/storage/azureblob/azureblob.go # False positive
+      linters:
+        - bodyclose
+    - path: pkg/storage/compliance/*
+      linters:
+        - thelper
+        - gosec
+        - errcheck
+    - path: pkg/index/compliance/*
+      linters:
+        - thelper
+        - gosec
+        - errcheck
diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md
index 88ea1e2e..5585724e 100644
--- a/DEVELOPMENT.md
+++ b/DEVELOPMENT.md
@@ -234,10 +234,10 @@ Then open [http://localhost:1313](http://localhost:1313/).
 
 # Linting
 
-In our CI/CD pass, we use govet, so feel free to run it locally beforehand:
+In our CI/CD pass, we use golangci-lint, so feel free to run it locally beforehand:
 
 ```
-go vet ./...
+make lint
 ```
 
 # For People Doing a Release
diff --git a/Makefile b/Makefile
index 95f726cf..f99c2162 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,8 @@
 VERSION = "unset"
 DATE=$(shell date -u +%Y-%m-%d-%H:%M:%S-%Z)
 
+GOLANGCI_LINT_VERSION=v1.51.2
+
 ifndef GOLANG_VERSION
 override GOLANG_VERSION = 1.19
 endif
@@ -43,10 +45,16 @@ docs: ## build the docs docker image
 setup-dev-env:
 	$(MAKE) dev
 
+.PHONY: lint
+lint:
+	@golangci-lint run ./...
+
+.PHONY: lint-docker
+lint-docker:
+	@docker run -t --rm -v $(CURDIR):/app -w /app golangci/golangci-lint:$(GOLANGCI_LINT_VERSION) golangci-lint run ./...
+
 .PHONY: verify
 verify: ## verify athens codebase
-	./scripts/check_gofmt.sh
-	./scripts/check_govet.sh
 	./scripts/check_deps.sh
 	./scripts/check_conflicts.sh
 
diff --git a/cmd/proxy/actions/app.go b/cmd/proxy/actions/app.go
index 4b3d7c3f..e3702246 100644
--- a/cmd/proxy/actions/app.go
+++ b/cmd/proxy/actions/app.go
@@ -16,7 +16,7 @@ import (
 	"go.opencensus.io/plugin/ochttp"
 )
 
-// Service is the name of the service that we want to tag our processes with
+// Service is the name of the service that we want to tag our processes with.
 const Service = "proxy"
 
 // App is where all routes and middleware for the proxy
@@ -126,7 +126,7 @@ func App(conf *config.Config) (http.Handler, error) {
 
 	store, err := GetStorage(conf.StorageType, conf.Storage, conf.TimeoutDuration(), client)
 	if err != nil {
-		err = fmt.Errorf("error getting storage configuration (%s)", err)
+		err = fmt.Errorf("error getting storage configuration: %w", err)
 		return nil, err
 	}
 
@@ -140,7 +140,7 @@ func App(conf *config.Config) (http.Handler, error) {
 		lggr,
 		conf,
 	); err != nil {
-		err = fmt.Errorf("error adding proxy routes (%s)", err)
+		err = fmt.Errorf("error adding proxy routes: %w", err)
 		return nil, err
 	}
 
diff --git a/cmd/proxy/actions/app_proxy.go b/cmd/proxy/actions/app_proxy.go
index e0f1f6bc..27187f68 100644
--- a/cmd/proxy/actions/app_proxy.go
+++ b/cmd/proxy/actions/app_proxy.go
@@ -2,6 +2,7 @@ package actions
 
 import (
 	"context"
+	"errors"
 	"fmt"
 	"net/http"
 	"net/url"
@@ -54,7 +55,7 @@ func addProxyRoutes(
 		}
 		supportPath := path.Join("/sumdb", sumdbURL.Host, "/supported")
 		r.HandleFunc(supportPath, func(w http.ResponseWriter, r *http.Request) {
-			w.WriteHeader(200)
+			w.WriteHeader(http.StatusOK)
 		})
 		sumHandler := sumdbProxy(sumdbURL, c.NoSumPatterns)
 		pathPrefix := "/sumdb/" + sumdbURL.Host
@@ -63,7 +64,7 @@ func addProxyRoutes(
 		)
 	}
 
-	// Download Protocol
+	// Download Protocol:
 	// the download.Protocol and the stash.Stasher interfaces are composable
 	// in a middleware fashion. Therefore you can separate concerns
 	// by the functionality: a download.Protocol that just takes care
@@ -142,13 +143,13 @@ func getSingleFlight(l *log.Logger, c *config.Config, checker storage.Checker) (
 		return stash.WithSingleflight, nil
 	case "etcd":
 		if c.SingleFlight == nil || c.SingleFlight.Etcd == nil {
-			return nil, fmt.Errorf("Etcd config must be present")
+			return nil, errors.New("etcd config must be present")
 		}
 		endpoints := strings.Split(c.SingleFlight.Etcd.Endpoints, ",")
 		return stash.WithEtcd(endpoints, checker)
 	case "redis":
 		if c.SingleFlight == nil || c.SingleFlight.Redis == nil {
-			return nil, fmt.Errorf("Redis config must be present")
+			return nil, errors.New("redis config must be present")
 		}
 		return stash.WithRedisLock(
 			&athensLoggerForRedis{logger: l},
@@ -158,7 +159,7 @@ func getSingleFlight(l *log.Logger, c *config.Config, checker storage.Checker) (
 			c.SingleFlight.Redis.LockConfig)
 	case "redis-sentinel":
 		if c.SingleFlight == nil || c.SingleFlight.RedisSentinel == nil {
-			return nil, fmt.Errorf("Redis config must be present")
+			return nil, errors.New("redis config must be present")
 		}
 		return stash.WithRedisSentinelLock(
 			&athensLoggerForRedis{logger: l},
diff --git a/cmd/proxy/actions/auth.go b/cmd/proxy/actions/auth.go
index e654da87..c4daedc6 100644
--- a/cmd/proxy/actions/auth.go
+++ b/cmd/proxy/actions/auth.go
@@ -19,7 +19,7 @@ func initializeAuthFile(path string) {
 		return
 	}
 
-	fileBts, err := os.ReadFile(path)
+	fileBts, err := os.ReadFile(filepath.Clean(path))
 	if err != nil {
 		log.Fatalf("could not read %s: %v", path, err)
 	}
@@ -31,7 +31,7 @@ func initializeAuthFile(path string) {
 
 	fileName := transformAuthFileName(filepath.Base(path))
 	rcp := filepath.Join(hdir, fileName)
-	if err := os.WriteFile(rcp, fileBts, 0600); err != nil {
+	if err := os.WriteFile(rcp, fileBts, 0o600); err != nil {
 		log.Fatalf("could not write to file: %v", err)
 	}
 }
@@ -45,7 +45,7 @@ func netrcFromToken(tok string) {
 		log.Fatalf("netrcFromToken: could not get homedir: %v", err)
 	}
 	rcp := filepath.Join(hdir, getNETRCFilename())
-	if err := os.WriteFile(rcp, []byte(fileContent), 0600); err != nil {
+	if err := os.WriteFile(rcp, []byte(fileContent), 0o600); err != nil {
 		log.Fatalf("netrcFromToken: could not write to file: %v", err)
 	}
 }
diff --git a/cmd/proxy/actions/basicauth.go b/cmd/proxy/actions/basicauth.go
index ea0938e0..a9a754b0 100644
--- a/cmd/proxy/actions/basicauth.go
+++ b/cmd/proxy/actions/basicauth.go
@@ -8,10 +8,8 @@ import (
 	"github.com/gorilla/mux"
 )
 
-var (
-	// basicAuthExcludedPaths is a regular expression that matches paths that should not be protected by HTTP basic authentication.
-	basicAuthExcludedPaths = regexp.MustCompile("^/(health|ready)z$")
-)
+// basicAuthExcludedPaths is a regular expression that matches paths that should not be protected by HTTP basic authentication.
+var basicAuthExcludedPaths = regexp.MustCompile("^/(health|ready)z$")
 
 func basicAuth(user, pass string) mux.MiddlewareFunc {
 	return func(h http.Handler) http.Handler {
@@ -40,9 +38,5 @@ func checkAuth(r *http.Request, user, pass string) bool {
 	}
 
 	isPass := subtle.ConstantTimeCompare([]byte(pass), []byte(givenPass))
-	if isPass != 1 {
-		return false
-	}
-
-	return true
+	return isPass == 1
 }
diff --git a/cmd/proxy/actions/catalog.go b/cmd/proxy/actions/catalog.go
index eb98052b..769208f1 100644
--- a/cmd/proxy/actions/catalog.go
+++ b/cmd/proxy/actions/catalog.go
@@ -18,7 +18,7 @@ type catalogRes struct {
 	NextPageToken   string                `json:"next,omitempty"`
 }
 
-// catalogHandler implements GET baseURL/catalog
+// catalogHandler implements GET baseURL/catalog.
 func catalogHandler(s storage.Backend) http.HandlerFunc {
 	const op errors.Op = "actions.CatalogHandler"
 	cs, isCataloger := s.(storage.Cataloger)
@@ -54,7 +54,7 @@ func catalogHandler(s storage.Backend) http.HandlerFunc {
 }
 
 // getLimitFromParam converts a URL query parameter into an int
-// otherwise converts defaultPageSize constant
+// otherwise converts defaultPageSize constant.
 func getLimitFromParam(param string) (int, error) {
 	if param == "" {
 		return defaultPageSize, nil
diff --git a/cmd/proxy/actions/home.go b/cmd/proxy/actions/home.go
index f0f62f74..94fb545f 100644
--- a/cmd/proxy/actions/home.go
+++ b/cmd/proxy/actions/home.go
@@ -5,5 +5,5 @@ import (
 )
 
 func proxyHomeHandler(w http.ResponseWriter, r *http.Request) {
-	w.Write([]byte(`"Welcome to The Athens Proxy"`))
+	_, _ = w.Write([]byte(`"Welcome to The Athens Proxy"`))
 }
diff --git a/cmd/proxy/actions/index.go b/cmd/proxy/actions/index.go
index 19fce99e..e747a7ab 100644
--- a/cmd/proxy/actions/index.go
+++ b/cmd/proxy/actions/index.go
@@ -13,7 +13,7 @@ import (
 	"github.com/sirupsen/logrus"
 )
 
-// indexHandler implements GET baseURL/index
+// indexHandler implements GET baseURL/index.
 func indexHandler(index index.Indexer) http.HandlerFunc {
 	return func(w http.ResponseWriter, r *http.Request) {
 		ctx := r.Context()
diff --git a/cmd/proxy/actions/robots.go b/cmd/proxy/actions/robots.go
index ce2387da..b7edb135 100644
--- a/cmd/proxy/actions/robots.go
+++ b/cmd/proxy/actions/robots.go
@@ -6,7 +6,7 @@ import (
 	"github.com/gomods/athens/pkg/config"
 )
 
-// robotsHandler implements GET baseURL/robots.txt
+// robotsHandler implements GET baseURL/robots.txt.
 func robotsHandler(c *config.Config) http.HandlerFunc {
 	return func(w http.ResponseWriter, r *http.Request) {
 		http.ServeFile(w, r, c.RobotsFile)
diff --git a/cmd/proxy/actions/storage.go b/cmd/proxy/actions/storage.go
index 04722cc6..3d9faa3e 100644
--- a/cmd/proxy/actions/storage.go
+++ b/cmd/proxy/actions/storage.go
@@ -21,7 +21,7 @@ import (
 	"github.com/spf13/afero"
 )
 
-// GetStorage returns storage backend based on env configuration
+// GetStorage returns storage backend based on env configuration.
 func GetStorage(storageType string, storageConfig *config.Storage, timeout time.Duration, client *http.Client) (storage.Backend, error) {
 	const op errors.Op = "actions.GetStorage"
 	switch storageType {
diff --git a/cmd/proxy/actions/sumdb.go b/cmd/proxy/actions/sumdb.go
index 24018b1c..6a9dbdbd 100644
--- a/cmd/proxy/actions/sumdb.go
+++ b/cmd/proxy/actions/sumdb.go
@@ -17,12 +17,12 @@ func sumdbProxy(url *url.URL, nosumPatterns []string) http.Handler {
 		req.URL.Host = url.Host
 	}
 	if len(nosumPatterns) > 0 {
-		return noSumWrapper(rp, url.Host, nosumPatterns)
+		return noSumWrapper(rp, nosumPatterns)
 	}
 	return rp
 }
 
-func noSumWrapper(h http.Handler, host string, patterns []string) http.Handler {
+func noSumWrapper(h http.Handler, patterns []string) http.Handler {
 	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 		if strings.HasPrefix(r.URL.Path, "/lookup/") {
 			for _, p := range patterns {
diff --git a/cmd/proxy/actions/version.go b/cmd/proxy/actions/version.go
index ba23a468..a0cba012 100644
--- a/cmd/proxy/actions/version.go
+++ b/cmd/proxy/actions/version.go
@@ -8,5 +8,5 @@ import (
 )
 
 func versionHandler(w http.ResponseWriter, r *http.Request) {
-	json.NewEncoder(w).Encode(build.Data())
+	_ = json.NewEncoder(w).Encode(build.Data())
 }
diff --git a/cmd/proxy/main.go b/cmd/proxy/main.go
index dafd68e2..13e981d7 100644
--- a/cmd/proxy/main.go
+++ b/cmd/proxy/main.go
@@ -2,16 +2,16 @@ package main
 
 import (
 	"context"
+	"errors"
 	"flag"
 	"fmt"
 	"log"
 	"net/http"
+	_ "net/http/pprof"
 	"os"
 	"os/signal"
 	"time"
 
-	_ "net/http/pprof"
-
 	"github.com/gomods/athens/cmd/proxy/actions"
 	"github.com/gomods/athens/internal/shutdown"
 	"github.com/gomods/athens/pkg/build"
@@ -45,8 +45,9 @@ func main() {
 	}
 
 	srv := &http.Server{
-		Addr:    conf.Port,
-		Handler: handler,
+		Addr:              conf.Port,
+		Handler:           handler,
+		ReadHeaderTimeout: 2 * time.Second,
 	}
 	idleConnsClosed := make(chan struct{})
 
@@ -54,7 +55,7 @@ func main() {
 		sigint := make(chan os.Signal, 1)
 		signal.Notify(sigint, shutdown.GetSignals()...)
 		s := <-sigint
-		log.Printf("Recived signal (%s): Shutting down server", s)
+		log.Printf("Received signal (%s): Shutting down server", s)
 
 		// We received an interrupt signal, shut down.
 		ctx, cancel := context.WithTimeout(context.Background(), time.Second*time.Duration(conf.ShutdownTimeout))
@@ -70,7 +71,7 @@ func main() {
 			// pprof to be exposed on a different port than the application for security matters, not to expose profiling data and avoid DoS attacks (profiling slows down the service)
 			// https://www.farsightsecurity.com/txt-record/2016/10/28/cmikk-go-remote-profiling/
 			log.Printf("Starting `pprof` at port %v", conf.PprofPort)
-			log.Fatal(http.ListenAndServe(conf.PprofPort, nil))
+			log.Fatal(http.ListenAndServe(conf.PprofPort, nil)) //nolint:gosec // This should not be exposed to the world.
 		}()
 	}
 
@@ -81,7 +82,7 @@ func main() {
 		err = srv.ListenAndServe()
 	}
 
-	if err != http.ErrServerClosed {
+	if !errors.Is(err, http.ErrServerClosed) {
 		log.Fatal(err)
 	}
 
diff --git a/init.ps1 b/init.ps1
index 6ff89a31..36ee0919 100644
--- a/init.ps1
+++ b/init.ps1
@@ -79,8 +79,6 @@ if ($docs.IsPresent) {
 }
 
 if ($verify.IsPresent) {
-	execScript "check_gofmt.ps1"
-	execScript "check_govet.ps1"
 	execScript "check_deps.ps1"
 }
 
diff --git a/pkg/build/build.go b/pkg/build/build.go
index bfb74b25..d88f1987 100644
--- a/pkg/build/build.go
+++ b/pkg/build/build.go
@@ -9,7 +9,7 @@ import (
 	"fmt"
 )
 
-// Details represents known data for a given build
+// Details represents known data for a given build.
 type Details struct {
 	Version string `json:"version,omitempty"`
 	Date    string `json:"date,omitempty"`
@@ -29,7 +29,7 @@ func String() string {
 	return fmt.Sprintf("Build Details:\n\tVersion:\t%s\n\tDate:\t\t%s", version, buildDate)
 }
 
-// Data returns build details as a struct
+// Data returns build details as a struct.
 func Data() Details {
 	return Details{
 		Version: version,
diff --git a/pkg/config/azureblob.go b/pkg/config/azureblob.go
index fb532fc4..bbff569f 100644
--- a/pkg/config/azureblob.go
+++ b/pkg/config/azureblob.go
@@ -1,6 +1,6 @@
 package config
 
-// AzureBlobConfig specifies the properties required to use Azure as the storage backend
+// AzureBlobConfig specifies the properties required to use Azure as the storage backend.
 type AzureBlobConfig struct {
 	AccountName   string `validate:"required" envconfig:"ATHENS_AZURE_ACCOUNT_NAME"`
 	AccountKey    string `validate:"required" envconfig:"ATHENS_AZURE_ACCOUNT_KEY"`
diff --git a/pkg/config/config.go b/pkg/config/config.go
index ca2a1b0e..d480f8a7 100644
--- a/pkg/config/config.go
+++ b/pkg/config/config.go
@@ -18,7 +18,7 @@ import (
 
 const defaultConfigFile = "athens.toml"
 
-// Config provides configuration values for all components
+// Config provides configuration values for all components.
 type Config struct {
 	TimeoutConf
 	GoEnv            string    `validate:"required" envconfig:"GO_ENV"`
@@ -63,12 +63,12 @@ type Config struct {
 }
 
 // EnvList is a list of key-value environment
-// variables that are passed to the Go command
+// variables that are passed to the Go command.
 type EnvList []string
 
 // HasKey returns whether a key-value entry
 // is present by only checking the left of
-// key=value
+// key=value.
 func (el EnvList) HasKey(key string) bool {
 	for _, env := range el {
 		if strings.HasPrefix(env, key+"=") {
@@ -79,7 +79,7 @@ func (el EnvList) HasKey(key string) bool {
 }
 
 // Add adds a key=value entry to the environment
-// list
+// list.
 func (el *EnvList) Add(key, value string) {
 	*el = append(*el, key+"="+value)
 }
@@ -110,7 +110,7 @@ func (el *EnvList) Decode(value string) error {
 }
 
 // Validate validates that all strings inside the
-// list are of the key=value format
+// list are of the key=value format.
 func (el EnvList) Validate() error {
 	const op errors.Op = "EnvList.Validate"
 	for _, env := range el {
@@ -123,7 +123,7 @@ func (el EnvList) Validate() error {
 }
 
 // Load loads the config from a file.
-// If file is not present returns default config
+// If file is not present returns default config.
 func Load(configFile string) (*Config, error) {
 	// User explicitly specified a config file
 	if configFile != "" {
@@ -206,7 +206,7 @@ func defaultConfig() *Config {
 }
 
 // BasicAuth returns BasicAuthUser and BasicAuthPassword
-// and ok if neither of them are empty
+// and ok if neither of them are empty.
 func (c *Config) BasicAuth() (user, pass string, ok bool) {
 	user = c.BasicAuthUser
 	pass = c.BasicAuthPass
@@ -215,7 +215,7 @@ func (c *Config) BasicAuth() (user, pass string, ok bool) {
 }
 
 // TLSCertFiles returns certificate and key files and an error if
-// both files doesn't exist and have approperiate file permissions
+// both files doesn't exist and have approperiate file permissions.
 func (c *Config) TLSCertFiles() (cert, key string, err error) {
 	if c.TLSCertFile == "" && c.TLSKeyFile == "" {
 		return "", "", nil
@@ -223,29 +223,28 @@ func (c *Config) TLSCertFiles() (cert, key string, err error) {
 
 	certFile, err := os.Stat(c.TLSCertFile)
 	if err != nil {
-		return "", "", fmt.Errorf("Could not access TLSCertFile: %v", err)
+		return "", "", fmt.Errorf("could not access TLSCertFile: %w", err)
 	}
 
 	keyFile, err := os.Stat(c.TLSKeyFile)
 	if err != nil {
-		return "", "", fmt.Errorf("Could not access TLSKeyFile: %v", err)
+		return "", "", fmt.Errorf("could not access TLSKeyFile: %w", err)
 	}
 
-	if keyFile.Mode()&077 != 0 && runtime.GOOS != "windows" {
+	if keyFile.Mode()&0o077 != 0 && runtime.GOOS != "windows" {
 		return "", "", fmt.Errorf("TLSKeyFile should not be accessible by others")
 	}
 
 	return certFile.Name(), keyFile.Name(), nil
 }
 
-// FilterOff returns true if the FilterFile is empty
+// FilterOff returns true if the FilterFile is empty.
 func (c *Config) FilterOff() bool {
 	return c.FilterFile == ""
 }
 
-// ParseConfigFile parses the given file into an athens config struct
+// ParseConfigFile parses the given file into an athens config struct.
 func ParseConfigFile(configFile string) (*Config, error) {
-
 	var config Config
 	// attempt to read the given config file
 	if _, err := toml.DecodeFile(configFile, &config); err != nil {
@@ -271,7 +270,7 @@ func ParseConfigFile(configFile string) (*Config, error) {
 	return &config, nil
 }
 
-// envOverride uses Environment variables to override unspecified properties
+// envOverride uses Environment variables to override unspecified properties.
 func envOverride(config *Config) error {
 	const defaultPort = ":3000"
 	err := envconfig.Process("athens", config)
@@ -355,16 +354,16 @@ func validateIndex(validate *validator.Validate, indexType string, config *Index
 func GetConf(path string) (*Config, error) {
 	absPath, err := filepath.Abs(path)
 	if err != nil {
-		return nil, fmt.Errorf("Unable to construct absolute path to test config file")
+		return nil, fmt.Errorf("unable to construct absolute path to test config file")
 	}
 	conf, err := ParseConfigFile(absPath)
 	if err != nil {
-		return nil, fmt.Errorf("Unable to parse test config file: %s", err.Error())
+		return nil, fmt.Errorf("unable to parse test config file: %w", err)
 	}
 	return conf, nil
 }
 
-// checkFilePerms given a list of files
+// checkFilePerms given a list of files.
 func checkFilePerms(files ...string) error {
 	const op = "config.checkFilePerms"
 
@@ -384,10 +383,9 @@ func checkFilePerms(files ...string) error {
 		// Assume unix based system (MacOS and Linux)
 		// the bit mask is calculated using the umask command which tells which permissions
 		// should not be allowed for a particular user, group or world
-		if fInfo.Mode()&0077 != 0 && runtime.GOOS != "windows" {
+		if fInfo.Mode()&0o077 != 0 && runtime.GOOS != "windows" {
 			return errors.E(op, f+" should have at most rwx,-, - (bit mask 077) as permission")
 		}
-
 	}
 
 	return nil
diff --git a/pkg/config/disk.go b/pkg/config/disk.go
index e8d37694..2db42f22 100644
--- a/pkg/config/disk.go
+++ b/pkg/config/disk.go
@@ -1,6 +1,6 @@
 package config
 
-// DiskConfig specifies the properties required to use Disk as the storage backend
+// DiskConfig specifies the properties required to use Disk as the storage backend.
 type DiskConfig struct {
 	RootPath string `validate:"required" envconfig:"ATHENS_DISK_STORAGE_ROOT"`
 }
diff --git a/pkg/config/external.go b/pkg/config/external.go
index a3f70b7a..ff5f563f 100644
--- a/pkg/config/external.go
+++ b/pkg/config/external.go
@@ -1,6 +1,6 @@
 package config
 
-// External specifies configuration for an external http storage
+// External specifies configuration for an external http storage.
 type External struct {
 	URL string `validate:"required" envconfig:"ATHENS_EXTERNAL_STORAGE_URL"`
 }
diff --git a/pkg/config/gcp.go b/pkg/config/gcp.go
index 36321a12..26f7343a 100644
--- a/pkg/config/gcp.go
+++ b/pkg/config/gcp.go
@@ -1,6 +1,6 @@
 package config
 
-// GCPConfig specifies the properties required to use GCP as the storage backend
+// GCPConfig specifies the properties required to use GCP as the storage backend.
 type GCPConfig struct {
 	ProjectID string `envconfig:"GOOGLE_CLOUD_PROJECT"`
 	Bucket    string `validate:"required" envconfig:"ATHENS_STORAGE_GCP_BUCKET"`
diff --git a/pkg/config/index.go b/pkg/config/index.go
index ed050ea9..c5ddd0af 100644
--- a/pkg/config/index.go
+++ b/pkg/config/index.go
@@ -1,6 +1,6 @@
 package config
 
-// Index is the config for various index storage backends
+// Index is the config for various index storage backends.
 type Index struct {
 	MySQL    *MySQL
 	Postgres *Postgres
diff --git a/pkg/config/minio.go b/pkg/config/minio.go
index fc5885f4..ee624382 100644
--- a/pkg/config/minio.go
+++ b/pkg/config/minio.go
@@ -1,7 +1,7 @@
 package config
 
 // MinioConfig specifies the properties required to use Minio or DigitalOcean Spaces
-// as the storage backend
+// as the storage backend.
 type MinioConfig struct {
 	Endpoint  string `validate:"required" envconfig:"ATHENS_MINIO_ENDPOINT"`
 	Key       string `validate:"required" envconfig:"ATHENS_MINIO_ACCESS_KEY_ID"`
diff --git a/pkg/config/module.go b/pkg/config/module.go
index 48412f84..f76bd1e9 100644
--- a/pkg/config/module.go
+++ b/pkg/config/module.go
@@ -7,20 +7,20 @@ import (
 )
 
 // PackageVersionedName return package full name used in storage.
-// E.g athens/@v/v1.0.mod
+// E.g athens/@v/v1.0.mod.
 func PackageVersionedName(module, version, ext string) string {
 	return fmt.Sprintf("%s/@v/%s.%s", module, version, ext)
 }
 
 // FmtModVer is a helper function that can take
-// pkg/a/b and v2.3.1 and returns pkg/a/b@v2.3.1
+// pkg/a/b and v2.3.1 and returns pkg/a/b@v2.3.1.
 func FmtModVer(mod, ver string) string {
 	return fmt.Sprintf("%s@%s", mod, ver)
 }
 
 // ModuleVersionFromPath returns module and version from a
-// storage path
-// E.g athens/@v/v1.0.info -> athens and v.1.0
+// storage path.
+// E.g athens/@v/v1.0.info -> athens and v.1.0.
 func ModuleVersionFromPath(path string) (string, string) {
 	segments := strings.Split(path, "/@v/")
 	if len(segments) != 2 {
diff --git a/pkg/config/mongo.go b/pkg/config/mongo.go
index 044e5e49..91f6f654 100644
--- a/pkg/config/mongo.go
+++ b/pkg/config/mongo.go
@@ -1,6 +1,6 @@
 package config
 
-// MongoConfig specifies the properties required to use MongoDB as the storage backend
+// MongoConfig specifies the properties required to use MongoDB as the storage backend.
 type MongoConfig struct {
 	URL                   string `validate:"required" envconfig:"ATHENS_MONGO_STORAGE_URL"`
 	DefaultDBName         string `envconfig:"ATHENS_MONGO_DEFAULT_DATABASE" default:"athens"`
diff --git a/pkg/config/mysql.go b/pkg/config/mysql.go
index 3234bc10..46e5c959 100644
--- a/pkg/config/mysql.go
+++ b/pkg/config/mysql.go
@@ -1,6 +1,6 @@
 package config
 
-// MySQL config
+// MySQL config.
 type MySQL struct {
 	Protocol string            `validate:"required" envconfig:"ATHENS_INDEX_MYSQL_PROTOCOL"`
 	Host     string            `validate:"required" envconfig:"ATHENS_INDEX_MYSQL_HOST"`
diff --git a/pkg/config/postgres.go b/pkg/config/postgres.go
index 4a4c07fc..ee2827f1 100644
--- a/pkg/config/postgres.go
+++ b/pkg/config/postgres.go
@@ -1,6 +1,6 @@
 package config
 
-// Postgres config
+// Postgres config.
 type Postgres struct {
 	Host     string            `validate:"required" envconfig:"ATHENS_INDEX_POSTGRES_HOST"`
 	Port     int               `validate:"required" envconfig:"ATHENS_INDEX_POSTGRES_PORT"`
diff --git a/pkg/config/s3.go b/pkg/config/s3.go
index bc644408..f72faefd 100644
--- a/pkg/config/s3.go
+++ b/pkg/config/s3.go
@@ -1,6 +1,6 @@
 package config
 
-// S3Config specifies the properties required to use S3 as the storage backend
+// S3Config specifies the properties required to use S3 as the storage backend.
 type S3Config struct {
 	Region                             string `validate:"required" envconfig:"AWS_REGION"`
 	Key                                string `envconfig:"AWS_ACCESS_KEY_ID"`
diff --git a/pkg/config/singleflight.go b/pkg/config/singleflight.go
index 49cc2568..69049b10 100644
--- a/pkg/config/singleflight.go
+++ b/pkg/config/singleflight.go
@@ -25,7 +25,7 @@ type Redis struct {
 }
 
 // RedisSentinel is the configuration for using redis with sentinel
-// for SingleFlight
+// for SingleFlight.
 type RedisSentinel struct {
 	Endpoints        []string `envconfig:"ATHENS_REDIS_SENTINEL_ENDPOINTS"`
 	MasterName       string   `envconfig:"ATHENS_REDIS_SENTINEL_MASTER_NAME"`
@@ -33,12 +33,14 @@ type RedisSentinel struct {
 	LockConfig       *RedisLockConfig
 }
 
+// RedisLockConfig is the configuration for redis locking.
 type RedisLockConfig struct {
 	Timeout    int `envconfig:"ATHENS_REDIS_LOCK_TIMEOUT"`
 	TTL        int `envconfig:"ATHENS_REDIS_LOCK_TTL"`
 	MaxRetries int `envconfig:"ATHENS_REDIS_LOCK_MAX_RETRIES"`
 }
 
+// DefaultRedisLockConfig returns the default redis locking configuration.
 func DefaultRedisLockConfig() *RedisLockConfig {
 	return &RedisLockConfig{
 		TTL:        900,
diff --git a/pkg/config/storage.go b/pkg/config/storage.go
index 9dd8ffa9..49d0c605 100644
--- a/pkg/config/storage.go
+++ b/pkg/config/storage.go
@@ -1,6 +1,6 @@
 package config
 
-// Storage provides configs for various storage backends
+// Storage provides configs for various storage backends.
 type Storage struct {
 	Disk      *DiskConfig
 	GCP       *GCPConfig
diff --git a/pkg/config/timeout.go b/pkg/config/timeout.go
index 8e86b84f..507bb308 100644
--- a/pkg/config/timeout.go
+++ b/pkg/config/timeout.go
@@ -2,17 +2,17 @@ package config
 
 import "time"
 
-// TimeoutConf is a common struct for anything with a timeout
+// TimeoutConf is a common struct for anything with a timeout.
 type TimeoutConf struct {
 	Timeout int `validate:"required"`
 }
 
-// TimeoutDuration returns the timeout as time.duration
+// TimeoutDuration returns the timeout as time.duration.
 func (t *TimeoutConf) TimeoutDuration() time.Duration {
 	return GetTimeoutDuration(t.Timeout)
 }
 
-// GetTimeoutDuration returns the timeout as time.duration
+// GetTimeoutDuration returns the timeout as time.duration.
 func GetTimeoutDuration(timeout int) time.Duration {
 	return time.Second * time.Duration(timeout)
 }
diff --git a/pkg/download/get_module_params.go b/pkg/download/get_module_params.go
index ff8bdd33..1d68a2bf 100644
--- a/pkg/download/get_module_params.go
+++ b/pkg/download/get_module_params.go
@@ -7,7 +7,7 @@ import (
 	"github.com/gomods/athens/pkg/paths"
 )
 
-func getModuleParams(r *http.Request, op errors.Op) (mod string, ver string, err error) {
+func getModuleParams(r *http.Request, op errors.Op) (mod, ver string, err error) {
 	params, err := paths.GetAllParams(r)
 	if err != nil {
 		return "", "", errors.E(op, err, errors.KindBadRequest)
diff --git a/pkg/download/handler.go b/pkg/download/handler.go
index 13106e62..8045e4d1 100644
--- a/pkg/download/handler.go
+++ b/pkg/download/handler.go
@@ -15,8 +15,7 @@ import (
 // a ready-to-go http handler that serves up cmd/go's download protocol.
 type ProtocolHandler func(dp Protocol, lggr log.Entry, df *mode.DownloadFile) http.Handler
 
-// HandlerOpts are the generic options
-// for a ProtocolHandler
+// HandlerOpts are the generic options for a ProtocolHandler.
 type HandlerOpts struct {
 	Protocol     Protocol
 	Logger       *log.Logger
@@ -26,7 +25,7 @@ type HandlerOpts struct {
 // LogEntryHandler pulls a log entry from the request context. Thanks to the
 // LogEntryMiddleware, we should have a log entry stored in the context for each
 // request with request-specific fields. This will grab the entry and pass it to
-// the protocol handlers
+// the protocol handlers.
 func LogEntryHandler(ph ProtocolHandler, opts *HandlerOpts) http.Handler {
 	f := func(w http.ResponseWriter, r *http.Request) {
 		ent := log.EntryFromContext(r.Context())
diff --git a/pkg/download/list.go b/pkg/download/list.go
index 3de919a4..405fbca4 100644
--- a/pkg/download/list.go
+++ b/pkg/download/list.go
@@ -14,7 +14,7 @@ import (
 // PathList URL.
 const PathList = "/{module:.+}/@v/list"
 
-// ListHandler implements GET baseURL/module/@v/list
+// ListHandler implements GET baseURL/module/@v/list.
 func ListHandler(dp Protocol, lggr log.Entry, df *mode.DownloadFile) http.Handler {
 	const op errors.Op = "download.ListHandler"
 	f := func(w http.ResponseWriter, r *http.Request) {
diff --git a/pkg/download/mode/mode.go b/pkg/download/mode/mode.go
index 0e46132f..20960eda 100644
--- a/pkg/download/mode/mode.go
+++ b/pkg/download/mode/mode.go
@@ -4,6 +4,7 @@ import (
 	"encoding/base64"
 	"fmt"
 	"os"
+	"path/filepath"
 	"strings"
 
 	"github.com/gomods/athens/pkg/errors"
@@ -16,7 +17,7 @@ import (
 // when a module is not found in storage.
 type Mode string
 
-// DownloadMode constants. For more information see config.dev.toml
+// DownloadMode constants. For more information see config.dev.toml.
 const (
 	Sync            Mode = "sync"
 	Async           Mode = "async"
@@ -59,7 +60,7 @@ func NewFile(m Mode, downloadURL string) (*DownloadFile, error) {
 
 	if strings.HasPrefix(string(m), "file:") {
 		filePath := string(m[5:])
-		bts, err := os.ReadFile(filePath)
+		bts, err := os.ReadFile(filepath.Clean(filePath))
 		if err != nil {
 			return nil, err
 		}
diff --git a/pkg/download/protocol.go b/pkg/download/protocol.go
index 324a0767..b9d5945e 100644
--- a/pkg/download/protocol.go
+++ b/pkg/download/protocol.go
@@ -48,7 +48,7 @@ type Opts struct {
 	NetworkMode  string
 }
 
-// NetworkMode constants
+// NetworkMode constants.
 const (
 	Strict   = "strict"
 	Offline  = "offline"
@@ -263,12 +263,12 @@ func (p *protocol) processDownload(ctx context.Context, mod, ver string, f func(
 		}
 		return f(newVer)
 	case mode.Async:
-		go p.stasher.Stash(ctx, mod, ver)
+		go func() { _, _ = p.stasher.Stash(ctx, mod, ver) }()
 		return errors.E(op, "async: module not found", errors.KindNotFound)
 	case mode.Redirect:
 		return errors.E(op, "redirect", errors.KindRedirect)
 	case mode.AsyncRedirect:
-		go p.stasher.Stash(ctx, mod, ver)
+		go func() { _, _ = p.stasher.Stash(ctx, mod, ver) }()
 		return errors.E(op, "async_redirect: module not found", errors.KindRedirect)
 	case mode.None:
 		return errors.E(op, "none", errors.KindNotFound)
@@ -276,7 +276,7 @@ func (p *protocol) processDownload(ctx context.Context, mod, ver string, f func(
 	return nil
 }
 
-// union concatenates two version lists and removes duplicates
+// union concatenates two version lists and removes duplicates.
 func union(list1, list2 []string) []string {
 	if list1 == nil {
 		list1 = []string{}
@@ -284,10 +284,10 @@ func union(list1, list2 []string) []string {
 	if list2 == nil {
 		list2 = []string{}
 	}
-	list := append(list1, list2...)
+	list1 = append(list1, list2...)
 	unique := []string{}
 	m := make(map[string]struct{})
-	for _, v := range list {
+	for _, v := range list1 {
 		if _, ok := m[v]; !ok {
 			unique = append(unique, v)
 			m[v] = struct{}{}
diff --git a/pkg/download/version_info.go b/pkg/download/version_info.go
index b0dd802e..3a6c9603 100644
--- a/pkg/download/version_info.go
+++ b/pkg/download/version_info.go
@@ -11,7 +11,7 @@ import (
 // PathVersionInfo URL.
 const PathVersionInfo = "/{module:.+}/@v/{version}.info"
 
-// InfoHandler implements GET baseURL/module/@v/version.info
+// InfoHandler implements GET baseURL/module/@v/version.info.
 func InfoHandler(dp Protocol, lggr log.Entry, df *mode.DownloadFile) http.Handler {
 	const op errors.Op = "download.InfoHandler"
 	f := func(w http.ResponseWriter, r *http.Request) {
@@ -38,7 +38,7 @@ func InfoHandler(dp Protocol, lggr log.Entry, df *mode.DownloadFile) http.Handle
 			w.WriteHeader(errors.Kind(err))
 		}
 
-		w.Write(info)
+		_, _ = w.Write(info)
 	}
 	return http.HandlerFunc(f)
 }
diff --git a/pkg/download/version_module.go b/pkg/download/version_module.go
index 46806894..1a100230 100644
--- a/pkg/download/version_module.go
+++ b/pkg/download/version_module.go
@@ -11,7 +11,7 @@ import (
 // PathVersionModule URL.
 const PathVersionModule = "/{module:.+}/@v/{version}.mod"
 
-// ModuleHandler implements GET baseURL/module/@v/version.mod
+// ModuleHandler implements GET baseURL/module/@v/version.mod.
 func ModuleHandler(dp Protocol, lggr log.Entry, df *mode.DownloadFile) http.Handler {
 	const op errors.Op = "download.VersionModuleHandler"
 	f := func(w http.ResponseWriter, r *http.Request) {
@@ -42,7 +42,7 @@ func ModuleHandler(dp Protocol, lggr log.Entry, df *mode.DownloadFile) http.Hand
 			return
 		}
 
-		w.Write(modBts)
+		_, _ = w.Write(modBts)
 	}
 	return http.HandlerFunc(f)
 }
diff --git a/pkg/download/version_zip.go b/pkg/download/version_zip.go
index d9bdb862..bfc5b773 100644
--- a/pkg/download/version_zip.go
+++ b/pkg/download/version_zip.go
@@ -13,7 +13,7 @@ import (
 // PathVersionZip URL.
 const PathVersionZip = "/{module:.+}/@v/{version}.zip"
 
-// ZipHandler implements GET baseURL/module/@v/version.zip
+// ZipHandler implements GET baseURL/module/@v/version.zip.
 func ZipHandler(dp Protocol, lggr log.Entry, df *mode.DownloadFile) http.Handler {
 	const op errors.Op = "download.ZipHandler"
 	f := func(w http.ResponseWriter, r *http.Request) {
@@ -41,7 +41,7 @@ func ZipHandler(dp Protocol, lggr log.Entry, df *mode.DownloadFile) http.Handler
 			w.WriteHeader(errors.Kind(err))
 			return
 		}
-		defer zip.Close()
+		defer func() { _ = zip.Close() }()
 
 		w.Header().Set("Content-Type", "application/zip")
 		size := zip.Size()
diff --git a/pkg/errors/errors.go b/pkg/errors/errors.go
index 9700b936..4f922034 100644
--- a/pkg/errors/errors.go
+++ b/pkg/errors/errors.go
@@ -9,7 +9,7 @@ import (
 	"github.com/sirupsen/logrus"
 )
 
-// Kind enums
+// Kind enums.
 const (
 	KindNotFound       = http.StatusNotFound
 	KindBadRequest     = http.StatusBadRequest
@@ -55,6 +55,16 @@ func Is(err error, kind int) bool {
 	return Kind(err) == kind
 }
 
+// IsErr is a convenience wrapper around the std library errors.Is.
+func IsErr(err, target error) bool {
+	return errors.Is(err, target)
+}
+
+// AsErr is a convenience wrapper around the std library errors.As.
+func AsErr(err error, target any) bool {
+	return errors.As(err, target)
+}
+
 // Op describes any independent function or
 // method in Athens. A series of operations
 // forms a more readable stack trace.
@@ -69,7 +79,7 @@ func (o Op) String() string {
 // a module from a regular error string or version.
 type M string
 
-// V represents a module version in an error
+// V represents a module version in an error.
 type V string
 
 // E is a helper function to construct an Error type
@@ -114,8 +124,8 @@ func E(op Op, args ...interface{}) error {
 // if none exists, then the level is Error because
 // it is an unexpected.
 func Severity(err error) logrus.Level {
-	e, ok := err.(Error)
-	if !ok {
+	var e Error
+	if !errors.As(err, &e) {
 		return logrus.ErrorLevel
 	}
 
@@ -145,8 +155,8 @@ func Expect(err error, kinds ...int) logrus.Level {
 // Kind recursively searches for the
 // first error kind it finds.
 func Kind(err error) int {
-	e, ok := err.(Error)
-	if !ok {
+	var e Error
+	if !errors.As(err, &e) {
 		return KindUnexpected
 	}
 
@@ -173,6 +183,7 @@ func KindText(err error) string {
 func Ops(err Error) []Op {
 	ops := []Op{err.Op}
 	for {
+		//nolint:errorlint // We iterate the errors anyway.
 		embeddedErr, ok := err.Err.(Error)
 		if !ok {
 			break
diff --git a/pkg/errors/kinds.go b/pkg/errors/kinds.go
index e62417ea..5b2f46d8 100644
--- a/pkg/errors/kinds.go
+++ b/pkg/errors/kinds.go
@@ -1,6 +1,6 @@
 package errors
 
-// IsNotFoundErr helper function for KindNotFound
+// IsNotFoundErr helper function for KindNotFound.
 func IsNotFoundErr(err error) bool {
 	return Kind(err) == KindNotFound
 }
diff --git a/pkg/index/compliance/compliance.go b/pkg/index/compliance/compliance.go
index 16f46499..e27591e7 100644
--- a/pkg/index/compliance/compliance.go
+++ b/pkg/index/compliance/compliance.go
@@ -21,7 +21,7 @@ func RunTests(t *testing.T, indexer index.Indexer, clearIndex func() error) {
 		t.Fatal(err)
 	}
 
-	var tests = []struct {
+	tests := []struct {
 		name    string
 		desc    string
 		limit   int
diff --git a/pkg/index/indexer.go b/pkg/index/indexer.go
index 395aa0c5..5b6f8a3d 100644
--- a/pkg/index/indexer.go
+++ b/pkg/index/indexer.go
@@ -13,7 +13,7 @@ type Line struct {
 }
 
 // Indexer is an interface that can process new module@versions
-// and also retrieve 'limit' module@versions that were indexed after 'since'
+// and also retrieve 'limit' module@versions that were indexed after 'since'.
 type Indexer interface {
 	// Index stores the module@version into the index backend.
 	// Implementer must create the Timestamp at the time and set it
diff --git a/pkg/index/mem/mem.go b/pkg/index/mem/mem.go
index 253f0d43..e6d0bf7e 100644
--- a/pkg/index/mem/mem.go
+++ b/pkg/index/mem/mem.go
@@ -10,7 +10,7 @@ import (
 	"github.com/gomods/athens/pkg/index"
 )
 
-// New returns a new in-memory indexer
+// New returns a new in-memory indexer.
 func New() index.Indexer {
 	return &indexer{}
 }
diff --git a/pkg/index/mysql/mysql.go b/pkg/index/mysql/mysql.go
index 7298cd3f..39f66771 100644
--- a/pkg/index/mysql/mysql.go
+++ b/pkg/index/mysql/mysql.go
@@ -83,8 +83,8 @@ func (i *indexer) Lines(ctx context.Context, since time.Time, limit int) ([]*ind
 	if err != nil {
 		return nil, errors.E(op, err)
 	}
-	defer rows.Close()
-	lines := []*index.Line{}
+	defer func() { _ = rows.Close() }()
+	var lines []*index.Line
 	for rows.Next() {
 		var line index.Line
 		err = rows.Scan(&line.Path, &line.Version, &line.Timestamp)
@@ -108,13 +108,14 @@ func getMySQLSource(cfg *config.MySQL) string {
 }
 
 func getKind(err error) int {
-	mysqlErr, ok := err.(*mysql.MySQLError)
-	if !ok {
+	mysqlErr := &mysql.MySQLError{}
+	if !errors.AsErr(err, &mysqlErr) {
 		return errors.KindUnexpected
 	}
 	switch mysqlErr.Number {
 	case 1062:
 		return errors.KindAlreadyExists
+	default:
+		return errors.KindUnexpected
 	}
-	return errors.KindUnexpected
 }
diff --git a/pkg/index/nop/nop.go b/pkg/index/nop/nop.go
index 5140d249..91049156 100644
--- a/pkg/index/nop/nop.go
+++ b/pkg/index/nop/nop.go
@@ -7,7 +7,7 @@ import (
 	"github.com/gomods/athens/pkg/index"
 )
 
-// New returns a no-op Indexer
+// New returns a no-op Indexer.
 func New() index.Indexer {
 	return indexer{}
 }
@@ -17,6 +17,7 @@ type indexer struct{}
 func (indexer) Index(ctx context.Context, mod, ver string) error {
 	return nil
 }
+
 func (indexer) Lines(ctx context.Context, since time.Time, limit int) ([]*index.Line, error) {
 	return []*index.Line{}, nil
 }
diff --git a/pkg/index/postgres/postgres.go b/pkg/index/postgres/postgres.go
index 6fb14c40..e3d83bcc 100644
--- a/pkg/index/postgres/postgres.go
+++ b/pkg/index/postgres/postgres.go
@@ -7,17 +7,15 @@ import (
 	"strings"
 	"time"
 
-	// register the driver with database/sql
-	"github.com/lib/pq"
-
 	"github.com/gomods/athens/pkg/config"
 	"github.com/gomods/athens/pkg/errors"
 	"github.com/gomods/athens/pkg/index"
+	"github.com/lib/pq"
 )
 
 // New returns a new Indexer with a PostgreSQL implementation.
 // It attempts to connect to the DB and create the index table
-// if it doesn ot already exist.
+// if it does not already exist.
 func New(cfg *config.Postgres) (index.Indexer, error) {
 	dataSource := getPostgresSource(cfg)
 	db, err := sql.Open("postgres", dataSource)
@@ -42,7 +40,7 @@ var schema = [...]string{
 			id SERIAL PRIMARY KEY,
 			path VARCHAR(255) NOT NULL,
 			version VARCHAR(255) NOT NULL,
-			timestamp timestamp NOT NULL
+			timestamp TIMESTAMP NOT NULL
 		)
 	`,
 	`
@@ -82,8 +80,8 @@ func (i *indexer) Lines(ctx context.Context, since time.Time, limit int) ([]*ind
 	if err != nil {
 		return nil, errors.E(op, err)
 	}
-	defer rows.Close()
-	lines := []*index.Line{}
+	defer func() { _ = rows.Close() }()
+	var lines []*index.Line
 	for rows.Next() {
 		var line index.Line
 		err = rows.Scan(&line.Path, &line.Version, &line.Timestamp)
@@ -96,7 +94,7 @@ func (i *indexer) Lines(ctx context.Context, since time.Time, limit int) ([]*ind
 }
 
 func getPostgresSource(cfg *config.Postgres) string {
-	args := []string{}
+	args := make([]string, 0, 5+len(cfg.Params))
 	args = append(args, "host="+cfg.Host)
 	args = append(args, "port=", strconv.Itoa(cfg.Port))
 	args = append(args, "user=", cfg.User)
@@ -109,13 +107,14 @@ func getPostgresSource(cfg *config.Postgres) string {
 }
 
 func getKind(err error) int {
-	pqerr, ok := err.(*pq.Error)
-	if !ok {
+	pqerr := &pq.Error{}
+	if !errors.AsErr(err, &pqerr) {
 		return errors.KindUnexpected
 	}
 	switch pqerr.Code {
 	case "23505":
 		return errors.KindAlreadyExists
+	default:
+		return errors.KindUnexpected
 	}
-	return errors.KindUnexpected
 }
diff --git a/pkg/log/entry.go b/pkg/log/entry.go
index e90d9df4..ef21480e 100644
--- a/pkg/log/entry.go
+++ b/pkg/log/entry.go
@@ -35,8 +35,8 @@ func (e *entry) WithFields(fields map[string]interface{}) Entry {
 }
 
 func (e *entry) SystemErr(err error) {
-	athensErr, ok := err.(errors.Error)
-	if !ok {
+	var athensErr errors.Error
+	if !errors.IsErr(err, athensErr) {
 		e.Error(err)
 		return
 	}
diff --git a/pkg/log/log.go b/pkg/log/log.go
index c0b78337..1c55d3e2 100644
--- a/pkg/log/log.go
+++ b/pkg/log/log.go
@@ -41,7 +41,7 @@ func (l *Logger) WithFields(fields map[string]interface{}) Entry {
 	return &entry{e}
 }
 
-// NoOpLogger provides a Logger that does nothing
+// NoOpLogger provides a Logger that does nothing.
 func NoOpLogger() *Logger {
 	return &Logger{
 		Logger: &logrus.Logger{},
diff --git a/pkg/log/log_context.go b/pkg/log/log_context.go
index c4501df0..fd36069d 100644
--- a/pkg/log/log_context.go
+++ b/pkg/log/log_context.go
@@ -8,14 +8,14 @@ type ctxKey string
 
 const logEntryKey ctxKey = "log-entry-context-key"
 
-// SetEntryInContext stores an Entry in the request context
+// SetEntryInContext stores an Entry in the request context.
 func SetEntryInContext(ctx context.Context, e Entry) context.Context {
 	return context.WithValue(ctx, logEntryKey, e)
 }
 
 // EntryFromContext returns an Entry that has been stored in the request context.
 // If there is no value for the key or the type assertion fails, it returns a new
-// entry from the provided logger
+// entry from the provided logger.
 func EntryFromContext(ctx context.Context) Entry {
 	e, ok := ctx.Value(logEntryKey).(Entry)
 	if !ok || e == nil {
diff --git a/pkg/middleware/content_type.go b/pkg/middleware/content_type.go
index 9078ea9a..76d906f6 100644
--- a/pkg/middleware/content_type.go
+++ b/pkg/middleware/content_type.go
@@ -4,7 +4,7 @@ import (
 	"net/http"
 )
 
-// ContentType writes writes an application/json
+// ContentType writes an application/json
 // Content-Type header.
 func ContentType(h http.Handler) http.Handler {
 	f := func(w http.ResponseWriter, r *http.Request) {
diff --git a/pkg/middleware/log_entry.go b/pkg/middleware/log_entry.go
index 88b084a9..8d6016cf 100644
--- a/pkg/middleware/log_entry.go
+++ b/pkg/middleware/log_entry.go
@@ -10,7 +10,7 @@ import (
 )
 
 // LogEntryMiddleware builds a log.Entry, setting the request fields
-// and storing it in the context to be used throughout the stack
+// and storing it in the context to be used throughout the stack.
 func LogEntryMiddleware(lggr *log.Logger) mux.MiddlewareFunc {
 	return func(h http.Handler) http.Handler {
 		f := func(w http.ResponseWriter, r *http.Request) {
diff --git a/pkg/middleware/requestid.go b/pkg/middleware/requestid.go
index d4850f94..9a528975 100644
--- a/pkg/middleware/requestid.go
+++ b/pkg/middleware/requestid.go
@@ -9,7 +9,7 @@ import (
 
 // WithRequestID ensures a request id is in the
 // request context by either the incoming header
-// or creating a new one
+// or creating a new one.
 func WithRequestID(h http.Handler) http.Handler {
 	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 		requestID := r.Header.Get(requestid.HeaderKey)
diff --git a/pkg/middleware/validation.go b/pkg/middleware/validation.go
index cd01a5e5..371b3df8 100644
--- a/pkg/middleware/validation.go
+++ b/pkg/middleware/validation.go
@@ -14,7 +14,7 @@ import (
 )
 
 // NewValidationMiddleware builds a middleware function that performs validation checks by calling
-// an external webhook
+// an external webhook.
 func NewValidationMiddleware(client *http.Client, validatorHook string) mux.MiddlewareFunc {
 	const op errors.Op = "actions.NewValidationMiddleware"
 	return func(h http.Handler) http.Handler {
@@ -50,7 +50,7 @@ func NewValidationMiddleware(client *http.Client, validatorHook string) mux.Midd
 	}
 }
 
-func maybeLogValidationReason(context context.Context, message string, mod string, version string) {
+func maybeLogValidationReason(context context.Context, message, mod, version string) {
 	if len(message) > 0 {
 		entry := log.EntryFromContext(context)
 		entry.Warnf("error validating %s@%s %s", mod, version, message)
@@ -85,6 +85,10 @@ func validate(ctx context.Context, client *http.Client, hook, mod, ver string) (
 	if err != nil {
 		return validationResponse{Valid: false}, errors.E(op, err)
 	}
+	defer func() {
+		_, _ = io.Copy(io.Discard, resp.Body)
+		_ = resp.Body.Close()
+	}()
 
 	switch resp.StatusCode {
 	case http.StatusOK:
@@ -97,8 +101,6 @@ func validate(ctx context.Context, client *http.Client, hook, mod, ver string) (
 }
 
 func validationResponseFromRequest(resp *http.Response) validationResponse {
-	defer resp.Body.Close()
-
 	body, _ := io.ReadAll(resp.Body)
 	return validationResponse{Valid: resp.StatusCode == http.StatusOK, Message: body}
 }
diff --git a/pkg/module/fetcher.go b/pkg/module/fetcher.go
index 1f76bdfe..b0969a72 100644
--- a/pkg/module/fetcher.go
+++ b/pkg/module/fetcher.go
@@ -6,7 +6,7 @@ import (
 	"github.com/gomods/athens/pkg/storage"
 )
 
-// Fetcher fetches module from an upstream source
+// Fetcher fetches module from an upstream source.
 type Fetcher interface {
 	// Fetch downloads the sources from an upstream and returns the corresponding
 	// .info, .mod, and .zip files.
diff --git a/pkg/module/filter.go b/pkg/module/filter.go
index 80b04eaa..8da2b9ca 100644
--- a/pkg/module/filter.go
+++ b/pkg/module/filter.go
@@ -3,6 +3,7 @@ package module
 import (
 	"bufio"
 	"os"
+	"path/filepath"
 	"strconv"
 	"strings"
 
@@ -14,15 +15,15 @@ var (
 	versionSeparator = "."
 )
 
-// Filter is a filter of modules
+// Filter is a filter of modules.
 type Filter struct {
 	root     ruleNode
 	filePath string
 }
 
-// NewFilter creates new filter based on rules defined in a configuration file
-// WARNING: this is not concurrently safe
-// Configuration consists of two operations: + for include and - for exclude
+// NewFilter creates new filter based on rules defined in a configuration file.
+// WARNING: this is not concurrently safe.
+// Configuration consists of two operations: + for include and - for exclude:
 // e.g.
 //   - github.com/a
 //   - github.com/a/b
@@ -33,7 +34,7 @@ type Filter struct {
 //	-
 //	+ github.com/a
 //
-// will exclude all items from communication except github.com/a
+// will exclude all items from communication except github.com/a.
 func NewFilter(filterFilePath string) (*Filter, error) {
 	// Do not return an error if the file path is empty
 	// Do not attempt to parse it as well.
@@ -42,10 +43,9 @@ func NewFilter(filterFilePath string) (*Filter, error) {
 	}
 
 	return initFromConfig(filterFilePath)
-
 }
 
-// AddRule adds rule for specified path
+// AddRule adds rule for specified path.
 func (f *Filter) AddRule(path string, qualifiers []string, rule FilterRule) {
 	f.ensurePath(path)
 
@@ -70,7 +70,7 @@ func (f *Filter) AddRule(path string, qualifiers []string, rule FilterRule) {
 	latest.next[last] = rn
 }
 
-// Rule returns the filter rule to be applied to the given path
+// Rule returns the filter rule to be applied to the given path.
 func (f *Filter) Rule(path, version string) FilterRule {
 	segs := getPathSegments(path)
 	rule := f.getAssociatedRule(version, segs...)
@@ -145,7 +145,6 @@ func initFromConfig(filePath string) (*Filter, error) {
 	f.root = rn
 
 	for idx, line := range lines {
-
 		// Ignore newline
 		if len(line) == 0 {
 			continue
@@ -160,7 +159,7 @@ func initFromConfig(filePath string) (*Filter, error) {
 		}
 
 		ruleSign := strings.TrimSpace(split[0])
-		rule := Default
+		var rule FilterRule
 		switch ruleSign {
 		case "+":
 			rule = Include
@@ -195,11 +194,11 @@ func initFromConfig(filePath string) (*Filter, error) {
 
 // matches checks if the given version matches the given qualifier.
 // Qualifiers can be:
-// - plain versions
-// - v1.2.3 enables v1.2.3
-// - ~1.2.3: enables 1.2.x  which are at least 1.2.3
-// - ^1.2.3: enables 1.x.x which are at least 1.2.3
-// - <1.2.3: enables everything lower than 1.2.3 includes 1.2.2 and 0.58.9 as well
+// - plain versions.
+// - v1.2.3 enables v1.2.3.
+// - ~1.2.3: enables 1.2.x  which are at least 1.2.3.
+// - ^1.2.3: enables 1.x.x which are at least 1.2.3.
+// - <1.2.3: enables everything lower than 1.2.3 includes 1.2.2 and 0.58.9 as well.
 func matches(version, qualifier string) bool {
 	if len(qualifier) < 2 || len(version) < 1 {
 		return false
@@ -297,7 +296,7 @@ func newRule(r FilterRule) ruleNode {
 func getConfigLines(filterFile string) ([]string, error) {
 	const op errors.Op = "module.getConfigLines"
 
-	f, err := os.Open(filterFile)
+	f, err := os.Open(filepath.Clean(filterFile))
 	if err != nil {
 		return nil, errors.E(op, err)
 	}
diff --git a/pkg/module/filterRule.go b/pkg/module/filterRule.go
index 3a8b88f2..8d24c79f 100644
--- a/pkg/module/filterRule.go
+++ b/pkg/module/filterRule.go
@@ -1,16 +1,16 @@
 package module
 
-// FilterRule defines behavior of module communication
+// FilterRule defines behavior of module communication.
 type FilterRule int
 
 const (
-	// Default filter rule does not alter default/parent behavior
+	// Default filter rule does not alter default/parent behavior.
 	Default FilterRule = iota
-	// Include treats modules the usual way
-	// Used for reverting Exclude of parent path
+	// Include treats modules the usual way.
+	// Used for reverting Exclude of parent path.
 	Include
-	// Exclude filter rule excludes package and its children from communication
+	// Exclude filter rule excludes package and its children from communication.
 	Exclude
-	// Direct filter rule forces the package to be fetched directly from upstream proxy
+	// Direct filter rule forces the package to be fetched directly from upstream proxy.
 	Direct
 )
diff --git a/pkg/module/go_get_fetcher.go b/pkg/module/go_get_fetcher.go
index 6e4ffb1e..e43d3529 100644
--- a/pkg/module/go_get_fetcher.go
+++ b/pkg/module/go_get_fetcher.go
@@ -35,7 +35,7 @@ type goModule struct {
 	GoModSum string `json:"goModSum"` // checksum for go.mod (as in go.sum)
 }
 
-// NewGoGetFetcher creates fetcher which uses go get tool to fetch modules
+// NewGoGetFetcher creates fetcher which uses go get tool to fetch modules.
 func NewGoGetFetcher(goBinaryName, gogetDir string, envVars []string, fs afero.Fs) (Fetcher, error) {
 	const op errors.Op = "module.NewGoGetFetcher"
 	if err := validGoBinary(goBinaryName); err != nil {
@@ -64,7 +64,7 @@ func (g *goGetFetcher) Fetch(ctx context.Context, mod, ver string) (*storage.Ver
 	sourcePath := filepath.Join(goPathRoot, "src")
 	modPath := filepath.Join(sourcePath, getRepoDirName(mod, ver))
 	if err := g.fs.MkdirAll(modPath, os.ModeDir|os.ModePerm); err != nil {
-		clearFiles(g.fs, goPathRoot)
+		_ = clearFiles(g.fs, goPathRoot)
 		return nil, errors.E(op, err)
 	}
 
@@ -72,14 +72,13 @@ func (g *goGetFetcher) Fetch(ctx context.Context, mod, ver string) (*storage.Ver
 		ctx,
 		g.goBinaryName,
 		g.envVars,
-		g.fs,
 		goPathRoot,
 		modPath,
 		mod,
 		ver,
 	)
 	if err != nil {
-		clearFiles(g.fs, goPathRoot)
+		_ = clearFiles(g.fs, goPathRoot)
 		return nil, errors.E(op, err)
 	}
 
@@ -116,7 +115,6 @@ func downloadModule(
 	ctx context.Context,
 	goBinaryName string,
 	envVars []string,
-	fs afero.Fs,
 	gopath,
 	repoRoot,
 	module,
@@ -137,7 +135,7 @@ func downloadModule(
 
 	err := cmd.Run()
 	if err != nil {
-		err = fmt.Errorf("%v: %s", err, stderr)
+		err = fmt.Errorf("%w: %s", err, stderr)
 		var m goModule
 		if jsonErr := json.NewDecoder(stdout).Decode(&m); jsonErr != nil {
 			return goModule{}, errors.E(op, err)
@@ -165,17 +163,17 @@ func isLimitHit(o string) bool {
 }
 
 // getRepoDirName takes a raw repository URI and a version and creates a directory name that the
-// repository contents can be put into
+// repository contents can be put into.
 func getRepoDirName(repoURI, version string) string {
-	escapedURI := strings.Replace(repoURI, "/", "-", -1)
+	escapedURI := strings.ReplaceAll(repoURI, "/", "-")
 	return fmt.Sprintf("%s-%s", escapedURI, version)
 }
 
 func validGoBinary(name string) error {
 	const op errors.Op = "module.validGoBinary"
 	err := exec.Command(name).Run()
-	_, ok := err.(*exec.ExitError)
-	if err != nil && !ok {
+	eErr := &exec.ExitError{}
+	if err != nil && !errors.AsErr(err, &eErr) {
 		return errors.E(op, err)
 	}
 	return nil
diff --git a/pkg/module/go_vcs_lister.go b/pkg/module/go_vcs_lister.go
index 7a021d05..a6c1c611 100644
--- a/pkg/module/go_vcs_lister.go
+++ b/pkg/module/go_vcs_lister.go
@@ -28,7 +28,7 @@ type vcsLister struct {
 	fs        afero.Fs
 }
 
-// NewVCSLister creates an UpstreamLister which uses VCS to fetch a list of available versions
+// NewVCSLister creates an UpstreamLister which uses VCS to fetch a list of available versions.
 func NewVCSLister(goBinPath string, env []string, fs afero.Fs) UpstreamLister {
 	return &vcsLister{
 		goBinPath: goBinPath,
@@ -39,13 +39,13 @@ func NewVCSLister(goBinPath string, env []string, fs afero.Fs) UpstreamLister {
 
 func (l *vcsLister) List(ctx context.Context, module string) (*storage.RevInfo, []string, error) {
 	const op errors.Op = "vcsLister.List"
-	ctx, span := observ.StartSpan(ctx, op.String())
+	_, span := observ.StartSpan(ctx, op.String())
 	defer span.End()
 	tmpDir, err := afero.TempDir(l.fs, "", "go-list")
 	if err != nil {
 		return nil, nil, errors.E(op, err)
 	}
-	defer l.fs.RemoveAll(tmpDir)
+	defer func() { _ = l.fs.RemoveAll(tmpDir) }()
 
 	cmd := exec.Command(
 		l.goBinPath,
@@ -62,12 +62,12 @@ func (l *vcsLister) List(ctx context.Context, module string) (*storage.RevInfo,
 	if err != nil {
 		return nil, nil, errors.E(op, err)
 	}
-	defer clearFiles(l.fs, gopath)
+	defer func() { _ = clearFiles(l.fs, gopath) }()
 	cmd.Env = prepareEnv(gopath, l.env)
 
 	err = cmd.Run()
 	if err != nil {
-		err = fmt.Errorf("%v: %s", err, stderr)
+		err = fmt.Errorf("%w: %s", err, stderr)
 		// as of now, we can't recognize between a true NotFound
 		// and an unexpected error, so we choose the more
 		// hopeful path of NotFound. This way the Go command
diff --git a/pkg/module/prepare_env.go b/pkg/module/prepare_env.go
index 49549759..f12b8334 100644
--- a/pkg/module/prepare_env.go
+++ b/pkg/module/prepare_env.go
@@ -9,7 +9,7 @@ import (
 
 // prepareEnv will return all the appropriate
 // environment variables for a Go Command to run
-// successfully (such as GOPATH, GOCACHE, PATH etc)
+// successfully (such as GOPATH, GOCACHE, PATH etc).
 func prepareEnv(gopath string, envVars []string) []string {
 	gopathEnv := fmt.Sprintf("GOPATH=%s", gopath)
 	cacheEnv := fmt.Sprintf("GOCACHE=%s", filepath.Join(gopath, "cache"))
diff --git a/pkg/module/zip_read_closer.go b/pkg/module/zip_read_closer.go
index 3f24f933..b6a14f38 100644
--- a/pkg/module/zip_read_closer.go
+++ b/pkg/module/zip_read_closer.go
@@ -14,10 +14,10 @@ type zipReadCloser struct {
 	goPath string
 }
 
-// Close closes the zip file handle and clears up disk space used by the underlying disk ref
-// It is the caller's responsibility to call this method to free up utilized disk space
+// Close closes the zip file handle and clears up disk space used by the underlying disk ref.
+// It is the caller's responsibility to call this method to free up utilized disk space.
 func (rc *zipReadCloser) Close() error {
-	rc.zip.Close()
+	_ = rc.zip.Close()
 	return clearFiles(rc.fs, rc.goPath)
 }
 
@@ -25,8 +25,8 @@ func (rc *zipReadCloser) Read(p []byte) (n int, err error) {
 	return rc.zip.Read(p)
 }
 
-// clearFiles deletes all data from the given fs at path root
-// This function must be called when zip is closed to cleanup the entire GOPATH created by the diskref
+// clearFiles deletes all data from the given fs at path root.
+// This function must be called when zip is closed to cleanup the entire GOPATH created by the diskref.
 func clearFiles(fs afero.Fs, root string) error {
 	const op errors.Op = "module.ClearFiles"
 	// This is required because vgo ensures dependencies are read-only
@@ -36,7 +36,7 @@ func clearFiles(fs afero.Fs, root string) error {
 		if err != nil {
 			return err
 		}
-		return fs.Chmod(path, 0770)
+		return fs.Chmod(path, 0o770)
 	}
 	err := afero.Walk(fs, root, walkFn)
 	if err != nil {
diff --git a/pkg/observ/observ.go b/pkg/observ/observ.go
index 15181c33..b7f98657 100755
--- a/pkg/observ/observ.go
+++ b/pkg/observ/observ.go
@@ -13,16 +13,16 @@ import (
 
 // RegisterExporter determines the type of TraceExporter service for exporting traces from opencensus
 // User can choose from multiple tracing services (datadog, jaegar)
-// RegisterExporter returns the 'Flush' function for that particular tracing service
-func RegisterExporter(traceExporter, URL, service, ENV string) (func(), error) {
+// RegisterExporter returns the 'Flush' function for that particular tracing service.
+func RegisterExporter(traceExporter, url, service, env string) (func(), error) {
 	const op errors.Op = "observ.RegisterExporter"
 	switch traceExporter {
 	case "jaeger":
-		return registerJaegerExporter(URL, service, ENV)
+		return registerJaegerExporter(url, service, env)
 	case "datadog":
-		return registerDatadogExporter(URL, service, ENV)
+		return registerDatadogExporter(url, service, env)
 	case "stackdriver":
-		return registerStackdriverExporter(URL, ENV)
+		return registerStackdriverExporter(url, env)
 	case "":
 		return nil, errors.E(op, "Exporter not specified. Traces won't be exported")
 	default:
@@ -32,14 +32,14 @@ func RegisterExporter(traceExporter, URL, service, ENV string) (func(), error) {
 
 // registerJaegerExporter creates a jaeger exporter for exporting traces to opencensus.
 // Currently uses the 'TraceExporter' variable in the config file.
-// It should in the future have a nice sampling rate defined
-func registerJaegerExporter(URL, service, ENV string) (func(), error) {
+// It should in the future have a nice sampling rate defined.
+func registerJaegerExporter(url, service, env string) (func(), error) {
 	const op errors.Op = "observ.registerJaegarExporter"
-	if URL == "" {
+	if url == "" {
 		return nil, errors.E(op, "Exporter URL is empty. Traces won't be exported")
 	}
 	ex, err := jaeger.NewExporter(jaeger.Options{
-		Endpoint: URL,
+		Endpoint: url,
 		Process: jaeger.Process{
 			ServiceName: service,
 			Tags: []jaeger.Tag{
@@ -53,41 +53,41 @@ func registerJaegerExporter(URL, service, ENV string) (func(), error) {
 	if err != nil {
 		return nil, errors.E(op, err)
 	}
-	traceRegisterExporter(ex, ENV)
+	traceRegisterExporter(ex, env)
 	return ex.Flush, nil
 }
 
-func traceRegisterExporter(exporter trace.Exporter, ENV string) {
+func traceRegisterExporter(exporter trace.Exporter, env string) {
 	trace.RegisterExporter(exporter)
-	if ENV == "development" {
+	if env == "development" {
 		trace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()})
 	}
 }
 
 // registerDatadogTracerExporter creates a datadog exporter.
 // Currently uses the 'TraceExporter' variable in the config file.
-func registerDatadogExporter(URL, service, ENV string) (func(), error) {
+func registerDatadogExporter(url, service, env string) (func(), error) {
 	ex := datadog.NewExporter(
 		datadog.Options{
-			TraceAddr: URL,
+			TraceAddr: url,
 			Service:   service,
 		})
-	traceRegisterExporter(ex, ENV)
+	traceRegisterExporter(ex, env)
 	return ex.Stop, nil
 }
 
-func registerStackdriverExporter(projectID, ENV string) (func(), error) {
+func registerStackdriverExporter(projectID, env string) (func(), error) {
 	const op errors.Op = "observ.registerStackdriverExporter"
 	ex, err := stackdriver.NewExporter(stackdriver.Options{ProjectID: projectID})
 	if err != nil {
 		return nil, errors.E(op, err)
 	}
-	traceRegisterExporter(ex, ENV)
+	traceRegisterExporter(ex, env)
 	return ex.Flush, nil
 }
 
 // StartSpan takes in a Context Interface and opName and starts a span. It returns the new attached ObserverContext
-// and span
+// and span.
 func StartSpan(ctx context.Context, op string) (context.Context, *trace.Span) {
 	return trace.StartSpan(ctx, op)
 }
diff --git a/pkg/observ/stats.go b/pkg/observ/stats.go
index 59560b12..a670ef2b 100755
--- a/pkg/observ/stats.go
+++ b/pkg/observ/stats.go
@@ -15,10 +15,10 @@ import (
 )
 
 // RegisterStatsExporter determines the type of StatsExporter service for exporting stats from Opencensus
-// Currently it supports: prometheus
+// Currently it supports: prometheus.
 func RegisterStatsExporter(r *mux.Router, statsExporter, service string) (func(), error) {
 	const op errors.Op = "observ.RegisterStatsExporter"
-	var stop = func() {}
+	stop := func() {}
 	var err error
 	switch statsExporter {
 	case "prometheus":
@@ -38,7 +38,7 @@ func RegisterStatsExporter(r *mux.Router, statsExporter, service string) (func()
 	default:
 		return nil, errors.E(op, fmt.Sprintf("StatsExporter %s not supported. Please open PR or an issue at github.com/gomods/athens", statsExporter))
 	}
-	if err := registerViews(); err != nil {
+	if err = registerViews(); err != nil {
 		return nil, errors.E(op, err)
 	}
 
@@ -89,7 +89,7 @@ func registerStatsStackDriverExporter(projectID string) (func(), error) {
 	return sd.Flush, nil
 }
 
-// registerViews register stats which should be collected in Athens
+// registerViews register stats which should be collected in Athens.
 func registerViews() error {
 	const op errors.Op = "observ.registerViews"
 	if err := view.Register(
diff --git a/pkg/paths/decode.go b/pkg/paths/decode.go
index e22eef98..ab3de74f 100644
--- a/pkg/paths/decode.go
+++ b/pkg/paths/decode.go
@@ -19,8 +19,9 @@ func DecodePath(encoding string) (path string, err error) {
 	return path, nil
 }
 
-// Ripped from cmd/go
+// Ripped from cmd/go.
 func decodeString(encoding string) (string, bool) {
+	//nolint:prealloc
 	var buf []byte
 
 	bang := false
diff --git a/pkg/paths/path.go b/pkg/paths/path.go
index d8109384..20995654 100644
--- a/pkg/paths/path.go
+++ b/pkg/paths/path.go
@@ -9,7 +9,7 @@ import (
 	"github.com/gorilla/mux"
 )
 
-// GetModule gets the module from the path of a ?go-get=1 request
+// GetModule gets the module from the path of a ?go-get=1 request.
 func GetModule(r *http.Request) (string, error) {
 	const op errors.Op = "paths.GetModule"
 	module := mux.Vars(r)["module"]
@@ -19,7 +19,7 @@ func GetModule(r *http.Request) (string, error) {
 	return DecodePath(module)
 }
 
-// GetVersion gets the version from the path of a ?go-get=1 request
+// GetVersion gets the version from the path of a ?go-get=1 request.
 func GetVersion(r *http.Request) (string, error) {
 	const op errors.Op = "paths.GetVersion"
 
@@ -31,13 +31,13 @@ func GetVersion(r *http.Request) (string, error) {
 }
 
 // AllPathParams holds the module and version in the path of a ?go-get=1
-// request
+// request.
 type AllPathParams struct {
 	Module  string `json:"module"`
 	Version string `json:"version"`
 }
 
-// GetAllParams fetches the path params from r and returns them
+// GetAllParams fetches the path params from r and returns them.
 func GetAllParams(r *http.Request) (*AllPathParams, error) {
 	const op errors.Op = "paths.GetAllParams"
 	mod, err := GetModule(r)
@@ -54,7 +54,7 @@ func GetAllParams(r *http.Request) (*AllPathParams, error) {
 }
 
 // MatchesPattern reports whether the path prefix of target matches
-// pattern (as defined by path.Match)
+// pattern (as defined by path.Match).
 //
 // This tries to keep the same behavior as GOPRIVATE/GONOPROXY/GONOSUMDB,
 // and is adopted from:
diff --git a/pkg/requestid/requestid.go b/pkg/requestid/requestid.go
index fc3a8b92..b92063fc 100644
--- a/pkg/requestid/requestid.go
+++ b/pkg/requestid/requestid.go
@@ -3,18 +3,18 @@ package requestid
 import "context"
 
 // HeaderKey is the header key that athens uses
-// to pass request ids into logs and outbound requests
+// to pass request ids into logs and outbound requests.
 const HeaderKey = "Athens-Request-ID"
 
 type key struct{}
 
-// SetInContext sets the given requestID into the context
+// SetInContext sets the given requestID into the context.
 func SetInContext(ctx context.Context, id string) context.Context {
 	return context.WithValue(ctx, key{}, id)
 }
 
 // FromContext returns a requestID from the context or an empty
-// string if not found
+// string if not found.
 func FromContext(ctx context.Context) string {
 	id, _ := ctx.Value(key{}).(string)
 	return id
diff --git a/pkg/stash/stasher.go b/pkg/stash/stasher.go
index d0d79a9a..68365cf5 100644
--- a/pkg/stash/stasher.go
+++ b/pkg/stash/stasher.go
@@ -19,7 +19,7 @@ import (
 // what was requested, this is helpful if what was requested
 // was a descriptive version such as a branch name or a full commit sha.
 type Stasher interface {
-	Stash(ctx context.Context, mod string, ver string) (string, error)
+	Stash(ctx context.Context, mod, ver string) (string, error)
 }
 
 // Wrapper helps extend the main stasher's functionality with addons.
@@ -46,7 +46,7 @@ type stasher struct {
 
 func (s *stasher) Stash(ctx context.Context, mod, ver string) (string, error) {
 	const op errors.Op = "stasher.Stash"
-	_, span := observ.StartSpan(ctx, op.String())
+	ctx, span := observ.StartSpan(ctx, op.String())
 	defer span.End()
 	log.EntryFromContext(ctx).Debugf("saving %s@%s to storage...", mod, ver)
 
@@ -58,7 +58,7 @@ func (s *stasher) Stash(ctx context.Context, mod, ver string) (string, error) {
 	if err != nil {
 		return "", errors.E(op, err)
 	}
-	defer v.Zip.Close()
+	defer func() { _ = v.Zip.Close() }()
 	if v.Semver != ver {
 		exists, err := s.checker.Exists(ctx, mod, v.Semver)
 		if err != nil {
diff --git a/pkg/stash/with_azureblob.go b/pkg/stash/with_azureblob.go
index fd4bd0a8..ccebda68 100644
--- a/pkg/stash/with_azureblob.go
+++ b/pkg/stash/with_azureblob.go
@@ -132,8 +132,8 @@ func (s *azblobLock) acquireLease(ctx context.Context, blobURL azblob.BlockBlobU
 	_, err := blobURL.Upload(tctx, bytes.NewReader([]byte{1}), azblob.BlobHTTPHeaders{}, nil, azblob.BlobAccessConditions{})
 	if err != nil {
 		// if the blob is already leased we will get http.StatusPreconditionFailed while writing to that blob
-		stgErr, ok := err.(azblob.StorageError)
-		if !ok || stgErr.Response().StatusCode != http.StatusPreconditionFailed {
+		var stgErr azblob.StorageError
+		if !errors.AsErr(err, &stgErr) || stgErr.Response().StatusCode != http.StatusPreconditionFailed {
 			return "", errors.E(op, err)
 		}
 	}
@@ -147,7 +147,8 @@ func (s *azblobLock) acquireLease(ctx context.Context, blobURL azblob.BlockBlobU
 		res, err := blobURL.AcquireLease(tctx, leaseID.String(), 15, azblob.ModifiedAccessConditions{})
 		if err != nil {
 			// if the blob is already leased we will get http.StatusConflict - wait and try again
-			if stgErr, ok := err.(azblob.StorageError); ok && stgErr.Response().StatusCode == http.StatusConflict {
+			var stgErr azblob.StorageError
+			if ok := errors.AsErr(err, &stgErr); ok && stgErr.Response().StatusCode == http.StatusConflict {
 				select {
 				case <-time.After(1 * time.Second):
 					continue
diff --git a/pkg/stash/with_etcd.go b/pkg/stash/with_etcd.go
index 7940e9bf..1cd8d2f9 100644
--- a/pkg/stash/with_etcd.go
+++ b/pkg/stash/with_etcd.go
@@ -8,7 +8,7 @@ import (
 	"github.com/gomods/athens/pkg/errors"
 	"github.com/gomods/athens/pkg/observ"
 	"github.com/gomods/athens/pkg/storage"
-	"go.etcd.io/etcd/client/v3"
+	clientv3 "go.etcd.io/etcd/client/v3"
 	"go.etcd.io/etcd/client/v3/concurrency"
 	"golang.org/x/sync/errgroup"
 )
diff --git a/pkg/stash/with_redis.go b/pkg/stash/with_redis.go
index 35bf7936..64e8d1de 100644
--- a/pkg/stash/with_redis.go
+++ b/pkg/stash/with_redis.go
@@ -13,14 +13,14 @@ import (
 	"github.com/gomods/athens/pkg/storage"
 )
 
-// RedisLogger mirrors github.com/go-redis/redis/v8/internal.Logging
+// RedisLogger mirrors github.com/go-redis/redis/v8/internal.Logging.
 type RedisLogger interface {
 	Printf(ctx context.Context, format string, v ...interface{})
 }
 
 // WithRedisLock returns a distributed singleflight
 // using a redis cluster. If it cannot connect, it will return an error.
-func WithRedisLock(l RedisLogger, endpoint string, password string, checker storage.Checker, lockConfig *config.RedisLockConfig) (Wrapper, error) {
+func WithRedisLock(l RedisLogger, endpoint, password string, checker storage.Checker, lockConfig *config.RedisLockConfig) (Wrapper, error) {
 	redis.SetLogger(l)
 
 	const op errors.Op = "stash.WithRedisLock"
diff --git a/pkg/stash/with_redis_sentinel.go b/pkg/stash/with_redis_sentinel.go
index 3eb4aa59..bf890b20 100644
--- a/pkg/stash/with_redis_sentinel.go
+++ b/pkg/stash/with_redis_sentinel.go
@@ -10,7 +10,7 @@ import (
 )
 
 // WithRedisSentinelLock returns a distributed singleflight
-// with a redis cluster that utilizes sentinel for quorum and failover
+// with a redis cluster that utilizes sentinel for quorum and failover.
 func WithRedisSentinelLock(l RedisLogger, endpoints []string, master, password string, checker storage.Checker, lockConfig *config.RedisLockConfig) (Wrapper, error) {
 	redis.SetLogger(l)
 
diff --git a/pkg/storage/azureblob/azureblob.go b/pkg/storage/azureblob/azureblob.go
index 916623e4..53712d5b 100644
--- a/pkg/storage/azureblob/azureblob.go
+++ b/pkg/storage/azureblob/azureblob.go
@@ -15,14 +15,6 @@ import (
 	"github.com/gomods/athens/pkg/storage"
 )
 
-type client interface {
-	UploadWithContext(ctx context.Context, path, contentType string, content io.Reader) error
-	BlobExists(ctx context.Context, path string) (bool, error)
-	ReadBlob(ctx context.Context, path string) (io.ReadCloser, error)
-	ListBlobs(ctx context.Context, prefix string) ([]string, error)
-	DeleteBlob(ctx context.Context, path string) error
-}
-
 type azureBlobStoreClient struct {
 	containerURL *azblob.ContainerURL
 }
@@ -45,13 +37,13 @@ func newBlobStoreClient(accountURL *url.URL, accountName, accountKey, containerN
 }
 
 // Storage implements (github.com/gomods/athens/pkg/storage).Saver and
-// also provides a function to fetch the location of a module
+// also provides a function to fetch the location of a module.
 type Storage struct {
 	client  *azureBlobStoreClient
 	timeout time.Duration
 }
 
-// New creates a new azure blobs storage
+// New creates a new azure blobs storage.
 func New(conf *config.AzureBlobConfig, timeout time.Duration) (*Storage, error) {
 	const op errors.Op = "azureblob.New"
 	u, err := url.Parse(fmt.Sprintf("https://%s.blob.core.windows.net", conf.AccountName))
@@ -65,7 +57,7 @@ func New(conf *config.AzureBlobConfig, timeout time.Duration) (*Storage, error)
 	return &Storage{client: cl, timeout: timeout}, nil
 }
 
-// BlobExists checks if a particular blob exists in the container
+// BlobExists checks if a particular blob exists in the container.
 func (c *azureBlobStoreClient) BlobExists(ctx context.Context, path string) (bool, error) {
 	const op errors.Op = "azureblob.BlobExists"
 	// TODO: Any better way of doing this ?
@@ -73,10 +65,8 @@ func (c *azureBlobStoreClient) BlobExists(ctx context.Context, path string) (boo
 	_, err := blobURL.GetProperties(ctx, azblob.BlobAccessConditions{})
 	if err != nil {
 		var serr azblob.StorageError
-		var ok bool
-
-		if serr, ok = err.(azblob.StorageError); !ok {
-			return false, errors.E(op, fmt.Errorf("Error in casting to azure error type %v", err))
+		if !errors.AsErr(err, &serr) {
+			return false, errors.E(op, fmt.Errorf("error in casting to azure error type %w", err))
 		}
 		if serr.Response().StatusCode == http.StatusNotFound {
 			return false, nil
@@ -85,10 +75,9 @@ func (c *azureBlobStoreClient) BlobExists(ctx context.Context, path string) (boo
 		return false, errors.E(op, err)
 	}
 	return true, nil
-
 }
 
-// ReadBlob returns a storage.SizeReadCloser for the contents of a blob
+// ReadBlob returns a storage.SizeReadCloser for the contents of a blob.
 func (c *azureBlobStoreClient) ReadBlob(ctx context.Context, path string) (storage.SizeReadCloser, error) {
 	const op errors.Op = "azureblob.ReadBlob"
 	blobURL := c.containerURL.NewBlockBlobURL(path)
@@ -101,7 +90,7 @@ func (c *azureBlobStoreClient) ReadBlob(ctx context.Context, path string) (stora
 	return storage.NewSizer(rc, size), nil
 }
 
-// ListBlobs will list all blobs which has the given prefix
+// ListBlobs will list all blobs which has the given prefix.
 func (c *azureBlobStoreClient) ListBlobs(ctx context.Context, prefix string) ([]string, error) {
 	const op errors.Op = "azureblob.ListBlobs"
 	var blobs []string
@@ -122,7 +111,7 @@ func (c *azureBlobStoreClient) ListBlobs(ctx context.Context, prefix string) ([]
 	return blobs, nil
 }
 
-// DeleteBlob deletes the blob with the given path
+// DeleteBlob deletes the blob with the given path.
 func (c *azureBlobStoreClient) DeleteBlob(ctx context.Context, path string) error {
 	const op errors.Op = "azureblob.DeleteBlob"
 	blobURL := c.containerURL.NewBlockBlobURL(path)
@@ -133,7 +122,7 @@ func (c *azureBlobStoreClient) DeleteBlob(ctx context.Context, path string) erro
 	return nil
 }
 
-// UploadWithContext uploads a blob to the container
+// UploadWithContext uploads a blob to the container.
 func (c *azureBlobStoreClient) UploadWithContext(ctx context.Context, path, contentType string, content io.Reader) error {
 	const op errors.Op = "azureblob.UploadWithContext"
 	ctx, span := observ.StartSpan(ctx, op.String())
diff --git a/pkg/storage/azureblob/cataloger.go b/pkg/storage/azureblob/cataloger.go
index d7906936..4bba622d 100644
--- a/pkg/storage/azureblob/cataloger.go
+++ b/pkg/storage/azureblob/cataloger.go
@@ -12,8 +12,8 @@ import (
 	"github.com/gomods/athens/pkg/paths"
 )
 
-// Catalog implements the (./pkg/storage).Catalog interface
-// It returns a list of versions, if any, for a given module
+// Catalog implements the (./pkg/storage).Catalog interface.
+// It returns a list of versions, if any, for a given module.
 func (s *Storage) Catalog(ctx context.Context, token string, pageSize int) ([]paths.AllPathParams, string, error) {
 	const op errors.Op = "azblob.Catalog"
 	ctx, span := observ.StartSpan(ctx, op.String())
diff --git a/pkg/storage/azureblob/checker.go b/pkg/storage/azureblob/checker.go
index 93388588..99f1056e 100644
--- a/pkg/storage/azureblob/checker.go
+++ b/pkg/storage/azureblob/checker.go
@@ -9,8 +9,8 @@ import (
 )
 
 // Exists implements the (./pkg/storage).Checker interface
-// returning true if the module at version exists in storage
-func (s *Storage) Exists(ctx context.Context, module string, version string) (bool, error) {
+// returning true if the module at version exists in storage.
+func (s *Storage) Exists(ctx context.Context, module, version string) (bool, error) {
 	const op errors.Op = "azureblob.Exists"
 	ctx, span := observ.StartSpan(ctx, op.String())
 	defer span.End()
diff --git a/pkg/storage/azureblob/deleter.go b/pkg/storage/azureblob/deleter.go
index 0907a1cc..bfdd1c0b 100644
--- a/pkg/storage/azureblob/deleter.go
+++ b/pkg/storage/azureblob/deleter.go
@@ -11,7 +11,7 @@ import (
 // Delete implements the (./pkg/storage).Deleter interface and
 // removes a version of a module from storage. Returning ErrNotFound
 // if the version does not exist.
-func (s *Storage) Delete(ctx context.Context, module string, version string) error {
+func (s *Storage) Delete(ctx context.Context, module, version string) error {
 	const op errors.Op = "azureblob.Delete"
 	ctx, span := observ.StartSpan(ctx, op.String())
 	defer span.End()
diff --git a/pkg/storage/azureblob/getter.go b/pkg/storage/azureblob/getter.go
index 1a8675a3..77aeb1a2 100644
--- a/pkg/storage/azureblob/getter.go
+++ b/pkg/storage/azureblob/getter.go
@@ -11,8 +11,8 @@ import (
 	"github.com/gomods/athens/pkg/storage"
 )
 
-// Info implements the (./pkg/storage).Getter interface
-func (s *Storage) Info(ctx context.Context, module string, version string) ([]byte, error) {
+// Info implements the (./pkg/storage).Getter interface.
+func (s *Storage) Info(ctx context.Context, module, version string) ([]byte, error) {
 	const op errors.Op = "azureblob.Info"
 	ctx, span := observ.StartSpan(ctx, op.String())
 	defer span.End()
@@ -43,8 +43,8 @@ func (s *Storage) Info(ctx context.Context, module string, version string) ([]by
 	return infoBytes, nil
 }
 
-// GoMod implements the (./pkg/storage).Getter interface
-func (s *Storage) GoMod(ctx context.Context, module string, version string) ([]byte, error) {
+// GoMod implements the (./pkg/storage).Getter interface.
+func (s *Storage) GoMod(ctx context.Context, module, version string) ([]byte, error) {
 	const op errors.Op = "azureblob.GoMod"
 	ctx, span := observ.StartSpan(ctx, op.String())
 	defer span.End()
@@ -64,7 +64,7 @@ func (s *Storage) GoMod(ctx context.Context, module string, version string) ([]b
 
 	modBytes, err := io.ReadAll(modReader)
 	if err != nil {
-		return nil, errors.E(op, fmt.Errorf("could not get new reader for mod file: %s", err), errors.M(module), errors.V(version))
+		return nil, errors.E(op, fmt.Errorf("could not get new reader for mod file: %w", err), errors.M(module), errors.V(version))
 	}
 
 	err = modReader.Close()
@@ -75,8 +75,8 @@ func (s *Storage) GoMod(ctx context.Context, module string, version string) ([]b
 	return modBytes, nil
 }
 
-// Zip implements the (./pkg/storage).Getter interface
-func (s *Storage) Zip(ctx context.Context, module string, version string) (storage.SizeReadCloser, error) {
+// Zip implements the (./pkg/storage).Getter interface.
+func (s *Storage) Zip(ctx context.Context, module, version string) (storage.SizeReadCloser, error) {
 	const op errors.Op = "azureblob.Zip"
 	ctx, span := observ.StartSpan(ctx, op.String())
 	defer span.End()
diff --git a/pkg/storage/azureblob/lister.go b/pkg/storage/azureblob/lister.go
index 9e8c5225..62425445 100644
--- a/pkg/storage/azureblob/lister.go
+++ b/pkg/storage/azureblob/lister.go
@@ -8,8 +8,8 @@ import (
 	"github.com/gomods/athens/pkg/observ"
 )
 
-// List implements the (./pkg/storage).Lister interface
-// It returns a list of versions, if any, for a given module
+// List implements the (./pkg/storage).Lister interface.
+// It returns a list of versions, if any, for a given module.
 func (s *Storage) List(ctx context.Context, module string) ([]string, error) {
 	const op errors.Op = "azureblob.List"
 	ctx, span := observ.StartSpan(ctx, op.String())
diff --git a/pkg/storage/backend.go b/pkg/storage/backend.go
index 7cb5ef4b..97c27a53 100644
--- a/pkg/storage/backend.go
+++ b/pkg/storage/backend.go
@@ -1,6 +1,6 @@
 package storage
 
-// Backend is a complete storage backend (i.e. file system, database) implementation - a lister, reader and saver
+// Backend is a complete storage backend (i.e. file system, database) implementation - a lister, reader and saver.
 type Backend interface {
 	Lister
 	Getter
diff --git a/pkg/storage/cataloger.go b/pkg/storage/cataloger.go
index b1bbd163..793f5c5c 100644
--- a/pkg/storage/cataloger.go
+++ b/pkg/storage/cataloger.go
@@ -6,7 +6,7 @@ import (
 	"github.com/gomods/athens/pkg/paths"
 )
 
-// Cataloger is the interface that lists all the modules and version contained in the storage
+// Cataloger is the interface that lists all the modules and version contained in the storage.
 type Cataloger interface {
 	// Catalog gets all the modules / versions.
 	Catalog(ctx context.Context, token string, pageSize int) ([]paths.AllPathParams, string, error)
diff --git a/pkg/storage/checker.go b/pkg/storage/checker.go
index 6a64c7d5..8f017b19 100644
--- a/pkg/storage/checker.go
+++ b/pkg/storage/checker.go
@@ -6,14 +6,14 @@ import (
 	"github.com/gomods/athens/pkg/errors"
 )
 
-// Checker is the interface that checks if the version of the module exists
+// Checker is the interface that checks if the version of the module exists.
 type Checker interface {
 	// Exists checks whether or not module in specified version is present
-	// in the backing storage
+	// in the backing storage.
 	Exists(ctx context.Context, module, version string) (bool, error)
 }
 
-// WithChecker wraps the backend with a Checker implementaiton
+// WithChecker wraps the backend with a Checker implementation.
 func WithChecker(strg Backend) Checker {
 	if checker, ok := strg.(Checker); ok {
 		return checker
diff --git a/pkg/storage/deleter.go b/pkg/storage/deleter.go
index 367c65b7..b093af00 100644
--- a/pkg/storage/deleter.go
+++ b/pkg/storage/deleter.go
@@ -2,7 +2,7 @@ package storage
 
 import "context"
 
-// Deleter deletes module metadata and its source from underlying storage
+// Deleter deletes module metadata and its source from underlying storage.
 type Deleter interface {
 	// Delete must return ErrNotFound if the module/version are not
 	// found.
diff --git a/pkg/storage/external/client.go b/pkg/storage/external/client.go
index 8a024ab2..b33e5d21 100644
--- a/pkg/storage/external/client.go
+++ b/pkg/storage/external/client.go
@@ -20,7 +20,7 @@ type service struct {
 	c   *http.Client
 }
 
-// NewClient returns an external storage client
+// NewClient returns an external storage client.
 func NewClient(url string, c *http.Client) storage.Backend {
 	if c == nil {
 		c = &http.Client{}
@@ -93,7 +93,7 @@ func (s *service) Save(ctx context.Context, mod, ver string, modFile []byte, zip
 	mw := multipart.NewWriter(pw)
 	go func() {
 		err := upload(mw, modFile, info, zip)
-		pw.CloseWithError(err)
+		_ = pw.CloseWithError(err)
 	}()
 	req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, pr)
 	if err != nil {
@@ -104,8 +104,8 @@ func (s *service) Save(ctx context.Context, mod, ver string, modFile []byte, zip
 	if err != nil {
 		return errors.E(op, err)
 	}
-	defer resp.Body.Close()
-	if resp.StatusCode != 200 {
+	defer func() { _ = resp.Body.Close() }()
+	if resp.StatusCode != http.StatusOK {
 		bts, _ := io.ReadAll(resp.Body)
 		return errors.E(op, fmt.Errorf("unexpected status code: %v - body: %s", resp.StatusCode, bts), resp.StatusCode)
 	}
@@ -118,35 +118,35 @@ func (s *service) Delete(ctx context.Context, mod, ver string) error {
 	if err != nil {
 		return errors.E(op, err)
 	}
-	defer body.Close()
+	defer func() { _ = body.Close() }()
 	return nil
 }
 
 func upload(mw *multipart.Writer, mod, info []byte, zip io.Reader) error {
-	defer mw.Close()
+	defer func() { _ = mw.Close() }()
 	infoW, err := mw.CreateFormFile("mod.info", "mod.info")
 	if err != nil {
-		return fmt.Errorf("error creating info file: %v", err)
+		return fmt.Errorf("error creating info file: %w", err)
 	}
 	_, err = infoW.Write(info)
 	if err != nil {
-		return fmt.Errorf("error writing info file: %v", err)
+		return fmt.Errorf("error writing info file: %w", err)
 	}
 	modW, err := mw.CreateFormFile("mod.mod", "mod.mod")
 	if err != nil {
-		return fmt.Errorf("error creating mod file: %v", err)
+		return fmt.Errorf("error creating mod file: %w", err)
 	}
 	_, err = modW.Write(mod)
 	if err != nil {
-		return fmt.Errorf("error writing mod file: %v", err)
+		return fmt.Errorf("error writing mod file: %w", err)
 	}
 	zipW, err := mw.CreateFormFile("mod.zip", "mod.zip")
 	if err != nil {
-		return fmt.Errorf("error creating zip file: %v", err)
+		return fmt.Errorf("error creating zip file: %w", err)
 	}
 	_, err = io.Copy(zipW, zip)
 	if err != nil {
-		return fmt.Errorf("error writing zip file: %v", err)
+		return fmt.Errorf("error writing zip file: %w", err)
 	}
 	return nil
 }
@@ -174,9 +174,9 @@ func (s *service) doRequest(ctx context.Context, method, mod, ver, ext string) (
 	if err != nil {
 		return nil, 0, errors.E(op, err)
 	}
-	if resp.StatusCode != 200 {
+	if resp.StatusCode != http.StatusOK {
 		body, _ := io.ReadAll(resp.Body)
-		resp.Body.Close()
+		_ = resp.Body.Close()
 		return nil, 0, errors.E(op, fmt.Errorf("none 200 status code: %v - body: %s", resp.StatusCode, body), resp.StatusCode)
 	}
 	var size int64
diff --git a/pkg/storage/external/server.go b/pkg/storage/external/server.go
index 4b9b76b6..b4a4b8ca 100644
--- a/pkg/storage/external/server.go
+++ b/pkg/storage/external/server.go
@@ -17,7 +17,7 @@ import (
 
 // NewServer takes a storage.Backend implementation of your
 // choice, and returns a new http.Handler that Athens can
-// reach out to for storage operations
+// reach out to for storage operations.
 func NewServer(strg storage.Backend) http.Handler {
 	r := mux.NewRouter()
 	r.HandleFunc(download.PathList, func(w http.ResponseWriter, r *http.Request) {
@@ -27,12 +27,12 @@ func NewServer(strg storage.Backend) http.Handler {
 			http.Error(w, err.Error(), errors.Kind(err))
 			return
 		}
-		fmt.Fprintf(w, "%s", strings.Join(list, "\n"))
+		_, _ = fmt.Fprintf(w, "%s", strings.Join(list, "\n"))
 	}).Methods(http.MethodGet)
 	r.HandleFunc(download.PathVersionInfo, func(w http.ResponseWriter, r *http.Request) {
 		params, err := paths.GetAllParams(r)
 		if err != nil {
-			http.Error(w, err.Error(), 400)
+			http.Error(w, err.Error(), http.StatusBadRequest)
 			return
 		}
 		info, err := strg.Info(r.Context(), params.Module, params.Version)
@@ -40,12 +40,12 @@ func NewServer(strg storage.Backend) http.Handler {
 			http.Error(w, err.Error(), errors.Kind(err))
 			return
 		}
-		w.Write(info)
+		_, _ = w.Write(info)
 	}).Methods(http.MethodGet)
 	r.HandleFunc(download.PathVersionModule, func(w http.ResponseWriter, r *http.Request) {
 		params, err := paths.GetAllParams(r)
 		if err != nil {
-			http.Error(w, err.Error(), 400)
+			http.Error(w, err.Error(), http.StatusBadRequest)
 			return
 		}
 		mod, err := strg.GoMod(r.Context(), params.Module, params.Version)
@@ -53,12 +53,12 @@ func NewServer(strg storage.Backend) http.Handler {
 			http.Error(w, err.Error(), errors.Kind(err))
 			return
 		}
-		w.Write(mod)
+		_, _ = w.Write(mod)
 	}).Methods(http.MethodGet)
 	r.HandleFunc(download.PathVersionZip, func(w http.ResponseWriter, r *http.Request) {
 		params, err := paths.GetAllParams(r)
 		if err != nil {
-			http.Error(w, err.Error(), 400)
+			http.Error(w, err.Error(), http.StatusBadRequest)
 			return
 		}
 		zip, err := strg.Zip(r.Context(), params.Module, params.Version)
@@ -66,52 +66,52 @@ func NewServer(strg storage.Backend) http.Handler {
 			http.Error(w, err.Error(), errors.Kind(err))
 			return
 		}
-		defer zip.Close()
+		defer func() { _ = zip.Close() }()
 		w.Header().Set("Content-Length", strconv.FormatInt(zip.Size(), 10))
-		io.Copy(w, zip)
+		_, _ = io.Copy(w, zip)
 	}).Methods(http.MethodGet)
 	r.HandleFunc("/{module:.+}/@v/{version}.save", func(w http.ResponseWriter, r *http.Request) {
 		params, err := paths.GetAllParams(r)
 		if err != nil {
-			http.Error(w, err.Error(), 400)
+			http.Error(w, err.Error(), http.StatusBadRequest)
 			return
 		}
 		err = r.ParseMultipartForm(zip.MaxZipFile + zip.MaxGoMod)
 		if err != nil {
-			http.Error(w, err.Error(), 400)
+			http.Error(w, err.Error(), http.StatusBadRequest)
 			return
 		}
 		infoFile, _, err := r.FormFile("mod.info")
 		if err != nil {
-			http.Error(w, err.Error(), 400)
+			http.Error(w, err.Error(), http.StatusBadRequest)
 			return
 		}
-		defer infoFile.Close()
+		defer func() { _ = infoFile.Close() }()
 		info, err := io.ReadAll(infoFile)
 		if err != nil {
-			http.Error(w, err.Error(), 400)
+			http.Error(w, err.Error(), http.StatusBadRequest)
 			return
 		}
 		modReader, _, err := r.FormFile("mod.mod")
 		if err != nil {
-			http.Error(w, err.Error(), 400)
+			http.Error(w, err.Error(), http.StatusBadRequest)
 			return
 		}
-		defer modReader.Close()
+		defer func() { _ = modReader.Close() }()
 		modFile, err := io.ReadAll(modReader)
 		if err != nil {
-			http.Error(w, err.Error(), 400)
+			http.Error(w, err.Error(), http.StatusBadRequest)
 			return
 		}
 		modZ, _, err := r.FormFile("mod.zip")
 		if err != nil {
-			http.Error(w, err.Error(), 400)
+			http.Error(w, err.Error(), http.StatusBadRequest)
 			return
 		}
-		defer modZ.Close()
+		defer func() { _ = modZ.Close() }()
 		err = strg.Save(r.Context(), params.Module, params.Version, modFile, modZ, info)
 		if err != nil {
-			http.Error(w, err.Error(), 400)
+			http.Error(w, err.Error(), http.StatusBadRequest)
 			return
 		}
 	}).Methods(http.MethodPost)
@@ -119,7 +119,7 @@ func NewServer(strg storage.Backend) http.Handler {
 	r.HandleFunc("/{module:.+}/@v/{version}.delete", func(w http.ResponseWriter, r *http.Request) {
 		params, err := paths.GetAllParams(r)
 		if err != nil {
-			http.Error(w, err.Error(), 400)
+			http.Error(w, err.Error(), http.StatusBadRequest)
 			return
 		}
 		err = strg.Delete(r.Context(), params.Module, params.Version)
diff --git a/pkg/storage/fs/cataloger.go b/pkg/storage/fs/cataloger.go
index 368f73cf..d310c483 100644
--- a/pkg/storage/fs/cataloger.go
+++ b/pkg/storage/fs/cataloger.go
@@ -15,11 +15,11 @@ import (
 
 const tokenSeparator = "|"
 
-// Catalog implements the (./pkg/storage).Cataloger interface
-// It returns a list of modules and versions contained in the storage
+// Catalog implements the (./pkg/storage).Cataloger interface.
+// It returns a list of modules and versions contained in the storage.
 func (s *storageImpl) Catalog(ctx context.Context, token string, pageSize int) ([]paths.AllPathParams, string, error) {
 	const op errors.Op = "fs.Catalog"
-	ctx, span := observ.StartSpan(ctx, op.String())
+	_, span := observ.StartSpan(ctx, op.String())
 	defer span.End()
 
 	fromModule, fromVersion, err := modVerFromToken(token)
@@ -41,7 +41,7 @@ func (s *storageImpl) Catalog(ctx context.Context, token string, pageSize int) (
 
 			m, version := filepath.Split(modVer)
 			module := filepath.Clean(m)
-			module = strings.Replace(module, string(os.PathSeparator), "/", -1)
+			module = strings.ReplaceAll(module, string(os.PathSeparator), "/")
 
 			if fromModule != "" && module < fromModule { // it is ok to land on the same module
 				return nil
@@ -60,7 +60,7 @@ func (s *storageImpl) Catalog(ctx context.Context, token string, pageSize int) (
 		}
 		return nil
 	})
-	if err != nil && err != io.EOF {
+	if err != nil && !errors.IsErr(err, io.EOF) {
 		return nil, "", errors.E(op, err, errors.KindUnexpected)
 	}
 
diff --git a/pkg/storage/fs/checker.go b/pkg/storage/fs/checker.go
index 9d7a3987..b32dc488 100644
--- a/pkg/storage/fs/checker.go
+++ b/pkg/storage/fs/checker.go
@@ -9,14 +9,13 @@ import (
 	"github.com/spf13/afero"
 )
 
-func (v *storageImpl) Exists(ctx context.Context, module, version string) (bool, error) {
+func (s *storageImpl) Exists(ctx context.Context, module, version string) (bool, error) {
 	const op errors.Op = "fs.Exists"
-	ctx, span := observ.StartSpan(ctx, op.String())
+	_, span := observ.StartSpan(ctx, op.String())
 	defer span.End()
-	versionedPath := v.versionLocation(module, version)
-
-	files, err := afero.ReadDir(v.filesystem, versionedPath)
+	versionedPath := s.versionLocation(module, version)
 
+	files, err := afero.ReadDir(s.filesystem, versionedPath)
 	if err != nil {
 		if os.IsNotExist(err) {
 			return false, nil
diff --git a/pkg/storage/fs/deleter.go b/pkg/storage/fs/deleter.go
index 02128258..420ccc04 100644
--- a/pkg/storage/fs/deleter.go
+++ b/pkg/storage/fs/deleter.go
@@ -8,17 +8,17 @@ import (
 )
 
 // Delete removes a specific version of a module.
-func (v *storageImpl) Delete(ctx context.Context, module, version string) error {
+func (s *storageImpl) Delete(ctx context.Context, module, version string) error {
 	const op errors.Op = "fs.Delete"
 	ctx, span := observ.StartSpan(ctx, op.String())
 	defer span.End()
-	versionedPath := v.versionLocation(module, version)
-	exists, err := v.Exists(ctx, module, version)
+	versionedPath := s.versionLocation(module, version)
+	exists, err := s.Exists(ctx, module, version)
 	if err != nil {
 		return errors.E(op, err, errors.M(module), errors.V(version))
 	}
 	if !exists {
 		return errors.E(op, errors.M(module), errors.V(version), errors.KindNotFound)
 	}
-	return v.filesystem.RemoveAll(versionedPath)
+	return s.filesystem.RemoveAll(versionedPath)
 }
diff --git a/pkg/storage/fs/fs.go b/pkg/storage/fs/fs.go
index bfc3bbf8..8e0dd41a 100644
--- a/pkg/storage/fs/fs.go
+++ b/pkg/storage/fs/fs.go
@@ -21,17 +21,16 @@ func (s *storageImpl) moduleLocation(module string) string {
 
 func (s *storageImpl) versionLocation(module, version string) string {
 	return filepath.Join(s.moduleLocation(module), version)
-
 }
 
 // NewStorage returns a new ListerSaver implementation that stores
-// everything under rootDir
-// If the root directory does not exist an error is returned
+// everything under rootDir.
+// If the root directory does not exist an error is returned.
 func NewStorage(rootDir string, filesystem afero.Fs) (storage.Backend, error) {
 	const op errors.Op = "fs.NewStorage"
 	exists, err := afero.Exists(filesystem, rootDir)
 	if err != nil {
-		return nil, errors.E(op, fmt.Errorf("could not check if root directory `%s` exists: %s", rootDir, err))
+		return nil, errors.E(op, fmt.Errorf("could not check if root directory `%s` exists: %w", rootDir, err))
 	}
 	if !exists {
 		return nil, errors.E(op, fmt.Errorf("root directory `%s` does not exist", rootDir))
diff --git a/pkg/storage/fs/getter.go b/pkg/storage/fs/getter.go
index 513e2ea8..e6f26e91 100644
--- a/pkg/storage/fs/getter.go
+++ b/pkg/storage/fs/getter.go
@@ -11,12 +11,12 @@ import (
 	"github.com/spf13/afero"
 )
 
-func (v *storageImpl) Info(ctx context.Context, module, version string) ([]byte, error) {
+func (s *storageImpl) Info(ctx context.Context, module, version string) ([]byte, error) {
 	const op errors.Op = "fs.Info"
-	ctx, span := observ.StartSpan(ctx, op.String())
+	_, span := observ.StartSpan(ctx, op.String())
 	defer span.End()
-	versionedPath := v.versionLocation(module, version)
-	info, err := afero.ReadFile(v.filesystem, filepath.Join(versionedPath, version+".info"))
+	versionedPath := s.versionLocation(module, version)
+	info, err := afero.ReadFile(s.filesystem, filepath.Join(versionedPath, version+".info"))
 	if err != nil {
 		return nil, errors.E(op, errors.M(module), errors.V(version), errors.KindNotFound)
 	}
@@ -24,12 +24,12 @@ func (v *storageImpl) Info(ctx context.Context, module, version string) ([]byte,
 	return info, nil
 }
 
-func (v *storageImpl) GoMod(ctx context.Context, module, version string) ([]byte, error) {
+func (s *storageImpl) GoMod(ctx context.Context, module, version string) ([]byte, error) {
 	const op errors.Op = "fs.GoMod"
-	ctx, span := observ.StartSpan(ctx, op.String())
+	_, span := observ.StartSpan(ctx, op.String())
 	defer span.End()
-	versionedPath := v.versionLocation(module, version)
-	mod, err := afero.ReadFile(v.filesystem, filepath.Join(versionedPath, "go.mod"))
+	versionedPath := s.versionLocation(module, version)
+	mod, err := afero.ReadFile(s.filesystem, filepath.Join(versionedPath, "go.mod"))
 	if err != nil {
 		return nil, errors.E(op, errors.M(module), errors.V(version), errors.KindNotFound)
 	}
@@ -37,13 +37,13 @@ func (v *storageImpl) GoMod(ctx context.Context, module, version string) ([]byte
 	return mod, nil
 }
 
-func (v *storageImpl) Zip(ctx context.Context, module, version string) (storage.SizeReadCloser, error) {
+func (s *storageImpl) Zip(ctx context.Context, module, version string) (storage.SizeReadCloser, error) {
 	const op errors.Op = "fs.Zip"
-	ctx, span := observ.StartSpan(ctx, op.String())
+	_, span := observ.StartSpan(ctx, op.String())
 	defer span.End()
-	versionedPath := v.versionLocation(module, version)
+	versionedPath := s.versionLocation(module, version)
 
-	src, err := v.filesystem.OpenFile(filepath.Join(versionedPath, "source.zip"), os.O_RDONLY, 0666)
+	src, err := s.filesystem.OpenFile(filepath.Join(versionedPath, "source.zip"), os.O_RDONLY, 0o666)
 	if err != nil {
 		return nil, errors.E(op, errors.M(module), errors.V(version), errors.KindNotFound)
 	}
@@ -53,15 +53,3 @@ func (v *storageImpl) Zip(ctx context.Context, module, version string) (storage.
 	}
 	return storage.NewSizer(src, fi.Size()), nil
 }
-
-func (v *storageImpl) ZipSize(ctx context.Context, module, version string) (int64, error) {
-	const op errors.Op = "fs.ZipFileSize"
-	ctx, span := observ.StartSpan(ctx, op.String())
-	defer span.End()
-	versionedPath := v.versionLocation(module, version)
-	fi, err := v.filesystem.Stat(filepath.Join(versionedPath))
-	if err != nil {
-		return 0, errors.E(op, err, errors.M(module), errors.V(version), errors.KindNotFound)
-	}
-	return fi.Size(), nil
-}
diff --git a/pkg/storage/fs/lister.go b/pkg/storage/fs/lister.go
index 04458035..d4982a7f 100644
--- a/pkg/storage/fs/lister.go
+++ b/pkg/storage/fs/lister.go
@@ -11,12 +11,12 @@ import (
 	"golang.org/x/mod/semver"
 )
 
-func (l *storageImpl) List(ctx context.Context, module string) ([]string, error) {
+func (s *storageImpl) List(ctx context.Context, module string) ([]string, error) {
 	const op errors.Op = "fs.List"
-	ctx, span := observ.StartSpan(ctx, op.String())
+	_, span := observ.StartSpan(ctx, op.String())
 	defer span.End()
-	loc := l.moduleLocation(module)
-	fileInfos, err := afero.ReadDir(l.filesystem, loc)
+	loc := s.moduleLocation(module)
+	fileInfos, err := afero.ReadDir(s.filesystem, loc)
 	if err != nil {
 		if os.IsNotExist(err) {
 			return []string{}, nil
diff --git a/pkg/storage/fs/saver.go b/pkg/storage/fs/saver.go
index e146d807..bf826eee 100644
--- a/pkg/storage/fs/saver.go
+++ b/pkg/storage/fs/saver.go
@@ -13,37 +13,37 @@ import (
 
 func (s *storageImpl) Save(ctx context.Context, module, version string, mod []byte, zip io.Reader, info []byte) error {
 	const op errors.Op = "fs.Save"
-	ctx, span := observ.StartSpan(ctx, op.String())
+	_, span := observ.StartSpan(ctx, op.String())
 	defer span.End()
 	dir := s.versionLocation(module, version)
 
-	// NB: the process's umask is subtracted from the permissions below,
-	// so a umask of for example 0077 allows directories and files to be
-	// created with mode 0700 / 0600, i.e. not world- or group-readable
+	// NB: The process's umask is subtracted from the permissions below,
+	// so an umask of for example 0077 allows directories and files to be
+	// created with mode 0700 / 0600, i.e. not world- or group-readable.
 
-	// make the versioned directory to hold the go.mod and the zipfile
-	if err := s.filesystem.MkdirAll(dir, 0777); err != nil {
+	// Make the versioned directory to hold the go.mod and the zipfile.
+	if err := s.filesystem.MkdirAll(dir, 0o777); err != nil {
 		return errors.E(op, err, errors.M(module), errors.V(version))
 	}
 
-	// write the go.mod file
-	if err := afero.WriteFile(s.filesystem, filepath.Join(dir, "go.mod"), mod, 0666); err != nil {
+	// Write the go.mod file.
+	if err := afero.WriteFile(s.filesystem, filepath.Join(dir, "go.mod"), mod, 0o666); err != nil {
 		return errors.E(op, err, errors.M(module), errors.V(version))
 	}
 
-	// write the zipfile
-	f, err := s.filesystem.OpenFile(filepath.Join(dir, "source.zip"), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
+	// Write the zipfile.
+	f, err := s.filesystem.OpenFile(filepath.Join(dir, "source.zip"), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0o666)
 	if err != nil {
 		return errors.E(op, err, errors.M(module), errors.V(version))
 	}
-	defer f.Close()
+	defer func() { _ = f.Close() }()
 	_, err = io.Copy(f, zip)
 	if err != nil {
 		return errors.E(op, err, errors.M(module), errors.V(version))
 	}
 
 	// write the info file
-	err = afero.WriteFile(s.filesystem, filepath.Join(dir, version+".info"), info, 0666)
+	err = afero.WriteFile(s.filesystem, filepath.Join(dir, version+".info"), info, 0o666)
 	if err != nil {
 		return errors.E(op, err)
 	}
diff --git a/pkg/storage/gcp/cataloger.go b/pkg/storage/gcp/cataloger.go
index 7de52596..32868bd8 100644
--- a/pkg/storage/gcp/cataloger.go
+++ b/pkg/storage/gcp/cataloger.go
@@ -14,7 +14,7 @@ import (
 )
 
 // Catalog implements the (./pkg/storage).Catalog interface
-// It returns a list of versions, if any, for a given module
+// It returns a list of versions, if any, for a given module.
 func (s *Storage) Catalog(ctx context.Context, token string, pageSize int) ([]paths.AllPathParams, string, error) {
 	const op errors.Op = "gcp.Catalog"
 	ctx, span := observ.StartSpan(ctx, op.String())
diff --git a/pkg/storage/gcp/checker.go b/pkg/storage/gcp/checker.go
index 2e8bf476..259a85ba 100644
--- a/pkg/storage/gcp/checker.go
+++ b/pkg/storage/gcp/checker.go
@@ -11,7 +11,7 @@ import (
 )
 
 // Exists implements the (./pkg/storage).Checker interface
-// returning true if the module at version exists in storage
+// returning true if the module at version exists in storage.
 func (s *Storage) Exists(ctx context.Context, module, version string) (bool, error) {
 	const op errors.Op = "gcp.Exists"
 	ctx, span := observ.StartSpan(ctx, op.String())
@@ -21,7 +21,7 @@ func (s *Storage) Exists(ctx context.Context, module, version string) (bool, err
 	var count int
 	for {
 		attrs, err := it.Next()
-		if err == iterator.Done {
+		if errors.IsErr(err, iterator.Done) {
 			break
 		}
 		if err != nil {
diff --git a/pkg/storage/gcp/gcp.go b/pkg/storage/gcp/gcp.go
index e7429845..a15d25d1 100644
--- a/pkg/storage/gcp/gcp.go
+++ b/pkg/storage/gcp/gcp.go
@@ -13,7 +13,7 @@ import (
 	"google.golang.org/api/option"
 )
 
-// Storage implements the (./pkg/storage).Backend interface
+// Storage implements the (./pkg/storage).Backend interface.
 type Storage struct {
 	bucket  *storage.BucketHandle
 	timeout time.Duration
@@ -34,8 +34,8 @@ func New(ctx context.Context, gcpConf *config.GCPConfig, timeout time.Duration)
 		return nil, errors.E(op, err)
 	}
 
-	if _, err := s.bucket.Attrs(ctx); err != nil {
-		if err == storage.ErrBucketNotExist {
+	if _, err = s.bucket.Attrs(ctx); err != nil {
+		if errors.IsErr(err, storage.ErrBucketNotExist) {
 			return nil, errors.E(op, "You must manually create a storage bucket for Athens, see https://cloud.google.com/storage/docs/creating-buckets#storage-create-bucket-console")
 		}
 		return nil, errors.E(op, err)
@@ -48,21 +48,21 @@ func New(ctx context.Context, gcpConf *config.GCPConfig, timeout time.Duration)
 // this is so that the unit tests can use this to create their own short-lived buckets.
 func newClient(ctx context.Context, gcpConf *config.GCPConfig, timeout time.Duration) (*Storage, error) {
 	const op errors.Op = "gcp.newClient"
-	opts := []option.ClientOption{}
+	var opts []option.ClientOption
 	if gcpConf.JSONKey != "" {
 		key, err := base64.StdEncoding.DecodeString(gcpConf.JSONKey)
 		if err != nil {
-			return nil, errors.E(op, fmt.Errorf("could not decode base64 json key: %v", err))
+			return nil, errors.E(op, fmt.Errorf("could not decode base64 json key: %w", err))
 		}
 		creds, err := google.CredentialsFromJSON(ctx, key, storage.ScopeReadWrite)
 		if err != nil {
-			return nil, errors.E(op, fmt.Errorf("could not get GCS credentials: %v", err))
+			return nil, errors.E(op, fmt.Errorf("could not get GCS credentials: %w", err))
 		}
 		opts = append(opts, option.WithCredentials(creds))
 	}
 	s, err := storage.NewClient(ctx, opts...)
 	if err != nil {
-		return nil, errors.E(op, fmt.Errorf("could not create new storage client: %s", err))
+		return nil, errors.E(op, fmt.Errorf("could not create new storage client: %w", err))
 	}
 
 	return &Storage{
diff --git a/pkg/storage/gcp/getter.go b/pkg/storage/gcp/getter.go
index b9abd7ef..3edea951 100644
--- a/pkg/storage/gcp/getter.go
+++ b/pkg/storage/gcp/getter.go
@@ -12,7 +12,7 @@ import (
 	pkgstorage "github.com/gomods/athens/pkg/storage"
 )
 
-// Info implements Getter
+// Info implements Getter.
 func (s *Storage) Info(ctx context.Context, module, version string) ([]byte, error) {
 	const op errors.Op = "gcp.Info"
 	ctx, span := observ.StartSpan(ctx, op.String())
@@ -22,14 +22,14 @@ func (s *Storage) Info(ctx context.Context, module, version string) ([]byte, err
 		return nil, errors.E(op, err, getErrorKind(err), errors.M(module), errors.V(version))
 	}
 	infoBytes, err := io.ReadAll(infoReader)
-	infoReader.Close()
+	_ = infoReader.Close()
 	if err != nil {
 		return nil, errors.E(op, err, errors.M(module), errors.V(version))
 	}
 	return infoBytes, nil
 }
 
-// GoMod implements Getter
+// GoMod implements Getter.
 func (s *Storage) GoMod(ctx context.Context, module, version string) ([]byte, error) {
 	const op errors.Op = "gcp.GoMod"
 	ctx, span := observ.StartSpan(ctx, op.String())
@@ -39,15 +39,15 @@ func (s *Storage) GoMod(ctx context.Context, module, version string) ([]byte, er
 		return nil, errors.E(op, err, getErrorKind(err), errors.M(module), errors.V(version))
 	}
 	modBytes, err := io.ReadAll(modReader)
-	modReader.Close()
+	_ = modReader.Close()
 	if err != nil {
-		return nil, errors.E(op, fmt.Errorf("could not get new reader for mod file: %s", err), errors.M(module), errors.V(version))
+		return nil, errors.E(op, fmt.Errorf("could not get new reader for mod file: %w", err), errors.M(module), errors.V(version))
 	}
 
 	return modBytes, nil
 }
 
-// Zip implements Getter
+// Zip implements Getter.
 func (s *Storage) Zip(ctx context.Context, module, version string) (pkgstorage.SizeReadCloser, error) {
 	const op errors.Op = "gcp.Zip"
 	ctx, span := observ.StartSpan(ctx, op.String())
@@ -56,11 +56,11 @@ func (s *Storage) Zip(ctx context.Context, module, version string) (pkgstorage.S
 	if err != nil {
 		return nil, errors.E(op, err, getErrorKind(err), errors.M(module), errors.V(version))
 	}
-	return pkgstorage.NewSizer(zipReader, zipReader.Size()), nil
+	return pkgstorage.NewSizer(zipReader, zipReader.Attrs.Size), nil
 }
 
 func getErrorKind(err error) int {
-	if err == storage.ErrObjectNotExist {
+	if errors.IsErr(err, storage.ErrObjectNotExist) {
 		return errors.KindNotFound
 	}
 	return errors.KindUnexpected
diff --git a/pkg/storage/gcp/lister.go b/pkg/storage/gcp/lister.go
index fb681037..97f2437b 100644
--- a/pkg/storage/gcp/lister.go
+++ b/pkg/storage/gcp/lister.go
@@ -10,8 +10,8 @@ import (
 	"google.golang.org/api/iterator"
 )
 
-// List implements the (./pkg/storage).Lister interface
-// It returns a list of versions, if any, for a given module
+// List implements the (./pkg/storage).Lister interface.
+// It returns a list of versions, if any, for a given module.
 func (s *Storage) List(ctx context.Context, module string) ([]string, error) {
 	const op errors.Op = "gcp.List"
 	ctx, span := observ.StartSpan(ctx, op.String())
@@ -22,7 +22,7 @@ func (s *Storage) List(ctx context.Context, module string) ([]string, error) {
 	paths := []string{}
 	for {
 		attrs, err := it.Next()
-		if err == iterator.Done {
+		if errors.IsErr(err, iterator.Done) {
 			break
 		}
 		if err != nil {
diff --git a/pkg/storage/gcp/saver.go b/pkg/storage/gcp/saver.go
index d66a559a..4298aaa1 100644
--- a/pkg/storage/gcp/saver.go
+++ b/pkg/storage/gcp/saver.go
@@ -53,15 +53,15 @@ func (s *Storage) upload(ctx context.Context, path string, stream io.Reader) err
 	// Once we support private storage buckets this may need refactoring
 	// unless there is a way to set the default perms in the project.
 	if _, err := io.Copy(wc, stream); err != nil {
-		wc.Close()
+		_ = wc.Close()
 		return err
 	}
 
 	err := wc.Close()
 	if err != nil {
 		kind := errors.KindBadRequest
-		apiErr, ok := err.(*googleapi.Error)
-		if ok && apiErr.Code == 412 {
+		apiErr := &googleapi.Error{}
+		if errors.AsErr(err, &apiErr) && apiErr.Code == 412 {
 			kind = errors.KindAlreadyExists
 		}
 		return errors.E(op, err, kind)
diff --git a/pkg/storage/getter.go b/pkg/storage/getter.go
index d26eb38b..e04531b8 100644
--- a/pkg/storage/getter.go
+++ b/pkg/storage/getter.go
@@ -5,7 +5,7 @@ import (
 	"io"
 )
 
-// Getter gets module metadata and its source from underlying storage
+// Getter gets module metadata and its source from underlying storage.
 type Getter interface {
 	Info(ctx context.Context, module, vsn string) ([]byte, error)
 	GoMod(ctx context.Context, module, vsn string) ([]byte, error)
@@ -14,14 +14,14 @@ type Getter interface {
 
 // SizeReadCloser extends io.ReadCloser
 // with a Size() method that tells you the
-// length of the io.ReadCloser if read in full
+// length of the io.ReadCloser if read in full.
 type SizeReadCloser interface {
 	io.ReadCloser
 	Size() int64
 }
 
 // NewSizer is a helper wrapper to return an implementation
-// of ReadCloserSizer
+// of ReadCloserSizer.
 func NewSizer(rc io.ReadCloser, size int64) SizeReadCloser {
 	return &sizeReadCloser{rc, size}
 }
diff --git a/pkg/storage/lister.go b/pkg/storage/lister.go
index 30135b5b..175d59f3 100644
--- a/pkg/storage/lister.go
+++ b/pkg/storage/lister.go
@@ -2,7 +2,7 @@ package storage
 
 import "context"
 
-// Lister is the interface that lists versions of a specific baseURL & module
+// Lister is the interface that lists versions of a specific baseURL & module.
 type Lister interface {
 	// List gets all the versions for the given baseURL & module.
 	// It returns ErrNotFound if the module isn't found
diff --git a/pkg/storage/mem/mem.go b/pkg/storage/mem/mem.go
index 8644edd1..13458c69 100644
--- a/pkg/storage/mem/mem.go
+++ b/pkg/storage/mem/mem.go
@@ -9,19 +9,19 @@ import (
 	"github.com/spf13/afero"
 )
 
-// NewStorage creates new in-memory storage using the afero.NewMemMapFs() in memory file system
+// NewStorage creates new in-memory storage using the afero.NewMemMapFs() in memory file system.
 func NewStorage() (storage.Backend, error) {
 	const op errors.Op = "mem.NewStorage"
 
 	memFs := afero.NewMemMapFs()
 	tmpDir, err := afero.TempDir(memFs, "", "")
 	if err != nil {
-		return nil, errors.E(op, fmt.Errorf("could not create temp dir for 'In Memory' storage (%s)", err))
+		return nil, errors.E(op, fmt.Errorf("could not create temp dir for 'In Memory' storage: %w", err))
 	}
 
 	memStorage, err := fs.NewStorage(tmpDir, memFs)
 	if err != nil {
-		return nil, errors.E(op, fmt.Errorf("could not create storage from memory fs (%s)", err))
+		return nil, errors.E(op, fmt.Errorf("could not create storage from memory fs: %w", err))
 	}
 	return memStorage, nil
 }
diff --git a/pkg/storage/minio/cataloger.go b/pkg/storage/minio/cataloger.go
index 56ccb48b..4cfbd226 100644
--- a/pkg/storage/minio/cataloger.go
+++ b/pkg/storage/minio/cataloger.go
@@ -11,11 +11,11 @@ import (
 	"github.com/minio/minio-go/v6"
 )
 
-// Catalog implements the (./pkg/storage).Cataloger interface
-// It returns a list of modules and versions contained in the storage
+// Catalog implements the (./pkg/storage).Cataloger interface.
+// It returns a list of modules and versions contained in the storage.
 func (s *storageImpl) Catalog(ctx context.Context, token string, pageSize int) ([]paths.AllPathParams, string, error) {
 	const op errors.Op = "minio.Catalog"
-	ctx, span := observ.StartSpan(ctx, op.String())
+	_, span := observ.StartSpan(ctx, op.String())
 	defer span.End()
 	res := make([]paths.AllPathParams, 0)
 	count := pageSize
@@ -50,7 +50,7 @@ func fetchModsAndVersions(objects []minio.ObjectInfo, elementsNum int) ([]paths.
 			continue
 		}
 
-		p, err := parseMinioKey(&o)
+		p, err := parseMinioKey(o)
 		if err != nil {
 			continue
 		}
@@ -66,7 +66,7 @@ func fetchModsAndVersions(objects []minio.ObjectInfo, elementsNum int) ([]paths.
 	return res, lastKey
 }
 
-func parseMinioKey(o *minio.ObjectInfo) (paths.AllPathParams, error) {
+func parseMinioKey(o minio.ObjectInfo) (paths.AllPathParams, error) {
 	const op errors.Op = "minio.parseMinioKey"
 
 	_, m, v := extractKey(o.Key)
diff --git a/pkg/storage/minio/checker.go b/pkg/storage/minio/checker.go
index c555a248..6fc6d6ea 100644
--- a/pkg/storage/minio/checker.go
+++ b/pkg/storage/minio/checker.go
@@ -8,21 +8,17 @@ import (
 	"github.com/gomods/athens/pkg/observ"
 )
 
-const (
-	minioErrorCodeNoSuchKey = "NoSuchKey"
-)
-
-func (v *storageImpl) Exists(ctx context.Context, module, version string) (bool, error) {
+func (s *storageImpl) Exists(ctx context.Context, module, version string) (bool, error) {
 	const op errors.Op = "minio.Exists"
-	ctx, span := observ.StartSpan(ctx, op.String())
+	_, span := observ.StartSpan(ctx, op.String())
 	defer span.End()
-	versionedPath := v.versionLocation(module, version)
+	versionedPath := s.versionLocation(module, version)
 	modPath := fmt.Sprintf("%s/go.mod", versionedPath)
 	infoPath := fmt.Sprintf("%s/%s.info", versionedPath, version)
 	zipPath := fmt.Sprintf("%s/source.zip", versionedPath)
 
 	var count int
-	objectCh, err := v.minioCore.ListObjectsV2(v.bucketName, versionedPath, "", false, "", 0, "")
+	objectCh, err := s.minioCore.ListObjectsV2(s.bucketName, versionedPath, "", false, "", 0, "")
 	if err != nil {
 		return false, errors.E(op, err, errors.M(module), errors.V(version))
 	}
diff --git a/pkg/storage/minio/deleter.go b/pkg/storage/minio/deleter.go
index 2275d25e..d261bdd3 100644
--- a/pkg/storage/minio/deleter.go
+++ b/pkg/storage/minio/deleter.go
@@ -8,11 +8,11 @@ import (
 	"github.com/gomods/athens/pkg/observ"
 )
 
-func (v *storageImpl) Delete(ctx context.Context, module, version string) error {
+func (s *storageImpl) Delete(ctx context.Context, module, version string) error {
 	const op errors.Op = "minio.Delete"
 	ctx, span := observ.StartSpan(ctx, op.String())
 	defer span.End()
-	exists, err := v.Exists(ctx, module, version)
+	exists, err := s.Exists(ctx, module, version)
 	if err != nil {
 		return errors.E(op, err, errors.M(module), errors.V(version))
 	}
@@ -21,20 +21,20 @@ func (v *storageImpl) Delete(ctx context.Context, module, version string) error
 		return errors.E(op, errors.M(module), errors.V(version), errors.KindNotFound)
 	}
 
-	versionedPath := v.versionLocation(module, version)
+	versionedPath := s.versionLocation(module, version)
 
 	modPath := fmt.Sprintf("%s/go.mod", versionedPath)
-	if err := v.minioClient.RemoveObject(v.bucketName, modPath); err != nil {
+	if err := s.minioClient.RemoveObject(s.bucketName, modPath); err != nil {
 		return errors.E(op, err, errors.M(module), errors.V(version))
 	}
 
 	zipPath := fmt.Sprintf("%s/source.zip", versionedPath)
-	if err := v.minioClient.RemoveObject(v.bucketName, zipPath); err != nil {
+	if err := s.minioClient.RemoveObject(s.bucketName, zipPath); err != nil {
 		return errors.E(op, err, errors.M(module), errors.V(version))
 	}
 
 	infoPath := fmt.Sprintf("%s/%s.info", versionedPath, version)
-	err = v.minioClient.RemoveObject(v.bucketName, infoPath)
+	err = s.minioClient.RemoveObject(s.bucketName, infoPath)
 	if err != nil {
 		return errors.E(op, err, errors.M(module), errors.V(version))
 	}
diff --git a/pkg/storage/minio/getter.go b/pkg/storage/minio/getter.go
index dd18891e..ebdf8bd5 100644
--- a/pkg/storage/minio/getter.go
+++ b/pkg/storage/minio/getter.go
@@ -12,16 +12,16 @@ import (
 	minio "github.com/minio/minio-go/v6"
 )
 
-func (v *storageImpl) Info(ctx context.Context, module, vsn string) ([]byte, error) {
+func (s *storageImpl) Info(ctx context.Context, module, vsn string) ([]byte, error) {
 	const op errors.Op = "minio.Info"
-	ctx, span := observ.StartSpan(ctx, op.String())
+	_, span := observ.StartSpan(ctx, op.String())
 	defer span.End()
-	infoPath := fmt.Sprintf("%s/%s.info", v.versionLocation(module, vsn), vsn)
-	infoReader, err := v.minioClient.GetObject(v.bucketName, infoPath, minio.GetObjectOptions{})
+	infoPath := fmt.Sprintf("%s/%s.info", s.versionLocation(module, vsn), vsn)
+	infoReader, err := s.minioClient.GetObject(s.bucketName, infoPath, minio.GetObjectOptions{})
 	if err != nil {
 		return nil, errors.E(op, err)
 	}
-	defer infoReader.Close()
+	defer func() { _ = infoReader.Close() }()
 	info, err := io.ReadAll(infoReader)
 	if err != nil {
 		return nil, transformNotFoundErr(op, module, vsn, err)
@@ -30,16 +30,16 @@ func (v *storageImpl) Info(ctx context.Context, module, vsn string) ([]byte, err
 	return info, nil
 }
 
-func (v *storageImpl) GoMod(ctx context.Context, module, vsn string) ([]byte, error) {
+func (s *storageImpl) GoMod(ctx context.Context, module, vsn string) ([]byte, error) {
 	const op errors.Op = "minio.GoMod"
-	ctx, span := observ.StartSpan(ctx, op.String())
+	_, span := observ.StartSpan(ctx, op.String())
 	defer span.End()
-	modPath := fmt.Sprintf("%s/go.mod", v.versionLocation(module, vsn))
-	modReader, err := v.minioClient.GetObject(v.bucketName, modPath, minio.GetObjectOptions{})
+	modPath := fmt.Sprintf("%s/go.mod", s.versionLocation(module, vsn))
+	modReader, err := s.minioClient.GetObject(s.bucketName, modPath, minio.GetObjectOptions{})
 	if err != nil {
 		return nil, errors.E(op, err)
 	}
-	defer modReader.Close()
+	defer func() { _ = modReader.Close() }()
 	mod, err := io.ReadAll(modReader)
 	if err != nil {
 		return nil, transformNotFoundErr(op, module, vsn, err)
@@ -48,31 +48,32 @@ func (v *storageImpl) GoMod(ctx context.Context, module, vsn string) ([]byte, er
 	return mod, nil
 }
 
-func (v *storageImpl) Zip(ctx context.Context, module, vsn string) (storage.SizeReadCloser, error) {
+func (s *storageImpl) Zip(ctx context.Context, module, vsn string) (storage.SizeReadCloser, error) {
 	const op errors.Op = "minio.Zip"
-	ctx, span := observ.StartSpan(ctx, op.String())
+	_, span := observ.StartSpan(ctx, op.String())
 	defer span.End()
 
-	zipPath := fmt.Sprintf("%s/source.zip", v.versionLocation(module, vsn))
-	_, err := v.minioClient.StatObject(v.bucketName, zipPath, minio.StatObjectOptions{})
+	zipPath := fmt.Sprintf("%s/source.zip", s.versionLocation(module, vsn))
+	_, err := s.minioClient.StatObject(s.bucketName, zipPath, minio.StatObjectOptions{})
 	if err != nil {
 		return nil, errors.E(op, err, errors.KindNotFound, errors.M(module), errors.V(vsn))
 	}
 
-	zipReader, err := v.minioClient.GetObject(v.bucketName, zipPath, minio.GetObjectOptions{})
+	zipReader, err := s.minioClient.GetObject(s.bucketName, zipPath, minio.GetObjectOptions{})
 	if err != nil {
 		return nil, errors.E(op, err)
 	}
 	oi, err := zipReader.Stat()
 	if err != nil {
-		zipReader.Close()
+		_ = zipReader.Close()
 		return nil, errors.E(op, err)
 	}
 	return storage.NewSizer(zipReader, oi.Size), nil
 }
 
 func transformNotFoundErr(op errors.Op, module, version string, err error) error {
-	if eresp, ok := err.(minio.ErrorResponse); ok {
+	var eresp minio.ErrorResponse
+	if errors.AsErr(err, &eresp) {
 		if eresp.StatusCode == http.StatusNotFound {
 			return errors.E(op, errors.M(module), errors.V(version), errors.KindNotFound)
 		}
diff --git a/pkg/storage/minio/key.go b/pkg/storage/minio/key.go
index 2af230ab..45327980 100644
--- a/pkg/storage/minio/key.go
+++ b/pkg/storage/minio/key.go
@@ -5,7 +5,7 @@ import (
 	"strings"
 )
 
-func extractKey(objectKey string) (key string, module string, version string) {
+func extractKey(objectKey string) (key, module, version string) {
 	var err error
 	key, err = url.PathUnescape(objectKey)
 	if err != nil {
@@ -14,8 +14,8 @@ func extractKey(objectKey string) (key string, module string, version string) {
 
 	parts := strings.Split(key, "/")
 	version = parts[len(parts)-2]
-	module = strings.Replace(key, version, "", -2)
-	module = strings.Replace(module, "//.info", "", -1)
+	module = strings.ReplaceAll(key, version, "")
+	module = strings.ReplaceAll(module, "//.info", "")
 
 	return key, module, version
 }
diff --git a/pkg/storage/minio/lister.go b/pkg/storage/minio/lister.go
index 6cb034aa..c656e6c3 100644
--- a/pkg/storage/minio/lister.go
+++ b/pkg/storage/minio/lister.go
@@ -9,26 +9,25 @@ import (
 	"github.com/gomods/athens/pkg/observ"
 )
 
-func (l *storageImpl) List(ctx context.Context, module string) ([]string, error) {
+func (s *storageImpl) List(ctx context.Context, module string) ([]string, error) {
 	const op errors.Op = "minio.List"
-	ctx, span := observ.StartSpan(ctx, op.String())
+	_, span := observ.StartSpan(ctx, op.String())
 	defer span.End()
 	doneCh := make(chan struct{})
 	defer close(doneCh)
 	searchPrefix := module + "/"
-	objectCh, err := l.minioCore.ListObjectsV2(l.bucketName, searchPrefix, "", false, "", 0, "")
-
+	objectCh, err := s.minioCore.ListObjectsV2(s.bucketName, searchPrefix, "", false, "", 0, "")
 	if err != nil {
 		return nil, errors.E(op, err, errors.M(module))
 	}
-	ret := []string{}
+	var ret []string
 	for _, object := range objectCh.Contents {
 		if object.Err != nil {
 			return nil, errors.E(op, object.Err, errors.M(module))
 		}
 
 		key, _, ver := extractKey(object.Key)
-		goModKey := fmt.Sprintf("%s/go.mod", l.versionLocation(module, ver))
+		goModKey := fmt.Sprintf("%s/go.mod", s.versionLocation(module, ver))
 		if goModKey == key {
 			ret = append(ret, ver)
 		}
diff --git a/pkg/storage/minio/minio.go b/pkg/storage/minio/minio.go
index 13d2baeb..b105aea1 100644
--- a/pkg/storage/minio/minio.go
+++ b/pkg/storage/minio/minio.go
@@ -21,7 +21,7 @@ func (s *storageImpl) versionLocation(module, version string) string {
 }
 
 // NewStorage returns a connected Minio or DigitalOcean Spaces storage
-// that implements storage.Backend
+// that implements storage.Backend.
 func NewStorage(conf *config.MinioConfig, timeout time.Duration) (storage.Backend, error) {
 	const op errors.Op = "minio.NewStorage"
 	endpoint := conf.Endpoint
diff --git a/pkg/storage/minio/saver.go b/pkg/storage/minio/saver.go
index 5fa1e7df..864b4c18 100644
--- a/pkg/storage/minio/saver.go
+++ b/pkg/storage/minio/saver.go
@@ -15,7 +15,7 @@ import (
 
 func (s *storageImpl) Save(ctx context.Context, module, vsn string, mod []byte, zip io.Reader, info []byte) error {
 	const op errors.Op = "storage.minio.Save"
-	ctx, span := observ.StartSpan(ctx, op.String())
+	_, span := observ.StartSpan(ctx, op.String())
 	defer span.End()
 	dir := s.versionLocation(module, vsn)
 	modFileName := dir + "/" + "go.mod"
diff --git a/pkg/storage/module/delete.go b/pkg/storage/module/delete.go
index 126eebcf..6bf54d66 100644
--- a/pkg/storage/module/delete.go
+++ b/pkg/storage/module/delete.go
@@ -7,26 +7,26 @@ import (
 
 	"github.com/gomods/athens/pkg/config"
 	"github.com/gomods/athens/pkg/errors"
-	multierror "github.com/hashicorp/go-multierror"
+	"github.com/hashicorp/go-multierror"
 )
 
-// Deleter takes a path to a file and deletes it from the blob store
+// Deleter takes a path to a file and deletes it from the blob store.
 type Deleter func(ctx context.Context, path string) error
 
 // Delete deletes .info, .mod and .zip files from the blob store in parallel.
-// Returns multierror containing errors from all deletes and timeouts
-func Delete(ctx context.Context, module, version string, delete Deleter, timeout time.Duration) error {
+// Returns multierror containing errors from all deletes and timeouts.
+func Delete(ctx context.Context, module, version string, del Deleter, timeout time.Duration) error {
 	const op errors.Op = "module.Delete"
 	tctx, cancel := context.WithTimeout(ctx, timeout)
 	defer cancel()
 
-	del := func(ext string) <-chan error {
+	delFn := func(ext string) <-chan error {
 		ec := make(chan error)
 
 		go func() {
 			defer close(ec)
 			p := config.PackageVersionedName(module, version, ext)
-			ec <- delete(tctx, p)
+			ec <- del(tctx, p)
 		}()
 		return ec
 	}
@@ -34,10 +34,10 @@ func Delete(ctx context.Context, module, version string, delete Deleter, timeout
 	errChan := make(chan error, numFiles)
 	delOrAbort := func(ext string) {
 		select {
-		case err := <-del(ext):
+		case err := <-delFn(ext):
 			errChan <- err
 		case <-tctx.Done():
-			errChan <- fmt.Errorf("deleting %s.%s.%s failed: %s", module, version, ext, tctx.Err())
+			errChan <- fmt.Errorf("deleting %s.%s.%s failed: %w", module, version, ext, tctx.Err())
 		}
 	}
 
diff --git a/pkg/storage/module/upload.go b/pkg/storage/module/upload.go
index 5395a007..5bd4a1e9 100644
--- a/pkg/storage/module/upload.go
+++ b/pkg/storage/module/upload.go
@@ -13,11 +13,11 @@ import (
 
 const numFiles = 3
 
-// Uploader takes a stream and saves it to the blob store under a given path
+// Uploader takes a stream and saves it to the blob store under a given path.
 type Uploader func(ctx context.Context, path, contentType string, stream io.Reader) error
 
 // Upload saves .info, .mod and .zip files to the blob store in parallel.
-// Returns multierror containing errors from all uploads and timeouts
+// Returns multierror containing errors from all uploads and timeouts.
 func Upload(ctx context.Context, module, version string, info, mod, zip io.Reader, uploader Uploader, timeout time.Duration) error {
 	const op errors.Op = "module.Upload"
 	tctx, cancel := context.WithTimeout(ctx, timeout)
@@ -40,7 +40,7 @@ func Upload(ctx context.Context, module, version string, info, mod, zip io.Reade
 		case err := <-save(ext, contentType, stream):
 			errChan <- err
 		case <-tctx.Done():
-			errChan <- fmt.Errorf("uploading %s.%s.%s failed: %s", module, version, ext, tctx.Err())
+			errChan <- fmt.Errorf("uploading %s.%s.%s failed: %w", module, version, ext, tctx.Err())
 		}
 	}
 	go saveOrAbort("info", "application/json", info)
diff --git a/pkg/storage/mongo/cataloger.go b/pkg/storage/mongo/cataloger.go
index 6430202f..f409fa99 100644
--- a/pkg/storage/mongo/cataloger.go
+++ b/pkg/storage/mongo/cataloger.go
@@ -2,6 +2,7 @@ package mongo
 
 import (
 	"context"
+
 	"github.com/gomods/athens/pkg/errors"
 	"github.com/gomods/athens/pkg/paths"
 	"github.com/gomods/athens/pkg/storage"
@@ -11,8 +12,8 @@ import (
 	"go.mongodb.org/mongo-driver/mongo/options"
 )
 
-// Catalog implements the (./pkg/storage).Cataloger interface
-// It returns a list of modules and versions contained in the storage
+// Catalog implements the (./pkg/storage).Cataloger interface.
+// It returns a list of modules and versions contained in the storage.
 func (s *ModuleStore) Catalog(ctx context.Context, token string, pageSize int) ([]paths.AllPathParams, string, error) {
 	const op errors.Op = "mongo.Catalog"
 	q := bson.M{}
@@ -33,7 +34,6 @@ func (s *ModuleStore) Catalog(ctx context.Context, token string, pageSize int) (
 	modules := make([]storage.Module, 0)
 	findOptions := options.Find().SetProjection(projection).SetSort(sort).SetLimit(int64(pageSize))
 	cursor, err := c.Find(tctx, q, findOptions)
-
 	if err != nil {
 		return nil, "", errors.E(op, err)
 	}
@@ -53,13 +53,13 @@ func (s *ModuleStore) Catalog(ctx context.Context, token string, pageSize int) (
 		return nil, "", nil
 	}
 
-	var versions = make([]paths.AllPathParams, len(modules))
+	versions := make([]paths.AllPathParams, len(modules))
 	for i := range modules {
 		versions[i].Module = modules[i].Module
 		versions[i].Version = modules[i].Version
 	}
 
-	var next = modules[len(modules)-1].ID.Hex()
+	next := modules[len(modules)-1].ID.Hex()
 	if len(modules) < pageSize {
 		return versions, "", nil
 	}
diff --git a/pkg/storage/mongo/checker.go b/pkg/storage/mongo/checker.go
index 27fe28b1..3fd45f2f 100644
--- a/pkg/storage/mongo/checker.go
+++ b/pkg/storage/mongo/checker.go
@@ -8,7 +8,7 @@ import (
 	"go.mongodb.org/mongo-driver/bson"
 )
 
-// Exists checks for a specific version of a module
+// Exists checks for a specific version of a module.
 func (s *ModuleStore) Exists(ctx context.Context, module, vsn string) (bool, error) {
 	var op errors.Op = "mongo.Exists"
 	ctx, span := observ.StartSpan(ctx, op.String())
diff --git a/pkg/storage/mongo/deleter.go b/pkg/storage/mongo/deleter.go
index d7fd7dba..8f25b235 100644
--- a/pkg/storage/mongo/deleter.go
+++ b/pkg/storage/mongo/deleter.go
@@ -11,7 +11,7 @@ import (
 	"go.mongodb.org/mongo-driver/x/bsonx"
 )
 
-// Delete removes a specific version of a module
+// Delete removes a specific version of a module.
 func (s *ModuleStore) Delete(ctx context.Context, module, version string) error {
 	const op errors.Op = "mongo.Delete"
 	ctx, span := observ.StartSpan(ctx, op.String())
@@ -40,11 +40,11 @@ func (s *ModuleStore) Delete(ctx context.Context, module, version string) error
 
 	var x bsonx.Doc
 	for cursor.Next(ctx) {
-		cursor.Decode(&x)
+		_ = cursor.Decode(&x)
 	}
 	if err = bucket.Delete(x.Lookup("_id").ObjectID()); err != nil {
 		kind := errors.KindUnexpected
-		if err == gridfs.ErrFileNotFound {
+		if errors.IsErr(err, gridfs.ErrFileNotFound) {
 			kind = errors.KindNotFound
 		}
 		return errors.E(op, err, kind, errors.M(module), errors.V(version))
diff --git a/pkg/storage/mongo/getter.go b/pkg/storage/mongo/getter.go
index 94762945..11821dec 100644
--- a/pkg/storage/mongo/getter.go
+++ b/pkg/storage/mongo/getter.go
@@ -13,14 +13,13 @@ import (
 	"go.mongodb.org/mongo-driver/x/bsonx"
 )
 
-// Info implements storage.Getter
+// Info implements storage.Getter.
 func (s *ModuleStore) Info(ctx context.Context, module, vsn string) ([]byte, error) {
 	const op errors.Op = "mongo.Info"
 	ctx, span := observ.StartSpan(ctx, op.String())
 	defer span.End()
 
 	result, err := query(ctx, s, module, vsn)
-
 	if err != nil {
 		return nil, errors.E(op, err)
 	}
@@ -28,14 +27,13 @@ func (s *ModuleStore) Info(ctx context.Context, module, vsn string) ([]byte, err
 	return result.Info, nil
 }
 
-// GoMod implements storage.Getter
+// GoMod implements storage.Getter.
 func (s *ModuleStore) GoMod(ctx context.Context, module, vsn string) ([]byte, error) {
 	const op errors.Op = "mongo.GoMod"
 	ctx, span := observ.StartSpan(ctx, op.String())
 	defer span.End()
 
 	result, err := query(ctx, s, module, vsn)
-
 	if err != nil {
 		return nil, errors.E(op, err)
 	}
@@ -43,7 +41,7 @@ func (s *ModuleStore) GoMod(ctx context.Context, module, vsn string) ([]byte, er
 	return result.Mod, nil
 }
 
-// Zip implements storage.Getter
+// Zip implements storage.Getter.
 func (s *ModuleStore) Zip(ctx context.Context, module, vsn string) (storage.SizeReadCloser, error) {
 	const op errors.Op = "mongo.Zip"
 	ctx, span := observ.StartSpan(ctx, op.String())
@@ -59,7 +57,7 @@ func (s *ModuleStore) Zip(ctx context.Context, module, vsn string) (storage.Size
 	dStream, err := bucket.OpenDownloadStreamByName(zipName, options.GridFSName())
 	if err != nil {
 		kind := errors.KindUnexpected
-		if err == gridfs.ErrFileNotFound {
+		if errors.IsErr(err, gridfs.ErrFileNotFound) {
 			kind = errors.KindNotFound
 		}
 		return nil, errors.E(op, err, kind, errors.M(module), errors.V(vsn))
@@ -79,7 +77,7 @@ func (s *ModuleStore) Zip(ctx context.Context, module, vsn string) (storage.Size
 	return storage.NewSizer(dStream, size), nil
 }
 
-// Query connects to and queries storage module
+// Query connects to and queries storage module.
 func query(ctx context.Context, s *ModuleStore, module, vsn string) (*storage.Module, error) {
 	const op errors.Op = "mongo.query"
 	ctx, span := observ.StartSpan(ctx, op.String())
@@ -95,7 +93,7 @@ func query(ctx context.Context, s *ModuleStore, module, vsn string) (*storage.Mo
 	queryResult := c.FindOne(tctx, bson.M{"module": module, "version": vsn})
 	if queryErr := queryResult.Err(); queryErr != nil {
 		kind := errors.KindUnexpected
-		if queryErr == mongo.ErrNoDocuments {
+		if errors.IsErr(queryErr, mongo.ErrNoDocuments) {
 			kind = errors.KindNotFound
 		}
 		return nil, errors.E(op, queryErr, kind, errors.M(module), errors.V(vsn))
@@ -103,7 +101,7 @@ func query(ctx context.Context, s *ModuleStore, module, vsn string) (*storage.Mo
 
 	if err := queryResult.Decode(result); err != nil {
 		kind := errors.KindUnexpected
-		if err == mongo.ErrNoDocuments {
+		if errors.IsErr(err, mongo.ErrNoDocuments) {
 			kind = errors.KindNotFound
 		}
 		return nil, errors.E(op, err, kind, errors.M(module), errors.V(vsn))
diff --git a/pkg/storage/mongo/lister.go b/pkg/storage/mongo/lister.go
index 09bfdd39..5f5ba52f 100644
--- a/pkg/storage/mongo/lister.go
+++ b/pkg/storage/mongo/lister.go
@@ -12,7 +12,7 @@ import (
 	"go.mongodb.org/mongo-driver/mongo/options"
 )
 
-// List lists all versions of a module
+// List lists all versions of a module.
 func (s *ModuleStore) List(ctx context.Context, moduleName string) ([]string, error) {
 	const op errors.Op = "mongo.List"
 	ctx, span := observ.StartSpan(ctx, op.String())
@@ -31,9 +31,9 @@ func (s *ModuleStore) List(ctx context.Context, moduleName string) ([]string, er
 	var errs error
 	for cursor.Next(ctx) {
 		var module storage.Module
-		if err := cursor.Decode(&module); err != nil {
+		if err = cursor.Decode(&module); err != nil {
 			kind := errors.KindUnexpected
-			if err == mongo.ErrNoDocuments {
+			if errors.IsErr(err, mongo.ErrNoDocuments) {
 				kind = errors.KindNotFound
 			}
 			errs = multierror.Append(errs, errors.E(op, err, kind))
diff --git a/pkg/storage/mongo/mongo.go b/pkg/storage/mongo/mongo.go
index 2ba32881..939ba9d7 100644
--- a/pkg/storage/mongo/mongo.go
+++ b/pkg/storage/mongo/mongo.go
@@ -44,7 +44,7 @@ func NewStorage(conf *config.MongoConfig, timeout time.Duration) (*ModuleStore,
 		return nil, errors.E(op, err)
 	}
 
-	_, err = ms.connect(conf)
+	_, err = ms.connect()
 
 	if err != nil {
 		return nil, errors.E(op, err)
@@ -53,27 +53,27 @@ func NewStorage(conf *config.MongoConfig, timeout time.Duration) (*ModuleStore,
 	return ms, nil
 }
 
-func (m *ModuleStore) connect(conf *config.MongoConfig) (*mongo.Collection, error) {
+func (s *ModuleStore) connect() (*mongo.Collection, error) {
 	const op errors.Op = "mongo.connect"
 
-	err := m.client.Connect(context.Background())
+	err := s.client.Connect(context.Background())
 	if err != nil {
 		return nil, errors.E(op, err)
 	}
 
-	return m.initDatabase(), nil
+	return s.initDatabase(), nil
 }
 
-func (m *ModuleStore) initDatabase() *mongo.Collection {
-	if m.db == "" {
-		m.db = "athens"
+func (s *ModuleStore) initDatabase() *mongo.Collection {
+	if s.db == "" {
+		s.db = "athens"
 	}
 
-	if m.coll == "" {
-		m.coll = "modules"
+	if s.coll == "" {
+		s.coll = "modules"
 	}
 
-	c := m.client.Database(m.db).Collection(m.coll)
+	c := s.client.Database(s.db).Collection(s.coll)
 	indexView := c.Indexes()
 	keys := bson.D{
 		{Key: "base_url", Value: 1},
@@ -81,26 +81,26 @@ func (m *ModuleStore) initDatabase() *mongo.Collection {
 		{Key: "version", Value: 1},
 	}
 	indexOptions := options.Index().SetSparse(true).SetUnique(true)
-	indexView.CreateOne(context.Background(), mongo.IndexModel{Keys: keys, Options: indexOptions}, options.CreateIndexes())
+	_, _ = indexView.CreateOne(context.Background(), mongo.IndexModel{Keys: keys, Options: indexOptions}, options.CreateIndexes())
 
 	return c
 }
 
-func (m *ModuleStore) newClient() (*mongo.Client, error) {
+func (s *ModuleStore) newClient() (*mongo.Client, error) {
 	const op errors.Op = "mongo.newClient"
 
 	tlsConfig := &tls.Config{}
 	clientOptions := options.Client()
-	clientOptions = clientOptions.ApplyURI(m.url)
+	clientOptions = clientOptions.ApplyURI(s.url)
 
 	err := clientOptions.Validate()
 	if err != nil {
 		return nil, errors.E(op, err)
 	}
 
-	if m.certPath != "" {
+	if s.certPath != "" {
 		// Sets only when the env var is setup in config.dev.toml
-		tlsConfig.InsecureSkipVerify = m.insecure
+		tlsConfig.InsecureSkipVerify = s.insecure
 		var roots *x509.CertPool
 		// See if there is a system cert pool
 		roots, err := x509.SystemCertPool()
@@ -109,19 +109,19 @@ func (m *ModuleStore) newClient() (*mongo.Client, error) {
 			roots = x509.NewCertPool()
 		}
 
-		cert, err := os.ReadFile(m.certPath)
+		cert, err := os.ReadFile(s.certPath)
 		if err != nil {
 			return nil, errors.E(op, err)
 		}
 
 		if ok := roots.AppendCertsFromPEM(cert); !ok {
-			return nil, fmt.Errorf("failed to parse certificate from: %s", m.certPath)
+			return nil, fmt.Errorf("failed to parse certificate from: %s", s.certPath)
 		}
 
 		tlsConfig.ClientCAs = roots
 		clientOptions = clientOptions.SetTLSConfig(tlsConfig)
 	}
-	clientOptions = clientOptions.SetConnectTimeout(m.timeout)
+	clientOptions = clientOptions.SetConnectTimeout(s.timeout)
 	client, err := mongo.NewClient(clientOptions)
 	if err != nil {
 		return nil, errors.E(op, err)
@@ -130,6 +130,6 @@ func (m *ModuleStore) newClient() (*mongo.Client, error) {
 	return client, nil
 }
 
-func (m *ModuleStore) gridFileName(mod, ver string) string {
-	return strings.Replace(mod, "/", "_", -1) + "_" + ver + ".zip"
+func (s *ModuleStore) gridFileName(mod, ver string) string {
+	return strings.ReplaceAll(mod, "/", "_") + "_" + ver + ".zip"
 }
diff --git a/pkg/storage/mongo/saver.go b/pkg/storage/mongo/saver.go
index 878d25b1..131c9097 100644
--- a/pkg/storage/mongo/saver.go
+++ b/pkg/storage/mongo/saver.go
@@ -37,10 +37,9 @@ func (s *ModuleStore) Save(ctx context.Context, module, version string, mod []by
 	if err != nil {
 		return errors.E(op, err, errors.M(module), errors.V(version))
 	}
-	defer uStream.Close()
+	defer func() { _ = uStream.Close() }()
 
 	numBytesWritten, err := io.Copy(uStream, zip)
-
 	if err != nil {
 		return errors.E(op, err, errors.M(module), errors.V(version))
 	}
diff --git a/pkg/storage/rev_info.go b/pkg/storage/rev_info.go
index 8ed99af7..bb97fe01 100644
--- a/pkg/storage/rev_info.go
+++ b/pkg/storage/rev_info.go
@@ -2,7 +2,7 @@ package storage
 
 import "time"
 
-// From https://pkg.go.dev/cmd/go/internal/modfetch/codehost#Origin
+// Origin is taken from https://pkg.go.dev/cmd/go/internal/modfetch/codehost#Origin.
 type Origin struct {
 	VCS    string `json:",omitempty"` // "git" etc
 	URL    string `json:",omitempty"` // URL of repository
@@ -36,7 +36,7 @@ type Origin struct {
 
 // RevInfo is json-encodable into the response body for
 // GET baseURL/module/@v/version.info
-// From https://pkg.go.dev/cmd/go/internal/modfetch/codehost#RevInfo
+// from https://pkg.go.dev/cmd/go/internal/modfetch/codehost#RevInfo.
 type RevInfo struct {
 	Origin  *Origin
 	Name    string    // complete ID in underlying repository
diff --git a/pkg/storage/s3/cataloger.go b/pkg/storage/s3/cataloger.go
index 3614329f..19308571 100644
--- a/pkg/storage/s3/cataloger.go
+++ b/pkg/storage/s3/cataloger.go
@@ -5,18 +5,16 @@ import (
 	"fmt"
 	"strings"
 
-	"github.com/gomods/athens/pkg/config"
-
-	"github.com/gomods/athens/pkg/paths"
-
 	"github.com/aws/aws-sdk-go/aws"
 	"github.com/aws/aws-sdk-go/service/s3"
+	"github.com/gomods/athens/pkg/config"
 	"github.com/gomods/athens/pkg/errors"
 	"github.com/gomods/athens/pkg/observ"
+	"github.com/gomods/athens/pkg/paths"
 )
 
-// Catalog implements the (./pkg/storage).Cataloger interface
-// It returns a list of modules and versions contained in the storage
+// Catalog implements the (./pkg/storage).Cataloger interface.
+// It returns a list of modules and versions contained in the storage.
 func (s *Storage) Catalog(ctx context.Context, token string, pageSize int) ([]paths.AllPathParams, string, error) {
 	const op errors.Op = "s3.Catalog"
 	ctx, span := observ.StartSpan(ctx, op.String())
diff --git a/pkg/storage/s3/checker.go b/pkg/storage/s3/checker.go
index 6fee5a03..63c6a91a 100644
--- a/pkg/storage/s3/checker.go
+++ b/pkg/storage/s3/checker.go
@@ -13,7 +13,7 @@ import (
 )
 
 // Exists implements the (./pkg/storage).Checker interface
-// returning true if the module at version exists in storage
+// returning true if the module at version exists in storage.
 func (s *Storage) Exists(ctx context.Context, module, version string) (bool, error) {
 	const op errors.Op = "s3.Exists"
 	ctx, span := observ.StartSpan(ctx, op.String())
@@ -38,7 +38,6 @@ func (s *Storage) Exists(ctx context.Context, module, version string) (bool, err
 		}
 		return len(found) < 3
 	})
-
 	if err != nil {
 		return false, errors.E(op, err, errors.M(module), errors.V(version))
 	}
diff --git a/pkg/storage/s3/getter.go b/pkg/storage/s3/getter.go
index d9b3e664..8420864b 100644
--- a/pkg/storage/s3/getter.go
+++ b/pkg/storage/s3/getter.go
@@ -13,7 +13,7 @@ import (
 	"github.com/gomods/athens/pkg/storage"
 )
 
-// Info implements the (./pkg/storage).Getter interface
+// Info implements the (./pkg/storage).Getter interface.
 func (s *Storage) Info(ctx context.Context, module, version string) ([]byte, error) {
 	const op errors.Op = "s3.Info"
 	ctx, span := observ.StartSpan(ctx, op.String())
@@ -30,7 +30,7 @@ func (s *Storage) Info(ctx context.Context, module, version string) ([]byte, err
 	if err != nil {
 		return nil, errors.E(op, err, errors.M(module), errors.V(version))
 	}
-	defer infoReader.Close()
+	defer func() { _ = infoReader.Close() }()
 
 	infoBytes, err := io.ReadAll(infoReader)
 	if err != nil {
@@ -39,7 +39,7 @@ func (s *Storage) Info(ctx context.Context, module, version string) ([]byte, err
 	return infoBytes, nil
 }
 
-// GoMod implements the (./pkg/storage).Getter interface
+// GoMod implements the (./pkg/storage).Getter interface.
 func (s *Storage) GoMod(ctx context.Context, module, version string) ([]byte, error) {
 	const op errors.Op = "s3.GoMod"
 	ctx, span := observ.StartSpan(ctx, op.String())
@@ -56,17 +56,17 @@ func (s *Storage) GoMod(ctx context.Context, module, version string) ([]byte, er
 	if err != nil {
 		return nil, errors.E(op, err, errors.M(module), errors.V(version))
 	}
-	defer modReader.Close()
+	defer func() { _ = modReader.Close() }()
 
 	modBytes, err := io.ReadAll(modReader)
 	if err != nil {
-		return nil, errors.E(op, fmt.Errorf("could not get new reader for mod file: %s", err), errors.M(module), errors.V(version))
+		return nil, errors.E(op, fmt.Errorf("could not get new reader for mod file: %w", err), errors.M(module), errors.V(version))
 	}
 
 	return modBytes, nil
 }
 
-// Zip implements the (./pkg/storage).Getter interface
+// Zip implements the (./pkg/storage).Getter interface.
 func (s *Storage) Zip(ctx context.Context, module, version string) (storage.SizeReadCloser, error) {
 	const op errors.Op = "s3.Zip"
 	ctx, span := observ.StartSpan(ctx, op.String())
diff --git a/pkg/storage/s3/lister.go b/pkg/storage/s3/lister.go
index 038cb406..9b51c6d6 100644
--- a/pkg/storage/s3/lister.go
+++ b/pkg/storage/s3/lister.go
@@ -10,8 +10,8 @@ import (
 	"github.com/gomods/athens/pkg/observ"
 )
 
-// List implements the (./pkg/storage).Lister interface
-// It returns a list of versions, if any, for a given module
+// List implements the (./pkg/storage).Lister interface.
+// It returns a list of versions, if any, for a given module.
 func (s *Storage) List(ctx context.Context, module string) ([]string, error) {
 	const op errors.Op = "s3.List"
 	ctx, span := observ.StartSpan(ctx, op.String())
diff --git a/pkg/storage/s3/s3.go b/pkg/storage/s3/s3.go
index bf29a168..813db57d 100644
--- a/pkg/storage/s3/s3.go
+++ b/pkg/storage/s3/s3.go
@@ -16,14 +16,14 @@ import (
 )
 
 // Storage implements (./pkg/storage).Backend and
-// also provides a function to fetch the location of a module
-// Storage uses amazon aws go SDK which expects these env variables
+// also provides a function to fetch the location of a module.
+// Storage uses amazon aws go SDK which expects these env variables.
 // - AWS_REGION			- region for this storage, e.g 'us-west-2'
 // - AWS_ACCESS_KEY_ID		- [optional]
 // - AWS_SECRET_ACCESS_KEY 	- [optional]
 // - AWS_SESSION_TOKEN		- [optional]
 // - AWS_FORCE_PATH_STYLE	- [optional]
-// For information how to get your keyId and access key turn to official aws docs: https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/setting-up.html
+// For information how to get your keyId and access key turn to official aws docs: https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/setting-up.html.
 type Storage struct {
 	bucket   string
 	uploader s3manageriface.UploaderAPI
@@ -31,12 +31,12 @@ type Storage struct {
 	timeout  time.Duration
 }
 
-// New creates a new AWS S3 CDN saver
+// New creates a new AWS S3 CDN saver.
 func New(s3Conf *config.S3Config, timeout time.Duration, options ...func(*aws.Config)) (*Storage, error) {
 	const op errors.Op = "s3.New"
 
 	awsConfig := defaults.Config()
-	// remove anonymous credentials from the default config so that
+	// Remove anonymous credentials from the default config so that
 	// session.NewSession can auto-resolve credentials from role, profile, env etc.
 	awsConfig.Credentials = nil
 	awsConfig.Region = aws.String(s3Conf.Region)
@@ -67,7 +67,7 @@ func New(s3Conf *config.S3Config, timeout time.Duration, options ...func(*aws.Co
 		awsConfig.Endpoint = aws.String(s3Conf.Endpoint)
 	}
 
-	// create a session with creds
+	// Create a session with creds.
 	sess, err := session.NewSession(awsConfig)
 	if err != nil {
 		return nil, errors.E(op, err)
@@ -83,6 +83,6 @@ func New(s3Conf *config.S3Config, timeout time.Duration, options ...func(*aws.Co
 	}, nil
 }
 
-func endpointFrom(credentialsEndpoint string, relativeURI string) string {
+func endpointFrom(credentialsEndpoint, relativeURI string) string {
 	return credentialsEndpoint + relativeURI
 }
diff --git a/pkg/storage/saver.go b/pkg/storage/saver.go
index 47777c99..45eb73a9 100644
--- a/pkg/storage/saver.go
+++ b/pkg/storage/saver.go
@@ -5,7 +5,7 @@ import (
 	"io"
 )
 
-// Saver saves module metadata and its source to underlying storage
+// Saver saves module metadata and its source to underlying storage.
 type Saver interface {
 	Save(ctx context.Context, module, version string, mod []byte, zip io.Reader, info []byte) error
 }
diff --git a/pkg/storage/version.go b/pkg/storage/version.go
index e21f7737..4947c4bf 100644
--- a/pkg/storage/version.go
+++ b/pkg/storage/version.go
@@ -2,7 +2,7 @@ package storage
 
 import "io"
 
-// Version represents a version of a module and contains .mod file, a .info file and zip file of a specific version
+// Version represents a version of a module and contains .mod file, a .info file and zip file of a specific version.
 type Version struct {
 	Mod    []byte
 	Zip    io.ReadCloser
diff --git a/scripts/check_gofmt.sh b/scripts/check_gofmt.sh
deleted file mode 100755
index f79aa9fe..00000000
--- a/scripts/check_gofmt.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/bash
-
-# check_gofmt.sh
-# Fail if a .go file hasn't been formatted with gofmt
-set -euo pipefail
-
-GO_FILES=$(find . -iname '*.go' -type f -not -path "./vendor/*")   # All the .go files
-for f in $GO_FILES; do
-  test -z "$(gofmt -s -w "$f" | tee /dev/stderr)"
-done
diff --git a/scripts/check_govet.sh b/scripts/check_govet.sh
deleted file mode 100755
index e6a8a484..00000000
--- a/scripts/check_govet.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/bash
-
-# check_govet.sh
-# Run the linter on everything except generated code
-set -euo pipefail
-
-go vet ./...
diff --git a/scripts/ps/check_gofmt.ps1 b/scripts/ps/check_gofmt.ps1
deleted file mode 100755
index 972fd4d3..00000000
--- a/scripts/ps/check_gofmt.ps1
+++ /dev/null
@@ -1,7 +0,0 @@
-# check_gofmt.ps1
-# Fail if a .go file hasn't been formatted with gofmt
-$GO_FILES = Get-ChildItem -Recurse -Filter *.go  -Name | Select-String -Pattern $(Join-Path "vendor" -ChildPath ".*") -NotMatch
-$out = & gofmt -s -l $GO_FILES
-if ($out.length -gt 0) {
-    Write-Error $out
-}
diff --git a/scripts/ps/check_govet.ps1 b/scripts/ps/check_govet.ps1
deleted file mode 100755
index 8e61f452..00000000
--- a/scripts/ps/check_govet.ps1
+++ /dev/null
@@ -1,7 +0,0 @@
-# check_govet.ps1
-# Run the linter on everything
-
-$out = & go vet ./...
-if ($LastExitCode -ne 0) {
-    Write-Error $out
-}


Test patch:
diff --git a/cmd/proxy/actions/sumdb_test.go b/cmd/proxy/actions/sumdb_test.go
index 195b9176..ff55604e 100644
--- a/cmd/proxy/actions/sumdb_test.go
+++ b/cmd/proxy/actions/sumdb_test.go
@@ -97,7 +97,7 @@ func TestNoSumPatterns(t *testing.T) {
 	for _, tc := range noSumTestCases {
 		t.Run(tc.name, func(t *testing.T) {
 			w := httptest.NewRecorder()
-			skipHandler := noSumWrapper(http.HandlerFunc(emptyHandler), "sum.golang.org", tc.patterns)
+			skipHandler := noSumWrapper(http.HandlerFunc(emptyHandler), tc.patterns)
 			req := httptest.NewRequest("GET", "/lookup/"+tc.given, nil)
 			skipHandler.ServeHTTP(w, req)
 			if tc.status != w.Code {
diff --git a/pkg/download/latest.go b/pkg/download/latest.go
index e288141f..6e5aad19 100644
--- a/pkg/download/latest.go
+++ b/pkg/download/latest.go
@@ -13,7 +13,7 @@ import (
 // PathLatest URL.
 const PathLatest = "/{module:.+}/@latest"
 
-// LatestHandler implements GET baseURL/module/@latest
+// LatestHandler implements GET baseURL/module/@latest.
 func LatestHandler(dp Protocol, lggr log.Entry, df *mode.DownloadFile) http.Handler {
 	const op errors.Op = "download.LatestHandler"
 	f := func(w http.ResponseWriter, r *http.Request) {
diff --git a/pkg/storage/compliance/tests.go b/pkg/storage/compliance/tests.go
index 47fcf521..32f60113 100644
--- a/pkg/storage/compliance/tests.go
+++ b/pkg/storage/compliance/tests.go
@@ -6,7 +6,6 @@ import (
 	"fmt"
 	"io"
 	"math/rand"
-	"sort"
 	"testing"
 
 	"github.com/gomods/athens/pkg/errors"
@@ -26,7 +25,6 @@ func RunTests(t *testing.T, b storage.Backend, clearBackend func() error) {
 	testGet(t, b)
 	testExists(t, b)
 	testShouldNotExist(t, b)
-	// testCatalog(t, b)
 }
 
 // testNotFound ensures that a storage Backend
@@ -209,49 +207,6 @@ func testDelete(t *testing.T, b storage.Backend) {
 	require.Equal(t, false, exists)
 }
 
-func testCatalog(t *testing.T, b storage.Backend) {
-	cs, ok := b.(storage.Cataloger)
-	if !ok {
-		t.Skip()
-	}
-	ctx := context.Background()
-
-	mock := getMockModule()
-	zipBts, _ := io.ReadAll(mock.Zip)
-	modname := "github.com/gomods/testCatalogModule"
-	for i := 0; i < 6; i++ {
-		ver := fmt.Sprintf("v1.2.%04d", i)
-		b.Save(ctx, modname, ver, mock.Mod, bytes.NewReader(zipBts), mock.Info)
-
-		defer b.Delete(ctx, modname, ver)
-	}
-
-	allres, next, err := cs.Catalog(ctx, "", 5)
-
-	require.NoError(t, err)
-	require.Equal(t, 5, len(allres))
-
-	res, next, err := cs.Catalog(ctx, next, 50)
-	allres = append(allres, res...)
-	require.NoError(t, err)
-	require.Equal(t, 1, len(res))
-	require.Equal(t, "", next)
-
-	sort.Slice(allres, func(i, j int) bool {
-		if allres[i].Module == allres[j].Module {
-			return allres[i].Version < allres[j].Version
-		}
-		return allres[i].Module < allres[j].Module
-	})
-	require.Equal(t, modname, allres[0].Module)
-	require.Equal(t, "v1.2.0000", allres[0].Version)
-	require.Equal(t, "v1.2.0004", allres[4].Version)
-
-	for i := 1; i < len(allres); i++ {
-		require.NotEqual(t, allres[i].Version, allres[i-1].Version)
-	}
-}
-
 func getMockModule() *storage.Version {
 	return &storage.Version{
 		Info: []byte("123"),
diff --git a/pkg/storage/mongo/mongo_test.go b/pkg/storage/mongo/mongo_test.go
index 13b2a8da..7e2a31e7 100644
--- a/pkg/storage/mongo/mongo_test.go
+++ b/pkg/storage/mongo/mongo_test.go
@@ -20,8 +20,8 @@ func TestBackend(t *testing.T) {
 	compliance.RunTests(t, backend, backend.clear)
 }
 
-func (m *ModuleStore) clear() error {
-	m.client.Database(m.db).Drop(context.Background())
+func (s *ModuleStore) clear() error {
+	s.client.Database(s.db).Drop(context.Background())
 	return nil
 }