diff --git a/.github/workflows/build-test-lint.yml b/.github/workflows/build-test-lint.yml index 3d8bb0ec8..c6cb620b1 100644 --- a/.github/workflows/build-test-lint.yml +++ b/.github/workflows/build-test-lint.yml @@ -62,10 +62,10 @@ jobs: run: make test-coverage - name: Coveralls - uses: coverallsapp/github-action@1.1.3 + uses: coverallsapp/github-action@v2 with: github-token: ${{ secrets.GITHUB_TOKEN }} - path-to-lcov: test/coverage/lcov.info + file: test/coverage/cover.out golangci: name: Golangci-lint @@ -75,12 +75,12 @@ jobs: uses: actions/setup-go@v3 with: go-version: 1.22.x - - uses: actions/checkout@v3 - - name: golangci-lint - uses: golangci/golangci-lint-action@v3 - with: - # Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version. - version: v1.55.2 + + - name: checkout + uses: actions/checkout@v3 + + - name: lint test + run: make lint shellcheck: name: Shellcheck diff --git a/.golangci.yml b/.golangci.yml index d8da63a3c..d9a2e26f4 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -69,7 +69,6 @@ linters: disable-all: true enable: - bodyclose - - deadcode # depguard has a bug in go 1.21 that will be fixed in future versions: https://github.com/kedacore/keda/pull/5285 #- depguard - dogsled @@ -97,13 +96,11 @@ linters: - rowserrcheck #- scopelint - staticcheck - - structcheck - stylecheck - typecheck - unconvert - unparam - unused - - varcheck - whitespace issues: diff --git a/Dockerfile.rhel7 b/Dockerfile.rhel7 index 0ab7a63db..2a2e9581b 100644 --- a/Dockerfile.rhel7 +++ b/Dockerfile.rhel7 @@ -7,7 +7,7 @@ WORKDIR /usr/src/sriov-network-device-plugin ENV HTTP_PROXY $http_proxy ENV HTTPS_PROXY $https_proxy RUN make clean && \ - make build + GO_BUILD_OPTS=CGO_ENABLED=1 GO_TAGS=" " make build FROM registry.ci.openshift.org/ocp/4.17:base-rhel9 ENV INSTALL_PKGS "hwdata" diff --git a/Makefile b/Makefile index 4c22d7d96..316dc8800 100644 --- a/Makefile +++ b/Makefile @@ -3,33 +3,17 @@ # This makefile was adapted from: https://github.com/vincentbernat/hellogopher/blob/feature/glide/Makefile # # Go environment -GOPATH=$(CURDIR)/.gopath -GOBIN=$(CURDIR)/bin -# Go tools -GOLINT = $(GOBIN)/golint -GOCOVMERGE = $(GOBIN)/gocovmerge -GOCOV = $(GOBIN)/gocov -GOCOVXML = $(GOBIN)/gocov-xml -GCOV2LCOV = $(GOBIN)/gcov2lcov -GO2XUNIT = $(GOBIN)/go2xunit -GOMOCKERY = $(GOBIN)/mockery -# Package info -BINARY_NAME=sriovdp -PACKAGE=sriov-network-device-plugin -ORG_PATH=github.com/k8snetworkplumbingwg +export GOPATH?=$(shell go env GOPATH) +BINDIR=$(CURDIR)/bin # Build info +BINARY_NAME=sriovdp BUILDDIR=$(CURDIR)/build -REPO_PATH=$(ORG_PATH)/$(PACKAGE) -BASE=$(GOPATH)/src/$(REPO_PATH) -PKGS = $(or $(PKG),$(shell cd $(BASE) && env GOPATH=$(GOPATH) go list ./...)) -GOFILES = $(shell find . -name *.go | grep -v "_test.go") +PKGS = $(or $(PKG),$(shell go list ./... | grep -v ".*/mocks")) # Test artifacts and settings -TESTPKGS = $(shell env GOPATH=$(GOPATH) go list -f '{{ if or .TestGoFiles .XTestGoFiles }}{{ .ImportPath }}{{ end }}' $(PKGS)) TIMEOUT = 15 +COVERAGE_DIR = $(CURDIR)/test/coverage COVERAGE_MODE = atomic -COVERAGE_PROFILE = $(COVERAGE_DIR)/profile.out -COVERAGE_XML = $(COVERAGE_DIR)/coverage.xml -COVERAGE_HTML = $(COVERAGE_DIR)/index.html +COVERAGE_PROFILE = $(COVERAGE_DIR)/cover.out # Docker image DOCKERFILE?=$(CURDIR)/images/Dockerfile TAG?=ghcr.io/k8snetworkplumbingwg/sriov-network-device-plugin @@ -42,125 +26,83 @@ ifdef HTTPS_PROXY DOCKERARGS += --build-arg https_proxy=$(HTTPS_PROXY) endif -LDFLAGS= +GO_BUILD_OPTS ?= +GO_LDFLAGS ?= +GO_FLAGS ?= +GO_TAGS ?=-tags no_openssl + ifdef STATIC - export CGO_ENABLED=0 - LDFLAGS=-a -ldflags '-extldflags \"-static\"' + GO_BUILD_OPTS+= CGO_ENABLED=0 + GO_LDFLAGS+= -extldflags \"-static\" + GO_FLAGS+= -a endif -export GOPATH -export GOBIN - V = 0 Q = $(if $(filter 1,$V),,@) .PHONY: all -all: fmt lint build +all: lint build test -$(BASE): ; $(info Setting GOPATH...) - @mkdir -p $(dir $@) - @ln -sf $(CURDIR) $@ +.PHONY: create-dirs +create-dirs: $(BINDIR) $(BUILDDIR) $(COVERAGE_DIR) -$(GOBIN): - @mkdir -p $@ +$(BINDIR) $(BUILDDIR) $(COVERAGE_DIR): ; $(info Creating directory $@...) + $Q mkdir -p $@ -$(BUILDDIR): | $(BASE) ; $(info Creating build directory...) - @cd $(BASE) && mkdir -p $@ - -build: $(BUILDDIR)/$(BINARY_NAME) | ; $(info Building $(BINARY_NAME)...) @ ## Build SR-IOV Network device plugin +.PHONY: build +build: | $(BUILDDIR) ; $(info Building $(BINARY_NAME)...) @ ## Build SR-IOV Network device plugin + $Q cd $(CURDIR)/cmd/$(BINARY_NAME) && $(GO_BUILD_OPTS) go build -ldflags '$(GO_LDFLAGS)' $(GO_FLAGS) -o $(BUILDDIR)/$(BINARY_NAME) $(GO_TAGS) -v $(info Done!) -$(BUILDDIR)/$(BINARY_NAME): $(GOFILES) | $(BUILDDIR) - @cd $(BASE)/cmd/$(BINARY_NAME) && CGO_ENABLED=0 go build $(LDFLAGS) -o $(BUILDDIR)/$(BINARY_NAME) -tags no_openssl -v - -$(GOLINT): | $(BASE) ; $(info building golint...) - $(call go-install-tool,$(GOLINT),golang.org/x/lint/golint@latest) - -$(GOCOVMERGE): | $(BASE) ; $(info building gocovmerge...) - $(call go-install-tool,$(GOCOVMERGE),github.com/wadey/gocovmerge@latest) +GOLANGCI_LINT = $(BINDIR)/golangci-lint +GOLANGCI_LINT_VERSION ?= v1.55.2 +$(GOLANGCI_LINT): | $(BINDIR) ; $(info installing golangci-lint...) + $Q[ -f $(GOLANGCI_LINT) ] || { \ + set -e ;\ + curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(shell dirname $(GOLANGCI_LINT)) $(GOLANGCI_LINT_VERSION) ;\ + } -$(GOCOV): | $(BASE) ; $(info building gocov...) - $(call go-install-tool,$(GOCOV),github.com/axw/gocov/gocov@v1.1.0) +MOCKERY = $(BINDIR)/mockery +$(MOCKERY): | $(BINDIR) ; $(info installing mockery...) + $(call go-install-tool,$(MOCKERY),github.com/vektra/mockery/v2@latest) -$(GCOV2LCOV): | $(BASE) ; $(info building gcov2lcov...) - $(call go-install-tool,$(GCOV2LCOV),github.com/jandelgado/gcov2lcov@latest) - -$(GOCOVXML): | $(BASE) ; $(info building gocov-xml...) - $(call go-install-tool,$(GOCOVXML),github.com/AlekSi/gocov-xml@latest) - -$(GO2XUNIT): | $(BASE) ; $(info building go2xunit...) - $(call go-install-tool,$(GO2XUNIT),github.com/tebeka/go2xunit@latest) - -$(GOMOCKERY): | $(BASE) ; $(info building go2xunit...) - $(call go-install-tool,$(GOMOCKERY),github.com/vektra/mockery/v2@latest) - -TEST_TARGETS := test-default test-bench test-short test-verbose test-race -.PHONY: $(TEST_TARGETS) test-xml check test tests -test-bench: ARGS=-run=__absolutelynothing__ -bench=. ## Run benchmarks -test-short: ARGS=-short ## Run only short tests +TEST_TARGETS := test-default test-verbose test-race +.PHONY: $(TEST_TARGETS) test test-verbose: ARGS=-v ## Run tests in verbose mode with coverage reporting test-race: ARGS=-race ## Run tests with race detector $(TEST_TARGETS): NAME=$(MAKECMDGOALS:test-%=%) $(TEST_TARGETS): test -check test tests: fmt lint | $(BASE) ; $(info running $(NAME:%=% )tests...) @ ## Run tests - $Q cd $(BASE) && go test -timeout $(TIMEOUT)s $(ARGS) $(TESTPKGS) - -test-xml: fmt lint | $(BASE) $(GO2XUNIT) ; $(info running $(NAME:%=% )tests...) @ ## Run tests with xUnit output - $Q cd $(BASE) && 2>&1 go test -timeout 20s -v $(TESTPKGS) | tee test/tests.output - $(GO2XUNIT) -fail -input test/tests.output -output test/tests.xml - -.PHONY: test-coverage test-coverage-tools -test-coverage-tools: | $(GOCOVMERGE) $(GOCOV) $(GOCOVXML) $(GCOV2LCOV) -test-coverage: COVERAGE_DIR := $(CURDIR)/test/coverage -test-coverage: fmt lint test-coverage-tools | $(BASE) ; $(info Running coverage tests...) @ ## Run coverage tests - $Q mkdir -p $(COVERAGE_DIR)/coverage - $Q cd $(BASE) && for pkg in $(TESTPKGS); do \ - go test \ - -coverpkg=$$(go list -f '{{ join .Deps "\n" }}' $$pkg | \ - grep '^$(PACKAGE)/' | \ - tr '\n' ',')$$pkg \ - -covermode=$(COVERAGE_MODE) \ - -coverprofile="$(COVERAGE_DIR)/coverage/`echo $$pkg | tr "/" "-"`.cover" $$pkg ;\ - done - $Q $(GOCOVMERGE) $(COVERAGE_DIR)/coverage/*.cover > $(COVERAGE_PROFILE) - $Q go tool cover -html=$(COVERAGE_PROFILE) -o $(COVERAGE_HTML) - $Q $(GOCOV) convert $(COVERAGE_PROFILE) | $(GOCOVXML) > $(COVERAGE_XML) - $Q $(GCOV2LCOV) -infile $(COVERAGE_PROFILE) -outfile $(COVERAGE_DIR)/lcov.info +test: ; $(info running $(NAME:%=% )tests...) @ ## Run tests + $Q go test -timeout $(TIMEOUT)s $(ARGS) $(PKGS) -.PHONY: lint -lint: | $(BASE) $(GOLINT) ; $(info Running golint...) @ ## Run golint on all source files - $Q cd $(BASE) && ret=0 && for pkg in $(PKGS); do \ - test -z "$$($(GOLINT) $$pkg | tee /dev/stderr)" || ret=1 ; \ - done ; exit $$ret +.PHONY: test-coverage +test-coverage: | $(COVERAGE_DIR) ; $(info Running coverage tests...) @ ## Run coverage tests + $Q go test -timeout 30s -cover -covermode=$(COVERAGE_MODE) -coverprofile=$(COVERAGE_PROFILE) $(PKGS) -.PHONY: fmt -fmt: ; $(info running gofmt...) @ ## Run gofmt on all source files - @ret=0 && for d in $$(go list -f '{{.Dir}}' ./...); do \ - gofmt -l -w $$d/*.go || ret=$$? ; \ - done ; exit $$ret +.PHONY: lint +lint: $(GOLANGCI_LINT) ; $(info Running golangci-lint linter...) @ ## Run golangci-lint linter + $Q $(GOLANGCI_LINT) run .PHONY: deps-update deps-update: ; $(info Updating dependencies...) @ ## Update dependencies - @go mod tidy + $Q go mod tidy .PHONY: image -image: | $(BASE) ; $(info Building Docker image...) @ ## Build SR-IOV Network device plugin docker image - @docker build -t $(TAG) -f $(DOCKERFILE) $(CURDIR) $(DOCKERARGS) +image: ; $(info Building Docker image...) @ ## Build SR-IOV Network device plugin docker image + $Q docker build -t $(TAG) -f $(DOCKERFILE) $(CURDIR) $(DOCKERARGS) .PHONY: clean clean: ; $(info Cleaning...) @ ## Cleanup everything @go clean --modcache --cache --testcache - @rm -rf $(GOPATH) @rm -rf $(BUILDDIR) - @rm -rf $(GOBIN) + @rm -rf $(BINDIR) @rm -rf test/ -.PHONY: mockery -mockery: | $(BASE) $(GOMOCKERY) ; $(info Running mockery...) @ ## Run golint on all source files -# $Q cd $(BASE)/pkg/types && rm -rf mocks && $(GOMOCKERY) --all 2>/dev/null - $Q $(GOMOCKERY) --name=".*" --dir=pkg/types --output=pkg/types/mocks --recursive=false --log-level=debug - $Q $(GOMOCKERY) --name=".*" --dir=pkg/utils --output=pkg/utils/mocks --recursive=false --log-level=debug - $Q $(GOMOCKERY) --name=".*" --dir=pkg/cdi --output=pkg/cdi/mocks --recursive=false --log-level=debug +.PHONY: generate-mocks +generate-mocks: | $(MOCKERY) ; $(info generating mocks...) @ ## Generate mocks + $Q $(MOCKERY) --name=".*" --dir=pkg/types --output=pkg/types/mocks --recursive=false --log-level=debug + $Q $(MOCKERY) --name=".*" --dir=pkg/utils --output=pkg/utils/mocks --recursive=false --log-level=debug + $Q $(MOCKERY) --name=".*" --dir=pkg/cdi --output=pkg/cdi/mocks --recursive=false --log-level=debug .PHONY: help help: ; @ ## Display this help message @@ -170,9 +112,9 @@ help: ; @ ## Display this help message # go-install-tool will 'go install' any package $2 and install it to $1. define go-install-tool -@[ -f $(1) ] || { \ +$Q[ -f $(1) ] || { \ set -e ;\ echo "Downloading $(2)" ;\ -GOBIN=$(GOBIN) go install -mod=mod $(2) ;\ +GOBIN=$(BINDIR) go install $(2) ;\ } endef