diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 697d29fc..c9caee4a 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -38,7 +38,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index cf04e293..9248b2e3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,7 +11,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5 - name: Setup Go uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1 @@ -19,12 +19,10 @@ jobs: go-version: "1.21" check-latest: true - # TODO: uncomment after migrating to Go >= 1.16 or after go mod tidy - # Error: ../../../go/pkg/mod/github.com/daixiang0/gci@v0.3.3/pkg/io/search.go:4:2: package io/fs is not in GOROOT (/opt/hostedtoolcache/go/1.15.15/x64/src/io/fs) - # - name: Lint - # run: | - # go get github.com/golangci/golangci-lint/cmd/golangci-lint - # make lint + - name: golangci-lint + uses: golangci/golangci-lint-action@a4f60bb28d35aeee14e6880718e0c85ff1882e64 # v6 + with: + version: v1.58.0 - name: Test run: make test diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 00000000..bb014c3c --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,75 @@ +run: + go: "1.22" + timeout: 3m + +linters-settings: + cyclop: + # The maximal code complexity to report. + # Default: 10 + max-complexity: 10 + # The maximal average package complexity. + # If it's higher than 0.0 (float) the check is enabled + # Default: 0.0 + package-average: 10.0 + + errcheck: + # Report about not checking of errors in type assertions: `a := b.(MyStruct)`. + # Such cases aren't reported by default. + # Default: false + check-type-assertions: true + + gocritic: + # Settings passed to gocritic. + # The settings key is the name of a supported gocritic checker. + # The list of supported checkers can be find in https://go-critic.github.io/overview. + settings: + captLocal: + # Whether to restrict checker to params only. + # Default: true + paramsOnly: false + underef: + # Whether to skip (*x).method() calls where x is a pointer receiver. + # Default: true + skipRecvDeref: false + + govet: + enable: + - shadow + + varcheck: + # Check usage of exported fields and variables. + # Default: false + exported-fields: true + +linters: + disable-all: true + enable: + ## enabled by default + - unused # Finds unused code + - gofmt + # - errcheck # Errcheck is a program for checking for unchecked errors in go programs. These unchecked errors can be critical bugs in some cases + # - gosimple # Linter for Go source code that specializes in simplifying a code + - govet # Vet examines Go source code and reports suspicious constructs, such as Printf calls whose arguments do not align with the format string + - ineffassign # Detects when assignments to existing variables are not used + # - staticcheck # Staticcheck is a go vet on steroids, applying a ton of static analysis checks + # - structcheck # Finds unused struct fields + - typecheck # Like the front-end of a Go compiler, parses and type-checks Go code + # - unused # Checks Go code for unused constants, variables, functions and types + # - varcheck # Finds unused global variables and constants + # ## disabled by default + # - contextcheck # check the function whether use a non-inherited context + # - cyclop # checks function and package cyclomatic complexity + # - errname # Checks that sentinel errors are prefixed with the Err and error types are suffixed with the Error. + # - gocritic # Provides diagnostics that check for bugs, performance and style issues. + # - gocyclo # Computes and checks the cyclomatic complexity of functions + # - nestif # Reports deeply nested if statements + - revive # Fast, configurable, extensible, flexible, and beautiful linter for Go. Drop-in replacement of golint. + # - sqlclosecheck # Checks that sql.Rows and sql.Stmt are closed + # - stylecheck # Stylecheck is a replacement for golint + # - wastedassign # wastedassign finds wasted assignment statements. + # - whitespace # Tool for detection of leading and trailing whitespace + +issues: + exclude-rules: + - text: 'shadow: declaration of "(err|ctx)" shadows declaration at' + linters: [govet] diff --git a/Makefile b/Makefile index 739fe504..1c4b7b04 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ test: go test -v ./... lint: - golangci-lint run -E gofmt -E golint --exclude-use-default=false + golangci-lint run clean: rm -f go-update diff --git a/controller/controller.go b/controller/controller.go index 2424d8bd..55f0433f 100644 --- a/controller/controller.go +++ b/controller/controller.go @@ -5,7 +5,6 @@ import ( "encoding/xml" "fmt" "io" - "io/ioutil" "log" "net/http" "net/url" @@ -113,7 +112,7 @@ func RefreshExtensionsTicker(extensionMapUpdater func()) { } // ExtensionsRouter is the router for /extensions endpoints -func ExtensionsRouter(extensions extension.Extensions, testRouter bool) chi.Router { +func ExtensionsRouter(_ extension.Extensions, testRouter bool) chi.Router { if !testRouter { RefreshExtensionsTicker(initExtensionUpdatesFromDynamoDB) } @@ -139,7 +138,7 @@ func PrintExtensions(w http.ResponseWriter, r *http.Request) { return } - _, err = w.Write([]byte(data)) + _, err = w.Write(data) if err != nil { log.Errorf("Error writing response for printing extensions: %v", err) } @@ -238,7 +237,7 @@ func UpdateExtensions(w http.ResponseWriter, r *http.Request) { }() limit := int64(1024 * 1024 * 10) // 10MiB - body, err := ioutil.ReadAll(io.LimitReader(r.Body, limit)) + body, err := io.ReadAll(io.LimitReader(r.Body, limit)) if err != nil { http.Error(w, fmt.Sprintf("Error reading body: %v", err), http.StatusBadRequest) return diff --git a/extension/json.go b/extension/json.go index 3721e255..c3923b24 100644 --- a/extension/json.go +++ b/extension/json.go @@ -59,7 +59,7 @@ func (updateResponse *UpdateResponse) MarshalJSON() ([]byte, error) { app.UpdateCheck = UpdateCheck{Status: GetUpdateStatus(extension)} extensionName := "extension_" + strings.Replace(extension.Version, ".", "_", -1) + ".crx" url := "https://" + GetS3ExtensionBucketHost(extension.ID) + "/release/" + extension.ID + "/" + extensionName - diffUrl := "https://" + GetS3ExtensionBucketHost(extension.ID) + "/release/" + extension.ID + "/patches/" + extension.SHA256 + "/" + diffURL := "https://" + GetS3ExtensionBucketHost(extension.ID) + "/release/" + extension.ID + "/patches/" + extension.SHA256 + "/" if app.UpdateCheck.Status == "ok" { if app.UpdateCheck.URLs == nil { app.UpdateCheck.URLs = &URLs{ @@ -83,7 +83,7 @@ func (updateResponse *UpdateResponse) MarshalJSON() ([]byte, error) { if pInfoFound { app.UpdateCheck.URLs.URLs = append(app.UpdateCheck.URLs.URLs, URL{ - CodebaseDiff: diffUrl, + CodebaseDiff: diffURL, }) pkg.NameDiff = patchInfo.Namediff pkg.DiffSHA256 = patchInfo.Hashdiff diff --git a/extension/xml.go b/extension/xml.go index e95aadf0..9860ec3e 100644 --- a/extension/xml.go +++ b/extension/xml.go @@ -7,7 +7,7 @@ import ( ) // MarshalXML encodes the extension list into response XML -func (updateResponse *UpdateResponse) MarshalXML(e *xml.Encoder, start xml.StartElement) error { +func (updateResponse *UpdateResponse) MarshalXML(e *xml.Encoder, _ xml.StartElement) error { type URL struct { XMLName xml.Name `xml:"url"` Codebase string `xml:"codebase,attr"` @@ -83,7 +83,7 @@ func (updateResponse *UpdateResponse) MarshalXML(e *xml.Encoder, start xml.Start } // MarshalXML encodes the extension list into response XML -func (updateResponse *WebStoreUpdateResponse) MarshalXML(e *xml.Encoder, start xml.StartElement) error { +func (updateResponse *WebStoreUpdateResponse) MarshalXML(e *xml.Encoder, _ xml.StartElement) error { type UpdateCheck struct { XMLName xml.Name `xml:"updatecheck"` Status string `xml:"status,attr"` diff --git a/go.mod b/go.mod index 271ba252..1f3c1d3c 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/brave/go-update go 1.21 require ( - github.com/aws/aws-sdk-go v1.51.30 + github.com/aws/aws-sdk-go v1.52.5 github.com/brave-intl/bat-go v0.1.0 github.com/getsentry/sentry-go v0.27.0 github.com/go-chi/chi v4.1.2+incompatible diff --git a/go.sum b/go.sum index e4a3b879..1a3422e6 100644 --- a/go.sum +++ b/go.sum @@ -14,6 +14,12 @@ github.com/aws/aws-sdk-go v1.51.25 h1:DjTT8mtmsachhV6yrXR8+yhnG6120dazr720nopRsl github.com/aws/aws-sdk-go v1.51.25/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= github.com/aws/aws-sdk-go v1.51.30 h1:RVFkjn9P0JMwnuZCVH0TlV5k9zepHzlbc4943eZMhGw= github.com/aws/aws-sdk-go v1.51.30/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= +github.com/aws/aws-sdk-go v1.52.1 h1:pYpPIuvVsawYDR0Nt3VrceizUAbtpTN3Z7xBzcZWwfI= +github.com/aws/aws-sdk-go v1.52.1/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= +github.com/aws/aws-sdk-go v1.52.2 h1:l4g9wBXRBlvCtScvv4iLZCzLCtR7BFJcXOnOGQ20orw= +github.com/aws/aws-sdk-go v1.52.2/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= +github.com/aws/aws-sdk-go v1.52.5 h1:m2lty5v9sHm1J3lhA43hJql+yKZudF09qzab0Ag9chM= +github.com/aws/aws-sdk-go v1.52.5/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/brave-intl/bat-go v0.1.0 h1:MnxS10+xgCIfTsb7yNSv4roPNM15ISyC0mWt5buR8Ys= diff --git a/server/server.go b/server/server.go index 9261b0bf..063778ba 100644 --- a/server/server.go +++ b/server/server.go @@ -37,8 +37,8 @@ func setupRouter(ctx context.Context, logger *logrus.Logger, testRouter bool) (c r.Use(chiware.Heartbeat("/")) r.Use(chiware.Timeout(60 * time.Second)) r.Use(middleware.BearerToken) - log, ok := os.LookupEnv("LOG_REQUEST") - if ok && log == "true" && logger != nil { + shouldLog, ok := os.LookupEnv("LOG_REQUEST") + if ok && shouldLog == "true" && logger != nil { // Also handles panic recovery r.Use(middleware.RequestLogger(logger)) } diff --git a/server/server_test.go b/server/server_test.go index c3db7375..dd859315 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -5,6 +5,7 @@ import ( "context" "crypto/rand" "fmt" + "io" "io/ioutil" "net/http" "net/http/httptest" @@ -77,7 +78,7 @@ func TestPing(t *testing.T) { t.Fatalf("Received non-200 response: %d\n", resp.StatusCode) } expected := "." - actual, err := ioutil.ReadAll(resp.Body) + actual, err := io.ReadAll(resp.Body) assert.Nil(t, err) if expected != string(actual) { t.Errorf("Expected the message '%s'\n", expected) @@ -92,7 +93,7 @@ func testCall(t *testing.T, server *httptest.Server, method string, contentType req.Header.Add("Content-Type", contentType) client := &http.Client{ - CheckRedirect: func(req *http.Request, via []*http.Request) error { + CheckRedirect: func(_ *http.Request, _ []*http.Request) error { return http.ErrUseLastResponse }, } @@ -562,7 +563,7 @@ func TestPrintExtensions(t *testing.T) { req, err := http.NewRequest(http.MethodGet, testURL, bytes.NewBuffer([]byte(""))) assert.Nil(t, err) client := &http.Client{ - CheckRedirect: func(req *http.Request, via []*http.Request) error { + CheckRedirect: func(_ *http.Request, _ []*http.Request) error { return http.ErrUseLastResponse }, }