diff --git a/.github/workflows/latest.yaml b/.github/workflows/latest.yaml index 05b25325d..8a1ba8570 100644 --- a/.github/workflows/latest.yaml +++ b/.github/workflows/latest.yaml @@ -9,7 +9,7 @@ on: name: build-test-publish jobs: - build: + go: runs-on: ubuntu-latest steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 @@ -20,12 +20,17 @@ jobs: - run: go env - name: go build run: go build -v ./... - + - uses: alexellis/setup-arkade@v3 + - uses: alexellis/arkade-get@master + with: + golangci-lint: latest + - name: Lint Go Code + run: | + make lint-go e2e: name: e2e tests runs-on: ubuntu-latest - needs: [build] - + needs: [go] steps: - uses: ko-build/setup-ko@v0.6 - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 000000000..3739e4a54 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,128 @@ +issues: + exclude-dirs: + - vendor + - pkg/provider/gitea/structs + exclude-rules: + # Exclude some linters from running on tests files. + - path: _test\.go + linters: + - gosec +run: + build-tags: + - e2e +linters-settings: + gocritic: + disabled-checks: + - unlambda + errcheck: + exclude-functions: + - (*github.com/tektoncd/pipeline/vendor/go.uber.org/zap.SugaredLogger).Sync + - flag.Set + - logger.Sync + - fmt.Fprintf + - fmt.Fprintln + - (io.Closer).Close + - updateConfigMap +linters: + enable: + - asasalint + - asciicheck + - bidichk + - bodyclose + #- containedctx + #- contextcheck + #- cyclop + - decorder + #- depguard + - dogsled + - dupl + - dupword + - durationcheck + - errcheck + - errchkjson + - errname + - errorlint + - execinquery + - exhaustive + #- exhaustruct + - exportloopref + - forbidigo + - forcetypeassert + #- funlen + #- gci + - ginkgolinter + - gocheckcompilerdirectives + #- gochecknoglobals + - gochecknoinits + - gochecksumtype + #- gocognit + #- goconst + - gocritic + #- gocyclo + - godot + #- godox + #- goerr113 + #- gofmt + - gofumpt + - goheader + - goimports + #- gomnd + #- gomoddirectives + - gomodguard + - goprintffuncname + - gosec + - gosimple + - gosmopolitan + - govet + - grouper + - importas + #- inamedparam + #- interfacebloat + #- ireturn + #- lll + - loggercheck + #- maintidx + - makezero + - mirror + - misspell + #- musttag + - nakedret + #- nestif + - nilerr + #- nilnil + #- nlreturn + - noctx + #- nolintlint + #- nonamedreturns + - nosprintfhostport + #- paralleltest + #- perfsprint + - prealloc + - predeclared + - promlinter + - protogetter + - reassign + - revive + #- rowserrcheck + - sloglint + #- sqlclosecheck + - staticcheck + - stylecheck + - tagalign + #- tagliatelle + - tenv + - testableexamples + # - testifylint + #- testpackage + #- thelper + - tparallel + #- unconvert + - unparam + - unused + - usestdlibvars + #- varnamelen + #- wastedassign + - whitespace + #- wrapcheck + #- wsl + - zerologlint diff --git a/Makefile b/Makefile index 0e837dea8..9bd899b95 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,16 @@ E2E_TAG ?= e2e REGISTRY_NAME ?= registry -e2e-coverage: +GOLANGCI_LINT=golangci-lint +TIMEOUT_UNIT = 20m +GOFUMPT=gofumpt + +e2e-coverage: ## run e2e tests with coverage @go test -failfast -count=1 -tags=$(E2E_TAG) ./tests -coverpkg=./... -coverprofile /tmp/coverage.out @go tool cover -func /tmp/coverage.out e2e: e2e-coverage -e2e-docker: +e2e-docker: ## run e2e tests with a docker registry started @if [[ $$(docker ps --filter name=$(REGISTRY_NAME) --format '{{.ID}}') == "" ]]; then \ echo -n "Starting container $(REGISTRY_NAME) ... "; \ docker run --name $(REGISTRY_NAME) -p 127.0.0.1:5000:5000 -d registry:2 >/dev/null; \ @@ -14,3 +18,20 @@ e2e-docker: fi make e2e-coverage @docker rm -f $(REGISTRY_NAME) >/dev/null + +lint: lint-go +lint-go: ## runs go linter on all go files + @echo "Linting go files..." + @$(GOLANGCI_LINT) run ./... --modules-download-mode=vendor \ + --max-issues-per-linter=0 \ + --max-same-issues=0 \ + --timeout $(TIMEOUT_UNIT) + +.PHONY: fumpt ## formats the GO code with gofumpt(excludes vendors dir) +fumpt: + @find internal cmd tests -name '*.go'|xargs -P4 $(GOFUMPT) -w -extra + +.PHONY: help +help: ## print this help + @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) + diff --git a/cmd/cache/fetch.go b/cmd/cache/fetch.go index ce432d81c..7fa542369 100644 --- a/cmd/cache/fetch.go +++ b/cmd/cache/fetch.go @@ -24,7 +24,7 @@ const ( func fetchCmd() *cobra.Command { cmd := &cobra.Command{ Use: "fetch", - RunE: func(cmd *cobra.Command, args []string) error { + RunE: func(cmd *cobra.Command, _ []string) error { target, err := cmd.Flags().GetString(sourceFlag) if err != nil { return err @@ -50,10 +50,9 @@ func fetchCmd() *cobra.Command { return m }) if len(matches) == 0 { - return fmt.Errorf("Didn't match any files with %v", patterns) - } else { - fmt.Fprintf(os.Stderr, "Matched the following files: %v\n", matches) + return fmt.Errorf("didn't match any files with %v", patterns) } + fmt.Fprintf(os.Stderr, "Matched the following files: %v\n", matches) // TODO: Hash files based of matches hashStr, err := hash.Compute(matches) if err != nil { @@ -82,11 +81,13 @@ func fetchCmd() *cobra.Command { func glob(root string, fn func(string) bool) []string { var files []string - filepath.WalkDir(root, func(s string, d fs.DirEntry, e error) error { + if err := filepath.WalkDir(root, func(s string, _ fs.DirEntry, _ error) error { if fn(s) { files = append(files, s) } return nil - }) + }); err != nil { + fmt.Fprintf(os.Stderr, "error walking the path %q: %v\n", root, err) + } return files } diff --git a/cmd/cache/main.go b/cmd/cache/main.go index b205916c5..26f128274 100644 --- a/cmd/cache/main.go +++ b/cmd/cache/main.go @@ -28,7 +28,7 @@ func main() { defer stop() cache := rootCmd() if err := cache.ExecuteContext(ctx); err != nil { - os.Exit(1) + os.Exit(1) //nolint:gocritic } } diff --git a/cmd/cache/upload.go b/cmd/cache/upload.go index 8152f9926..c4afafcd8 100644 --- a/cmd/cache/upload.go +++ b/cmd/cache/upload.go @@ -17,7 +17,7 @@ const ( func uploadCmd() *cobra.Command { cmd := &cobra.Command{ Use: "upload", - RunE: func(cmd *cobra.Command, args []string) error { + RunE: func(cmd *cobra.Command, _ []string) error { target, err := cmd.Flags().GetString(targetFlag) if err != nil { return err @@ -48,10 +48,9 @@ func uploadCmd() *cobra.Command { return m }) if len(matches) == 0 { - return fmt.Errorf("Didn't match any files with %v", patterns) - } else { - fmt.Fprintf(os.Stderr, "Matched the following files: %v\n", matches) + return fmt.Errorf("didn't match any files with %v", patterns) } + fmt.Fprintf(os.Stderr, "Matched the following files: %v\n", matches) // TODO: Hash files based of matches hashStr, err := hash.Compute(matches) diff --git a/internal/fetch/fetch.go b/internal/fetch/fetch.go index 591a02192..674c7a0ca 100644 --- a/internal/fetch/fetch.go +++ b/internal/fetch/fetch.go @@ -13,7 +13,7 @@ import ( func Fetch(ctx context.Context, hash, target, folder string, insecure bool) error { // check that folder exists or automatically create it if _, err := os.Stat(folder); os.IsNotExist(err) { - if err := os.MkdirAll(folder, 0755); err != nil { + if err := os.MkdirAll(folder, 0o755); err != nil { return fmt.Errorf("failed to create folder: %w", err) } } diff --git a/internal/provider/oci/upload.go b/internal/provider/oci/upload.go index 80bd2d104..156e2f308 100644 --- a/internal/provider/oci/upload.go +++ b/internal/provider/oci/upload.go @@ -15,7 +15,7 @@ import ( "github.com/google/go-containerregistry/pkg/v1/types" ) -func Upload(ctx context.Context, hash, target, folder string, insecure bool) error { +func Upload(_ context.Context, hash, target, folder string, insecure bool) error { cacheImageRef := strings.ReplaceAll(target, "{{hash}}", hash) fmt.Fprintf(os.Stderr, "Upload %s content to oci image %s\n", folder, cacheImageRef) diff --git a/tests/oci_test.go b/tests/oci_test.go index a175af68e..32c973683 100644 --- a/tests/oci_test.go +++ b/tests/oci_test.go @@ -17,14 +17,14 @@ import ( ) const ( - DEFAULT_REG = "oci://127.0.0.1:5000/cache/go" + defaultReg = "oci://127.0.0.1:5000/cache/go" goModContent = `module foo/bar/hello.moto` hashOfGoModContent = "749da1a3a827cde86850743dd2bbf6b65d13497d4b0ecf88d1df7a77ce687f86" ) func TestOCIUpload(t *testing.T) { ctx := context.Background() - regTarget := DEFAULT_REG + regTarget := defaultReg if os.Getenv("TARGET_REGISTRY") != "" { regTarget = os.Getenv("TARGET_REGISTRY") } @@ -38,5 +38,5 @@ func TestOCIUpload(t *testing.T) { assert.NilError(t, err) assert.NilError(t, upload.Upload(ctx, hash, regTarget, tmpdir.Path(), true)) assert.NilError(t, fetch.Fetch(ctx, hash, regTarget, tmpdir.Path(), false)) - assert.NilError(t, fetch.Fetch(ctx, "unknown", regTarget, tmpdir.Path(), false)) // should not error on unkown hash + assert.NilError(t, fetch.Fetch(ctx, "unknown", regTarget, tmpdir.Path(), false)) // should not error on unknown hash }