# Copyright 2022 PingCAP, Inc.
#
# 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.

BINARY_DIR = ${CURDIR}/build/bin
OBSERVABILITY_GLOBAL_SERVER_BINARY = ${BINARY_DIR}/observability-global-server
OBSERVABILITY_REGIONAL_SERVER_BINARY = ${BINARY_DIR}/observability-regional-server
OBSERVABILITY_REGIONAL_DATA_SERVER_BINARY = ${BINARY_DIR}/observability-regional-data-server
OBSERVABILITY_REGIONAL_TASK_COLLECTOR_BINARY = ${BINARY_DIR}/observability-regional-task-collector
OBSERVABILITY_OPS_SERVER_BINARY = ${BINARY_DIR}/observability-ops-server
MOCK_METRICS_SERVER_BINARY = ${BINARY_DIR}/mock-metrics-server
INSTALL_PREFIX = ${PREFIX}/observability
PROTOC_GEN_GO = google.golang.org/protobuf/cmd/protoc-gen-go@v1.27.1
PROTOBUF_VERSION = 3.14.0
PROTOC_PKG = protoc-$(PROTOBUF_VERSION)-$(OS)-$(ARCH).zip
PROTOC_URL = https://github.com/protocolbuffers/protobuf/releases/download/v$(PROTOBUF_VERSION)/$(PROTOC_PKG)
GENERATE_TARGET_DIR = $(CURDIR)/proto
COMMIT := $(shell git rev-parse --short HEAD)
IMAGE_REGISTRY_GLOBAL_SERVER ?= 552185537300.dkr.ecr.us-west-2.amazonaws.com/observability-global-server
IMAGE_REGISTRY_REGIONAL_SERVER ?= 552185537300.dkr.ecr.us-west-2.amazonaws.com/observability-regional-server
IMAGE_REGISTRY_REGIONAL_DATA_SERVER ?= 552185537300.dkr.ecr.us-west-2.amazonaws.com/observability-regional-data-server
IMAGE_REGISTRY_OPS_SERVER ?= 552185537300.dkr.ecr.us-west-2.amazonaws.com/observability-ops-server
IMAGE_REGISTRY_INGRESS_CONTROLLER ?= 552185537300.dkr.ecr.us-west-2.amazonaws.com/ingress-nginx/controller
IMAGE_TAG ?= $(COMMIT)
NGINX_VERSION ?= v1.12.5
GOLANGCI_LINT_VERSION ?= v2.2.2

include Makefile.common

.PHONY: all clean test gotest gotool help build
.PHONY: refresh-ops-server-flux-assets
all: prepare swag build

refresh-ops-server-flux-assets:
	./hack/refresh-ops-server-flux-assets.sh

# download protoc-gen-micro, protoc-gen-go and protoc
prepare:
	@echo "prepare start."
	#@if [ ! -f "$(GOPATH)/bin/protoc-gen-go" ]; then echo "download $(PROTOC_GEN_GO)"; fi
	#@if [ ! -f "$(GOPATH)/bin/protoc-gen-go" ]; then $(GO) install $(PROTOC_GEN_GO); fi
	#@if [ ! -f "$(GOPATH)/bin/protoc" ]; then echo "download $(PROTOC_URL)"; fi
	#@if [ ! -f "$(GOPATH)/bin/protoc" ]; then curl -OL $(PROTOC_URL); fi
	#@if [ -f "$(CURDIR)/$(PROTOC_PKG)" ]; then unzip -o $(PROTOC_PKG) -d $(GOPATH) bin/protoc; fi
	#@if [ -f "$(CURDIR)/$(PROTOC_PKG)" ]; then unzip -o $(PROTOC_PKG) -d $(GOPATH) 'include/*'; fi
	#@if [ -f "$(CURDIR)/$(PROTOC_PKG)" ]; then rm -rf $(PROTOC_PKG); fi
	@echo "prepare end."


# generate protobuf files
proto:
	#@echo "start to generate protobuf files"
	#@if [ ! -d "$(GENERATE_TARGET_DIR)" ]; then mkdir -p $(GENERATE_TARGET_DIR); fi
	##protoc --proto_path=$(CURDIR)/proto:$(GOPATH)/include --micro_out=$(GENERATE_TARGET_DIR) \
	##	--go_out=$(GENERATE_TARGET_DIR) $(CURDIR)/proto/*.proto
	#@echo "generate protobuf files successfully"


# 1. build binary
build:
	@echo "build observability server start."
	make global_server
	make regional_server
	make regional_data_server
	make ops_server
	@echo "build observability all server successfully."

docker-build-global:
	IMAGE_REGISTRY=$(if $(IMAGE_REGISTRY),$(IMAGE_REGISTRY),$(IMAGE_REGISTRY_GLOBAL_SERVER)) IMAGE_TAG=${IMAGE_TAG} build/package/globalserver/build.sh

docker-build-regional:
	IMAGE_REGISTRY=$(if $(IMAGE_REGISTRY),$(IMAGE_REGISTRY),$(IMAGE_REGISTRY_REGIONAL_SERVER))  IMAGE_TAG=${IMAGE_TAG} build/package/regionalserver/build.sh

docker-build-dataserver:
	IMAGE_REGISTRY=$(if $(IMAGE_REGISTRY),$(IMAGE_REGISTRY),$(IMAGE_REGISTRY_REGIONAL_DATA_SERVER)) IMAGE_TAG=${IMAGE_TAG} build/package/dataserver/build.sh

docker-build-ops-server:
	IMAGE_REGISTRY=$(if $(IMAGE_REGISTRY),$(IMAGE_REGISTRY),$(IMAGE_REGISTRY_OPS_SERVER)) IMAGE_TAG=${IMAGE_TAG} build/package/opsserver/build.sh

docker-build-ingress-controller:
	IMAGE_REGISTRY=$(if $(IMAGE_REGISTRY),$(IMAGE_REGISTRY),$(IMAGE_REGISTRY_INGRESS_CONTROLLER)) IMAGE_TAG=${NGINX_VERSION}-${IMAGE_TAG} build/package/ingress-nginx/build.sh

#Compile all Observability microservices
global_server:
	@echo "build global-server start."
	$(GOBUILD) $(RACE_FLAG) -ldflags '$(LDFLAGS) $(CHECK_FLAG)' -o ${OBSERVABILITY_GLOBAL_SERVER_BINARY} cmd/globalserver/*.go
	@echo "build global-server successfully."

regional_server:
	@echo "build regional-server start."
	$(GOBUILD) $(RACE_FLAG) -ldflags '$(LDFLAGS) $(CHECK_FLAG)' -o ${OBSERVABILITY_REGIONAL_SERVER_BINARY} cmd/regionalserver/*.go
	@echo "build regional-server successfully."

regional_data_server:
	@echo "build regional-data-server start."
	$(GOBUILD) $(RACE_FLAG) -ldflags '$(LDFLAGS) $(CHECK_FLAG)' -o ${OBSERVABILITY_REGIONAL_DATA_SERVER_BINARY} cmd/dataserver/*.go
	@echo "build regional-data-server successfully."

ops_server:
	@echo "build ops-server start."
	$(GOBUILD) $(RACE_FLAG) -ldflags '$(LDFLAGS) $(CHECK_FLAG)' -o ${OBSERVABILITY_OPS_SERVER_BINARY} cmd/opsserver/*.go
	@echo "build ops-server successfully."

task-collector:
	@echo "build task-collector start."
	$(GOBUILD) $(RACE_FLAG) -ldflags '$(LDFLAGS) $(CHECK_FLAG)' -o ${OBSERVABILITY_REGIONAL_TASK_COLLECTOR_BINARY} cmd/taskcollector/*.go
	@echo "build task-collector successfully."

mock_metrics:
	@echo "build mock-metrics-server start."
	$(GOBUILD) $(RACE_FLAG) -ldflags '$(LDFLAGS) $(CHECK_FLAG)' -o ${MOCK_METRICS_SERVER_BINARY} cmd/mockmetricsserver/*.go
	@echo "build regional-server successfully."

#2. R&D to test the code themselves for compliance before submitting it
devselfcheck:
	#cat resource/prchecklist.md
	make gotool
	@echo "start self check."
	make check_fmt
	make check_goword
	make check_static
	make check_unconvert
	make check_lint
	make check_vet
	make test
	@echo "self check complete."

gotool:
	@echo "build compilation toolchain start."
	make build_revive
	make build_goword
	make build_unconvert
	make build_failpoint_ctl
	make build_errdoc_gen
	make build_golangci_lint
	make build_vfsgendev
	@echo "build compilation toolchain successfully."

check_fmt:
	@echo "gofmt (simplify)"
	#@gofmt -s -l -w $(FILES) 2>&1 | $(FAIL_ON_STDOUT)

check_goword:
	@echo "goword check, files: ${FILES}"
	#${BINARY_DIR}/goword $(FILES) 2>&1 | $(FAIL_ON_STDOUT)

check_static:
	@echo "code static check, files: $($(PACKAGE_LIST))"
	#${BINARY_DIR}/golangci-lint run -v $$($(PACKAGE_DIRECTORIES))

check_unconvert:
	@echo "unconvert check, files: $($(PACKAGE_LIST))"
	#@GO111MODULE=on ${BINARY_DIR}/unconvert $(UNCONVERT_PACKAGES)

check_lint:
	@echo "linting check"
	#@${BINARY_DIR}/revive -formatter friendly -config build_helper/revive.toml $(FILES_WITHOUT_BR)

check_vet:
	@echo "vet check"
	#$(GO) vet -all $(PACKAGES_WITHOUT_BR) 2>&1 | $(FAIL_ON_STDOUT)

install:
	mkdir -p ${INSTALL_PREFIX}
	mkdir -p ${INSTALL_PREFIX}/bin
	mkdir -p ${INSTALL_PREFIX}/etc
	mkdir -p ${INSTALL_PREFIX}/logs
	mkdir -p ${INSTALL_PREFIX}/scripts
	mkdir -p ${INSTALL_PREFIX}/docs
	cp ${OBSERVABILITY_GLOBAL_SERVER_BINARY} ${INSTALL_PREFIX}/bin
	cp ${OBSERVABILITY_REGIONAL_SERVER_BINARY} ${INSTALL_PREFIX}/bin
	cp ${OBSERVABILITY_REGIONAL_DATA_SERVER_BINARY} ${INSTALL_PREFIX}/bin
	cp ${OBSERVABILITY_OPS_SERVER_BINARY} ${INSTALL_PREFIX}/bin
	cp ${MOCK_METRICS_SERVER_BINARY} ${INSTALL_PREFIX}/bin

uninstall:
	@echo "uninstall: remove all files in $(INSTALL_PREFIX)"
	@if [ -d ${INSTALL_PREFIX} ] ; then rm ${INSTALL_PREFIX} ; fi

clean:
	@if [ -f ${OBSERVABILITY_GLOBAL_SERVER_BINARY} ] ; then rm ${OBSERVABILITY_GLOBAL_SERVER_BINARY} ; fi
	@if [ -f ${OBSERVABILITY_REGIONAL_SERVER_BINARY} ] ; then rm ${OBSERVABILITY_REGIONAL_SERVER_BINARY} ; fi
	@if [ -f ${OBSERVABILITY_REGIONAL_DATA_SERVER_BINARY} ] ; then rm ${OBSERVABILITY_REGIONAL_DATA_SERVER_BINARY} ; fi
	@if [ -f ${OBSERVABILITY_OPS_SERVER_BINARY} ] ; then rm ${OBSERVABILITY_OPS_SERVER_BINARY} ; fi
	@if [ -f ${MOCK_METRICS_SERVER_BINARY} ] ; then rm ${MOCK_METRICS_SERVER_BINARY} ; fi
	@if [ -f ${BINARY_DIR}/revive ] ; then rm ${BINARY_DIR}/revive ; fi
	@if [ -f ${BINARY_DIR}/goword ] ; then rm ${BINARY_DIR}/goword ; fi
	@if [ -f ${BINARY_DIR}/unconvert ] ; then rm ${BINARY_DIR}/unconvert ; fi
	@if [ -f ${BINARY_DIR}/failpoint-ctl ] ; then rm ${BINARY_DIR}/failpoint-ctl; fi
	@if [ -f ${BINARY_DIR}/vfsgendev ] ; then rm ${BINARY_DIR}/vfsgendev; fi
	@if [ -f ${BINARY_DIR}/golangci-lint ] ; then rm ${BINARY_DIR}/golangci-lint; fi
	@if [ -f ${BINARY_DIR}/errdoc-gen ] ; then rm ${BINARY_DIR}/errdoc-gen; fi
	##@if [ -d ${GENERATE_TARGET_DIR}/clusterservices ] ; then rm -rf ${GENERATE_TARGET_DIR}/clusterservices; fi
	@if [ -d ${CURDIR}/test ] ; then rm -rf ${CURDIR}/test; fi

help:
	@echo "make build, build binary for all servers"
	@echo "make install, install binary to target "
	@echo "make uninstall, uninstall binary from target "
	@echo "make devselfcheck, dev commit code prechecked."
	@echo "make test, test all case"
	@echo "make upload_coverage, upload coverage information"
	@echo "make reviewable before push code to github"

upload_coverage:
#	GO111MODULE=off go get github.com/wadey/gocovmerge
#	gocovmerge "$(TEST_DIR)"/cov.* | grep -vE ".*.pb.go" > "$(TEST_DIR)/all_cov.out"
	grep -vE ".*.pb.go" "$(TEST_DIR)/cov.unit.out" > "$(TEST_DIR)/unit_cov.out"
ifeq ("$(JenkinsCI)", "1")
#	GO111MODULE=off go get github.com/mattn/goveralls
#	@goveralls -coverprofile=$(TEST_DIR)/all_cov.out -service=jenkins-ci -repotoken $(COVERALLS_TOKEN)
	curl -s https://codecov.io/bash > $(CODECOV_BASH)
	bash $(CODECOV_BASH) -f $(TEST_DIR)/unit_cov.out -t $(CODECOV_TOKEN)
else
	go tool cover -html "$(TEST_DIR)/all_cov.out" -o "$(TEST_DIR)/all_cov.html"
	go tool cover -html "$(TEST_DIR)/unit_cov.out" -o "$(TEST_DIR)/unit_cov.html"
	go tool cover -func="$(TEST_DIR)/unit_cov.out"
endif

# don't run it locally, only for CI, use `make test` instead
ci_test: add_test_file prepare proto build mock
	go install github.com/jstemmer/go-junit-report@latest
	$(GO) install github.com/boumenot/gocover-cobertura@v1.5.0
	$(GO) install gotest.tools/gotestsum@latest
	@-(gotestsum --junitfile ./unit-tests.xml --packages=${PACKAGES})
	-go test -v ${PACKAGES} -coverprofile=cover.out
	gocover-cobertura < cover.out > coverage.xml

test: prepare proto build lint
	mkdir -p "$(TEST_DIR)"
	$(GO) install gotest.tools/gotestsum@latest
	@-(gotestsum --junitfile "$(TEST_DIR)/unit-tests.xml" --packages=${PACKAGES})
	-go test -v ${PACKAGES} -coverprofile="$(TEST_DIR)/cover.out"
	go tool cover -html "$(TEST_DIR)/cover.out" -o "$(TEST_DIR)/cover.html"
	@echo "check ut results in $(TEST_DIR)/unit-tests.xml"
	@echo "check ut coverage by opening $(TEST_DIR)/cover.html using browser"

# build e2e test binary file
e2e:
	$(GO)  test -c -tags e2e ./test/ft/cases -o build/bin/cases.test

e2e_delete_ft_ns:
	$(GO)  test -c -tags e2e ./test/ft/deleteftns -o build/bin/delete.ftns

#build datalink test binary file
datalink:
	$(GO)  test -c -tags e2e ./test/ft/datalink -o build/bin/datalink.test


# build logscheck test binary file
logs:
	$(GO)  test -c -tags logs ./test/ft/logscheck -o build/bin/logscheck.test

# build datacheck test binary file
datacheck:
	$(GO)  test -c -tags datacheck ./test/ft/datacheck -o build/bin/datacheck.test

# build datacheck-nextgen test binary file
datacheck-nextgen:
	$(GO)  test -c -tags datacheck-nextgen ./test/ft/datacheck-nextgen -o build/bin/datacheck-nextgen.test

# build dedicatede2e test binary file
dedicatede2e:
	$(GO)  test -c -tags datacheck ./test/ft/dedicatede2e -o build/bin/dedicatede2e.test


#race: failpoint-enable
#   @export log_level=debug; \
#	$(GOTEST) -timeout 20m -race $(PACKAGES) || { $(FAILPOINT_DISABLE); exit 1; }
#	@$(FAILPOINT_DISABLE)
#
#leak: failpoint-enable
#	@export log_level=debug; \
#	$(GOTEST) -tags leak $(PACKAGES) || { $(FAILPOINT_DISABLE); exit 1; }
#	@$(FAILPOINT_DISABLE)
#

failpoint-enable: build_failpoint_ctl
# Converting gofail failpoints...
	@$(FAILPOINT_ENABLE)

failpoint-disable: build_failpoint_ctl
# Restoring gofail failpoints...
	@$(FAILPOINT_DISABLE)

lint: mock
	$(GO) install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@$(GOLANGCI_LINT_VERSION)
	$(GO_LINT_ENV) golangci-lint run --fix -v $(LINT_PACKAGES) --config .golangci.yml
	$(GO_LINT_ENV) golangci-lint run --build-tags e2e,logs,datacheck,dedicatede2e --fix -v test/ft/... --config .golangci.yml
	$(GO_LINT_ENV) golangci-lint run --build-tags service --fix -v test/ft/... --config .golangci.yml

# don't run it locally, only for CI, use `make gosec` instead
ci_gosec:
	$(GO) install github.com/securego/gosec/v2/cmd/gosec@latest
	gosec -fmt=junit-xml -out=gosec-results.xml -stdout -verbose=text -exclude-dir="agent-control-server/*|data-collector/*|vm-bench/*" -exclude=G103,G104,G204,G304,G307,G401,G404,G501,G505,G601 ./...

gosec:
	mkdir -p "$(TEST_DIR)"
	$(GO) install github.com/securego/gosec/v2/cmd/gosec@latest
	gosec -fmt=junit-xml -out="$(TEST_DIR)/gosec-results.xml" -stdout -verbose=text -exclude-dir="agent-control-server/*|data-collector/*|vm-bench/*" -exclude=G103,G104,G204,G304,G307,G401,G404,G501,G505,G601 ./...
	echo "check gosec result by opening $(TEST_DIR)/gosec-results.xml"

add_test_file:
	build/ci/add_test_file.sh

mock:
	$(GO) install go.uber.org/mock/mockgen@latest
	rm -rf ./test/mockmetamanager/
	rm -rf ./test/mockresourcemanager/
	rm -rf ./test/mockresourceworker/
	mockgen -destination ./test/mockmetamanager/mock_logical_router.go -package mock_meta_manager -source ./pkg/globalservice/logical_router.go
	mockgen -destination ./test/mockmetamanager/mock_meta_manager.go -package mock_meta_manager -source ./pkg/metamanager/interface.go
	mockgen -destination ./test/mockmetamanager/mock_meta_cache_getter.go -package mock_meta_manager -source ./pkg/globalservice/manager.go
	mockgen -destination ./test/mockresourcemanager/mock_rw.go  -source ./pkg/resourcemanager/interface.go -package mockresourcemanager
	mockgen -destination ./test/mockresourceworker/providers/aws/mocks.go -source ./pkg/resourceworker/providers/aws/awsinterface.go  -package mock_awsclient
	mockgen -destination ./test/mockresourceworker/providers/azure/mocks.go -source ./pkg/resourceworker/providers/azure/interfaces.go  -package mock_azureclient
	mockgen -destination ./test/mockresourceworker/providers/gcp/gcs/mocks.go -source ./pkg/resourceworker/providers/gcp/gcs/gcswrap.go  -package mock_gcsclient
	mockgen -destination ./test/mockresourceworker/providers/gcp/psc/mocks.go -source ./pkg/resourceworker/providers/gcp/psc/pscwrap.go  -package mock_pscclient
	mockgen -destination ./test/mockresourceworker/providers/alicloud/mocks.go -source ./pkg/resourceworker/providers/alicloud/aliinterface.go  -package mock_aliclient
	mockgen -destination ./test/mockresourceworker/providers/mocks.go -source ./pkg/resourceworker/providers/interface.go  -package mock_prodiders
	mockgen -destination ./test/mocko11ydiagnosis/pkg/utils/duckdb/mocks.go -source ./o11ydiagnosis/pkg/utils/duckdb/duckdb_query.go  -package mock_o11ydiagnosis
	mockgen -destination ./test/mocko11ydiagnosis/pkg/utils/metacache/mocks.go -source ./o11ydiagnosis/pkg/utils/metacache/metacache.go  -package mock_o11ydiagnosis

swag:
	$(GO) install github.com/swaggo/swag/cmd/swag@v1.6.7
	$(GO_MODULE_ENV) swag init -g cmd/globalserver/main.go --exclude pkg/regionalapi,pkg/opsapi,agent-control-server,pkg/dataapi,o11ydiagnosis,o11ymetering,data-collector -o api/globalserverswagger
	$(GO_MODULE_ENV) swag init -g cmd/regionalserver/main.go --exclude pkg/globalapi,pkg/opsapi,agent-control-server,pkg/dataapi,o11ydiagnosis,o11ymetering,data-collector -o api/regionalserverswagger
	$(GO_MODULE_ENV) swag init -g cmd/opsserver/main.go --exclude pkg/globalapi,pkg/regionalapi,agent-control-server,pkg/dataapi,o11ydiagnosis,o11ymetering,data-collector -o api/opsserverswagger
	$(GO_MODULE_ENV) swag init -g cmd/diagnosis-query/main.go --exclude pkg/globalapi,pkg/regionalapi,pkg/opsapi,pkg/dataapi,agent-control-server,data-collector,sli-reporter,o11ymetering,o11ydiagnosis/pkg/topsql -o api/diagnosisqueryswagger

reviewable: generate manifests swag lint
	$(GO_MODULE_ENV) go mod tidy
	git diff --exit-code

##@ ResourceWorker Development

.PHONY: manifests
manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects.
	$(GO_MODULE_ENV) $(CONTROLLER_GEN) rbac:roleName=regional-server-manager-role crd webhook paths="{./api/..., ./pkg/...}" output:artifacts:config=deployments/regional-server/regional-server/common
	bash ./deployments/regional-server/regional-server/sync-chart-artifacts.sh

.PHONY: generate
generate: controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations.
	$(GO_MODULE_ENV) $(CONTROLLER_GEN)  object:headerFile="hack/boilerplate.go.txt" paths="{./api/..., ./pkg/...}"
##@ ResourceWorker Build Dependencies
.PHONY: install_crd
install_crd: manifests kustomize ## Install CRDs into the K8s cluster specified in ~/.kube/config.
	$(KUSTOMIZE) build config/regionalserver/resourceworker/crd | kubectl apply -f -

.PHONY: uninstall_crd
uninstall_crd: manifests kustomize ## Uninstall CRDs from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion.
	$(KUSTOMIZE) build config/regionalserver/resourceworker/crd  | kubectl delete --ignore-not-found=$(ignore-not-found) -f -

## Location to install dependencies to
LOCALBIN ?= $(shell pwd)/bin
$(LOCALBIN):
	mkdir -p $(LOCALBIN)

## Tool Binaries
KUSTOMIZE ?= $(LOCALBIN)/kustomize
CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen
ENVTEST ?= $(LOCALBIN)/setup-envtest

## Tool Versions
KUSTOMIZE_VERSION ?= v4.5.5
CONTROLLER_TOOLS_VERSION ?= v0.17.3

KUSTOMIZE_INSTALL_SCRIPT ?= "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh"
.PHONY: kustomize
kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary.
$(KUSTOMIZE): $(LOCALBIN)
	curl -s $(KUSTOMIZE_INSTALL_SCRIPT) | bash -s -- $(subst v,,$(KUSTOMIZE_VERSION)) $(LOCALBIN)

.PHONY: controller-gen
controller-gen: $(CONTROLLER_GEN) ## Download controller-gen locally if necessary.
$(CONTROLLER_GEN): $(LOCALBIN)
	GOBIN=$(LOCALBIN) $(GO_MODULE_ENV) go install sigs.k8s.io/controller-tools/cmd/controller-gen@$(CONTROLLER_TOOLS_VERSION)

.PHONY: envtest
envtest: $(ENVTEST) ## Download envtest-setup locally if necessary.
$(ENVTEST): $(LOCALBIN)
	GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest
