diff --git a/Makefile b/Makefile index 046c03340a3..4b22b8523cd 100644 --- a/Makefile +++ b/Makefile @@ -23,8 +23,6 @@ ifeq ($(CI),true) $(shell git config --global --add safe.directory '*') endif -GO_INSTALL = ./hack/go-install.sh - TOOLS_DIR=hack/tools ROOT_DIR=$(abspath .) TOOLS_GOBIN_DIR := $(abspath $(TOOLS_DIR)) @@ -42,35 +40,35 @@ endif CONTROLLER_GEN_VER := v0.17.3 CONTROLLER_GEN_BIN := controller-gen -CONTROLLER_GEN := $(TOOLS_DIR)/$(CONTROLLER_GEN_BIN)-$(CONTROLLER_GEN_VER) +CONTROLLER_GEN := $(TOOLS_DIR)/$(CONTROLLER_GEN_BIN) export CONTROLLER_GEN # so hack scripts can use it YAML_PATCH_VER ?= v0.0.11 YAML_PATCH_BIN := yaml-patch -YAML_PATCH := $(TOOLS_DIR)/$(YAML_PATCH_BIN)-$(YAML_PATCH_VER) +YAML_PATCH := $(TOOLS_DIR)/$(YAML_PATCH_BIN) export YAML_PATCH # so hack scripts can use it -GOLANGCI_LINT_VER := v2.1.6 +GOLANGCI_LINT_VER := 2.1.6 GOLANGCI_LINT_BIN := golangci-lint -GOLANGCI_LINT := $(TOOLS_GOBIN_DIR)/$(GOLANGCI_LINT_BIN)-$(GOLANGCI_LINT_VER) +GOLANGCI_LINT := $(TOOLS_GOBIN_DIR)/$(GOLANGCI_LINT_BIN) GOLANGCI_LINT_FLAGS ?= -HTTEST_VER := v0.3.2 +HTTEST_VER := 0.3.4 HTTEST_BIN := httest -HTTEST := $(TOOLS_GOBIN_DIR)/$(HTTEST_BIN)-$(HTTEST_VER) +HTTEST := $(TOOLS_GOBIN_DIR)/$(HTTEST_BIN) -GOTESTSUM_VER := v1.8.1 +GOTESTSUM_VER := 1.12.2 GOTESTSUM_BIN := gotestsum -GOTESTSUM := $(abspath $(TOOLS_DIR))/$(GOTESTSUM_BIN)-$(GOTESTSUM_VER) +GOTESTSUM := $(abspath $(TOOLS_DIR))/$(GOTESTSUM_BIN) LOGCHECK_VER := v0.8.2 LOGCHECK_BIN := logcheck -LOGCHECK := $(TOOLS_GOBIN_DIR)/$(LOGCHECK_BIN)-$(LOGCHECK_VER) +LOGCHECK := $(TOOLS_GOBIN_DIR)/$(LOGCHECK_BIN) export LOGCHECK # so hack scripts can use it -KCP_APIGEN_BIN := apigen -KCP_APIGEN_GEN := $(TOOLS_DIR)/$(KCP_APIGEN_BIN) -export KCP_APIGEN_GEN # so hack scripts can use it +BOILERPLATE_BIN := verify_boilerplate.py +BOILERPLATE_VER := 201dcad9616c117927232ee0bc499ff38a27023e +BOILERPLATE := $(TOOLS_DIR)/$(BOILERPLATE_BIN) ARCH := $(shell go env GOARCH) OS := $(shell go env GOOS) @@ -129,36 +127,44 @@ install: require-jq require-go require-git verify-go-versions ## Install the pro .PHONY: install $(GOLANGCI_LINT): - GOBIN=$(TOOLS_GOBIN_DIR) $(GO_INSTALL) github.com/golangci/golangci-lint/v2/cmd/golangci-lint $(GOLANGCI_LINT_BIN) $(GOLANGCI_LINT_VER) + @hack/download-tool.sh \ + https://github.com/golangci/golangci-lint/releases/download/v${GOLANGCI_LINT_VER}/golangci-lint-${GOLANGCI_LINT_VER}-${OS}-${ARCH}.tar.gz \ + ${GOLANGCI_LINT_BIN} \ + ${GOLANGCI_LINT_VER} $(HTTEST): - GOBIN=$(TOOLS_GOBIN_DIR) $(GO_INSTALL) go.xrstf.de/httest $(HTTEST_BIN) $(HTTEST_VER) + @hack/download-tool.sh \ + https://codeberg.org/xrstf/httest/releases/download/v$(HTTEST_VER)/httest_$(HTTEST_VER)_${OS}_${ARCH}.tar.gz \ + ${HTTEST_BIN} \ + ${HTTEST_VER} $(LOGCHECK): - GOBIN=$(TOOLS_GOBIN_DIR) $(GO_INSTALL) sigs.k8s.io/logtools/logcheck $(LOGCHECK_BIN) $(LOGCHECK_VER) - -$(KCP_APIGEN_GEN): - pushd . && cd sdk && GOBIN=$(TOOLS_GOBIN_DIR) go install ./cmd/apigen && popd + @GO_MODULE=true hack/download-tool.sh \ + sigs.k8s.io/logtools/logcheck \ + ${LOGCHECK_BIN} \ + $(LOGCHECK_VER) +.PHONY: lint lint: $(GOLANGCI_LINT) $(LOGCHECK) ## Verify lint - echo "Linting root module..."; \ + @echo "Linting root module..."; \ $(GOLANGCI_LINT) run $(GOLANGCI_LINT_FLAGS) -c $(ROOT_DIR)/.golangci.yaml --timeout 20m - for MOD in $$(git ls-files '**/go.mod' | sed 's,/go.mod,,'); do \ + + @for MOD in $$(git ls-files '**/go.mod' | xargs dirname); do \ if [ "$$MOD" != "." ]; then \ echo "Linting $$MOD module..."; \ (cd $$MOD && $(GOLANGCI_LINT) run $(GOLANGCI_LINT_FLAGS) -c $(ROOT_DIR)/.golangci.yaml --timeout 20m); \ fi; \ done + ./hack/verify-contextual-logging.sh -.PHONY: lint +.PHONY: fix-lint fix-lint: $(GOLANGCI_LINT) GOLANGCI_LINT_FLAGS="--fix" $(MAKE) lint -.PHONY: fix-lint +.PHONY: update-contextual-logging update-contextual-logging: $(LOGCHECK) ## Update contextual logging UPDATE=true ./hack/verify-contextual-logging.sh -.PHONY: update-contextual-logging .PHONY: generate-cli-docs generate-cli-docs: ## Generate cli docs @@ -189,33 +195,41 @@ deploy-docs: venv ## Deploy docs . $(VENV)/activate; \ REMOTE=$(REMOTE) BRANCH=$(BRANCH) docs/scripts/deploy-docs.sh +.PHONY: vendor vendor: ## Vendor the dependencies go mod tidy go mod vendor -.PHONY: vendor -tools: $(GOLANGCI_LINT) $(HTTEST) $(CONTROLLER_GEN) $(KCP_APIGEN_GEN) $(YAML_PATCH) $(GOTESTSUM) ## Install tools .PHONY: tools +tools: $(GOLANGCI_LINT) $(HTTEST) $(CONTROLLER_GEN) $(YAML_PATCH) $(GOTESTSUM) ## Install tools $(CONTROLLER_GEN): - GOBIN=$(TOOLS_GOBIN_DIR) $(GO_INSTALL) sigs.k8s.io/controller-tools/cmd/controller-gen $(CONTROLLER_GEN_BIN) $(CONTROLLER_GEN_VER) + @UNCOMPRESSED=true hack/download-tool.sh \ + https://github.com/kubernetes-sigs/controller-tools/releases/download/$(CONTROLLER_GEN_VER)/controller-gen-${OS}-${ARCH} \ + $(CONTROLLER_GEN_BIN) \ + $(CONTROLLER_GEN_VER) \ + 'controller-gen-*' $(YAML_PATCH): - GOBIN=$(TOOLS_GOBIN_DIR) $(GO_INSTALL) github.com/pivotal-cf/yaml-patch/cmd/yaml-patch $(YAML_PATCH_BIN) $(YAML_PATCH_VER) + @GO_MODULE=true hack/download-tool.sh github.com/pivotal-cf/yaml-patch/cmd/yaml-patch $(YAML_PATCH_BIN) $(YAML_PATCH_VER) $(GOTESTSUM): - GOBIN=$(TOOLS_GOBIN_DIR) $(GO_INSTALL) gotest.tools/gotestsum $(GOTESTSUM_BIN) $(GOTESTSUM_VER) + @hack/download-tool.sh \ + https://github.com/gotestyourself/gotestsum/releases/download/v${GOTESTSUM_VER}/gotestsum_${GOTESTSUM_VER}_${OS}_${ARCH}.tar.gz \ + $(GOTESTSUM_BIN) \ + $(GOTESTSUM_VER) \ + $(GOTESTSUM_BIN) +.PHONY: crds crds: $(CONTROLLER_GEN) $(YAML_PATCH) ## Generate crds ./hack/update-codegen-crds.sh -.PHONY: crds -codegen: $(KCP_APIGEN_GEN) crds ## Generate all +.PHONY: codegen +codegen: crds ## Generate all go mod download ./hack/update-codegen-clients.sh ./hack/gen-patch-defaultrestmapper.sh $(MAKE) imports -.PHONY: codegen # Note, running this locally if you have any modified files, even those that are not generated, # will result in an error. This target is mostly for CI jobs. @@ -247,14 +261,16 @@ imports: $(GOLANGCI_LINT) verify-go-versions done; \ fi -$(TOOLS_DIR)/verify_boilerplate.py: - mkdir -p $(TOOLS_DIR) - curl --fail --retry 3 -L -o $(TOOLS_DIR)/verify_boilerplate.py https://raw.githubusercontent.com/kubernetes/repo-infra/201dcad9616c117927232ee0bc499ff38a27023e/hack/verify_boilerplate.py - chmod +x $(TOOLS_DIR)/verify_boilerplate.py +$(BOILERPLATE): + @UNCOMPRESSED=true hack/download-tool.sh \ + https://raw.githubusercontent.com/kubernetes/repo-infra/$(BOILERPLATE_VER)/hack/verify_boilerplate.py \ + $(BOILERPLATE_BIN) \ + $(BOILERPLATE_VER) \ + $(BOILERPLATE_BIN) .PHONY: verify-boilerplate -verify-boilerplate: $(TOOLS_DIR)/verify_boilerplate.py ## Verify boilerplate - $(TOOLS_DIR)/verify_boilerplate.py --boilerplate-dir=hack/boilerplate --skip docs/venv --skip pkg/network/dialer +verify-boilerplate: $(BOILERPLATE) ## Verify boilerplate + $(BOILERPLATE) --boilerplate-dir=hack/boilerplate --skip docs/venv --skip pkg/network/dialer ifdef ARTIFACT_DIR GOTESTSUM_ARGS += --junitfile=$(ARTIFACT_DIR)/junit.xml @@ -294,7 +310,6 @@ test-e2e: build-all ## Run e2e tests UNSAFE_E2E_HACK_DISABLE_ETCD_FSYNC=true NO_GORUN=1 GOOS=$(OS) GOARCH=$(ARCH) \ $(GO_TEST) -race $(COUNT_ARG) $(PARALLELISM_ARG) $(WHAT) $(TEST_ARGS) $(COMPLETE_SUITES_ARG) - .PHONY: test-e2e-shared-minimal ifdef USE_GOTESTSUM test-e2e-shared-minimal: $(GOTESTSUM) diff --git a/hack/download-tool.sh b/hack/download-tool.sh new file mode 100755 index 00000000000..d84a448e864 --- /dev/null +++ b/hack/download-tool.sh @@ -0,0 +1,79 @@ +#!/usr/bin/env bash + +# Copyright 2025 The KCP Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -euo pipefail + +cd $(dirname $0)/.. + +mkdir -p hack/tools +cd hack/tools + +URL="$1" +BINARY="$2" +VERSION="$3" +BINARY_PATTERN="${4:-**/$BINARY}" +GO_MODULE=${GO_MODULE:-false} +UNCOMPRESSED=${UNCOMPRESSED:-false} + +# Check if and what version we installed already. +versionFile="$BINARY.version" +existingVersion="" +if [ -f "$versionFile" ]; then + existingVersion="$(cat "$versionFile")" +fi + +# If the binary exists and its version matches, we're good. +if [ -f "$BINARY" ] && [ "$VERSION" == "$existingVersion" ]; then + exit 0 +fi + +( + rm -rf tmp + mkdir -p tmp + cd tmp + + echo "Downloading $BINARY version $VERSION …" >&2 + + if $GO_MODULE; then + GOBIN=$(realpath .) go install "$URL@$VERSION" + mv * "../$BINARY" + else + curl --fail --silent -LO "$URL" + archive="$(ls)" + + if ! $UNCOMPRESSED; then + case "$archive" in + *.tar.gz | *.tgz) + tar xzf "$archive" + ;; + *.zip) + unzip "$archive" + ;; + *) + echo "Unknown file type: $archive" >&2 + exit 1 + esac + fi + + mv $BINARY_PATTERN ../$BINARY + chmod +x ../$BINARY + fi +) + +rm -rf tmp +echo "$VERSION" > "$versionFile" + +echo "Installed at _tools/$BINARY." >&2 diff --git a/hack/go-install.sh b/hack/go-install.sh deleted file mode 100755 index ef6f8af6345..00000000000 --- a/hack/go-install.sh +++ /dev/null @@ -1,62 +0,0 @@ -#!/usr/bin/env bash - -# Copyright 2021 The KCP Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Originally copied from -# https://github.com/kubernetes-sigs/cluster-api-provider-gcp/blob/c26a68b23e9317323d5d37660fe9d29b3d2ff40c/scripts/go_install.sh - -set -o errexit -set -o nounset -set -o pipefail - -if [[ -z "${1:-}" ]]; then - echo "must provide module as first parameter" - exit 1 -fi - -if [[ -z "${2:-}" ]]; then - echo "must provide binary name as second parameter" - exit 1 -fi - -if [[ -z "${3:-}" ]]; then - echo "must provide version as third parameter" - exit 1 -fi - -if [[ -z "${GOBIN:-}" ]]; then - echo "GOBIN is not set. Must set GOBIN to install the bin in a specified directory." - exit 1 -fi - -mkdir -p "${GOBIN}" - -tmp_dir=$(mktemp -d -t goinstall_XXXXXXXXXX) -function clean { - rm -rf "${tmp_dir}" -} -trap clean EXIT - -rm "${GOBIN}/${2}"* > /dev/null 2>&1 || true - -cd "${tmp_dir}" - -# create a new module in the tmp directory -go mod init fake/mod - -# install the golang module specified as the first argument -go install -tags kcptools "${1}@${3}" -mv "${GOBIN}/${2}" "${GOBIN}/${2}-${3}" -ln -sf "${GOBIN}/${2}-${3}" "${GOBIN}/${2}" \ No newline at end of file diff --git a/hack/update-codegen-crds.sh b/hack/update-codegen-crds.sh index 835bc463882..9e6aea03006 100755 --- a/hack/update-codegen-crds.sh +++ b/hack/update-codegen-crds.sh @@ -46,11 +46,13 @@ for CRD in "${REPO_ROOT}"/config/crds/*.yaml; do done ( - ${KCP_APIGEN_GEN} --input-dir "${REPO_ROOT}"/config/crds --output-dir "${REPO_ROOT}"/config/root-phase0 \ - --ignore-export-schemas cachedobjects.cache.kcp.io + cd sdk + go run ./cmd/apigen \ + --input-dir "${REPO_ROOT}"/config/crds \ + --output-dir "${REPO_ROOT}"/config/root-phase0 \ + --ignore-export-schemas cachedobjects.cache.kcp.io ) - # Tests CRDs (