@@ -37,8 +37,12 @@ checkhash_script := $(dir $(lastword $(MAKEFILE_LIST)))/util/checkhash.sh
3737lock_script := $(dir $(lastword $(MAKEFILE_LIST ) ) ) /util/lock.sh
3838
3939# $outfile is a variable in the lock script
40+ # Escape the dollar sign so it's passed literally to the shell script, not expanded by make
4041outfile := $$outfile
4142
43+ # Helper function to iterate over key=value pairs and call a function for each pair
44+ # Usage: $(call for_each_kv,function_name,list_of_key=value_pairs)
45+ # For each item, splits on "=" and calls function_name with key as $1 and value as $2
4246for_each_kv = $(foreach item,$2,$(eval $(call $1,$(word 1,$(subst =, ,$(item ) ) ) ,$(word 2,$(subst =, ,$(item ) ) ) ) ) )
4347
4448# To make sure we use the right version of each tool, we put symlink in
@@ -77,7 +81,7 @@ tools += vault=v1.21.1
7781tools += azwi=v1.5.1
7882# https://github.com/kyverno/kyverno/releases
7983# renovate: datasource=github-releases packageName=kyverno/kyverno
80- tools += kyverno=v1.16.0
84+ tools += kyverno=v1.16.1
8185# https://github.com/mikefarah/yq/releases
8286# renovate: datasource=github-releases packageName=mikefarah/yq
8387tools += yq=v4.49.2
@@ -89,7 +93,7 @@ tools += ko=0.18.0
8993tools += protoc=v33.1
9094# https://github.com/aquasecurity/trivy/releases
9195# renovate: datasource=github-releases packageName=aquasecurity/trivy
92- tools += trivy=v0.67.2
96+ tools += trivy=v0.68.1
9397# https://github.com/vmware-tanzu/carvel-ytt/releases
9498# renovate: datasource=github-releases packageName=vmware-tanzu/carvel-ytt
9599tools += ytt=v0.52.1
@@ -118,7 +122,7 @@ tools += gotestsum=v1.13.0
118122tools += kustomize=v5.8.0
119123# https://pkg.go.dev/github.com/itchyny/gojq?tab=versions
120124# renovate: datasource=go packageName=github.com/itchyny/gojq
121- tools += gojq=v0.12.17
125+ tools += gojq=v0.12.18
122126# https://pkg.go.dev/github.com/google/go-containerregistry/pkg/crane?tab=versions
123127# renovate: datasource=go packageName=github.com/google/go-containerregistry
124128tools += crane=v0.20.7
@@ -226,6 +230,8 @@ print-go-version:
226230
227231# When switching branches which use different versions of the tools, we
228232# need a way to re-trigger the symlinking from $(bin_dir)/downloaded to $(bin_dir)/tools.
233+ # This pattern rule creates a version stamp file that tracks the tool version.
234+ # If the version changes (or file doesn't exist), update the stamp file to trigger rebuild.
229235$(bin_dir ) /scratch/% _VERSION : FORCE | $(bin_dir ) /scratch
230236 @test " $( $* _VERSION) " == " $( shell cat $@ 2> /dev/null) " || echo $($* _VERSION) > $@
231237
@@ -247,7 +253,11 @@ CURL := curl --silent --show-error --fail --location --retry 10 --retry-connrefu
247253# -n = If destination already exists, replace it, don't use it as a directory to create a new link inside
248254LN := ln -fsn
249255
256+ # Mapping of lowercase to uppercase letters for the uc (uppercase) function
250257upper_map := a:A b:B c:C d:D e:E f:F g:G h:H i:I j:J k:K l:L m:M n:N o:O p:P q:Q r:R s:S t:T u:U v:V w:W x:X y:Y z:Z
258+ # Function to convert a string to uppercase (e.g., "helm" -> "HELM")
259+ # Works by iterating through upper_map and substituting each lowercase letter with uppercase
260+ # Used to create variable names like HELM_VERSION from tool names like "helm"
251261uc = $(strip \
252262 $(eval __upper := $1) \
253263 $(foreach p,$(upper_map ) , \
@@ -281,11 +291,16 @@ $(call uc,$1)_VERSION ?= $2
281291NEEDS_$(call uc,$1) := $$(bin_dir ) /tools/$1
282292$(call uc,$1) := $$(CURDIR ) /$$(bin_dir ) /tools/$1
283293
294+ # Create symlink from $(bin_dir)/tools/$1 to the versioned binary in $(DOWNLOAD_DIR)
284295$$(bin_dir ) /tools/$1: $$(bin_dir ) /scratch/$(call uc,$1) _VERSION | $$(DOWNLOAD_DIR ) /tools/$1@$$($(call uc,$1) _VERSION) _$$(HOST_OS ) _$$(HOST_ARCH ) $$(bin_dir ) /tools
296+ @
# cd into tools dir and create relative symlink (e.g., ../downloaded/tools/[email protected] _darwin_arm64)297+ @# patsubst converts absolute path to relative by replacing $(bin_dir) with ..
285298 @cd $$(dir $$@ ) && $$(LN ) $$(patsubst $$(bin_dir ) /% ,../% ,$$(word 1,$$|) ) $$(notdir $$@ )
286299 @touch $$@ # making sure the target of the symlink is newer than *_VERSION
287300endef
288301
302+ # For each tool in the tools list (e.g., "helm=v4.0.1"), split on "=" and call tool_defs
303+ # with the tool name as first arg and version as second arg
289304$(foreach tool,$(tools),$(eval $(call tool_defs,$(word 1,$(subst =, ,$(tool))),$(word 2,$(subst =, ,$(tool))))))
290305
291306# #####
@@ -303,6 +318,9 @@ $(foreach tool,$(tools),$(eval $(call tool_defs,$(word 1,$(subst =, ,$(tool))),$
303318# to $(bin_dir)/tools/go, since $(bin_dir)/tools/go is a prerequisite of
304319# any target depending on Go when "make vendor-go" was run.
305320
321+ # Auto-detect if Go vendoring should be enabled:
322+ # - Set if "vendor-go" is in the make command goals, OR
323+ # - Set if $(bin_dir)/tools/go already exists (vendoring was previously run)
306324detected_vendoring := $(findstring vendor-go,$(MAKECMDGOALS ) )$(shell [ -f $(bin_dir ) /tools/go ] && echo yes)
307325export VENDOR_GO ?= $(detected_vendoring )
308326
@@ -346,16 +364,22 @@ which-go: | $(NEEDS_GO)
346364 @echo " go binary used for above version information: $( GO) "
347365
348366$(bin_dir ) /tools/go : $(bin_dir ) /scratch/VENDORED_GO_VERSION | $(bin_dir ) /tools/goroot $(bin_dir ) /tools
367+ @# Create symlink to the go binary inside the goroot
349368 @cd $(dir $@ ) && $(LN ) ./goroot/bin/go $(notdir $@ )
350369 @touch $@ # making sure the target of the symlink is newer than *_VERSION
351370
352371# The "_" in "_bin" prevents "go mod tidy" from trying to tidy the vendored goroot.
353372$(bin_dir ) /tools/goroot : $(bin_dir ) /scratch/VENDORED_GO_VERSION | $(GOVENDOR_DIR ) /go@$(VENDORED_GO_VERSION ) _$(HOST_OS ) _$(HOST_ARCH ) /goroot $(bin_dir ) /tools
373+ @# Create relative symlink from $(bin_dir)/tools/goroot to $(GOVENDOR_DIR)/...
374+ @
# patsubst converts the absolute path to relative (e.g., ../../go_vendor/[email protected] _darwin_arm64/goroot)354375 @cd $(dir $@ ) && $(LN ) $(patsubst $(bin_dir ) /% ,../% ,$(word 1,$|) ) $(notdir $@ )
355376 @touch $@ # making sure the target of the symlink is newer than *_VERSION
356377
357378# Extract the tar to the $(GOVENDOR_DIR) directory, this directory is not cached across CI runs.
358379$(GOVENDOR_DIR ) /go@$(VENDORED_GO_VERSION ) _$(HOST_OS ) _$(HOST_ARCH ) /goroot : | $(DOWNLOAD_DIR ) /tools/go@$(VENDORED_GO_VERSION ) _$(HOST_OS ) _$(HOST_ARCH ) .tar.gz
380+ @# 1. Use lock script to prevent concurrent extraction
381+ @# 2. Extract tar.gz to temp directory (creates "go" folder inside)
382+ @# 3. Rename the extracted "go" directory to final location
359383 @source $(lock_script ) $@ ; \
360384 mkdir -p $(outfile ) .dir; \
361385 tar xzf $| -C $(outfile ) .dir; \
@@ -425,9 +449,13 @@ $(call for_each_kv,go_tags_defs,$(go_tags))
425449
426450go_tool_names :=
427451
452+ # Template for building Go-based tools from source using "go install"
428453define go_dependency
429454go_tool_names += $1
430455$$(DOWNLOAD_DIR ) /tools/$1@$($(call uc,$1) _VERSION) _$(HOST_OS ) _$(HOST_ARCH ) : | $$(NEEDS_GO ) $$(DOWNLOAD_DIR ) /tools
456+ @# 1. Use lock script to prevent concurrent builds of the same tool
457+ @# 2. Install to temp dir using GOBIN, with GOWORK=off to ignore workspace files
458+ @# 3. Move the binary to final location
431459 @source $$(lock_script ) $$@ ; \
432460 mkdir -p $$(outfile ) .dir; \
433461 GOWORK=off GOBIN=$$(outfile ) .dir $$(GO ) install --tags "$(strip $(go_tags_$1 ) ) " $2@$($(call uc,$1) _VERSION) ; \
@@ -528,20 +556,23 @@ $(DOWNLOAD_DIR)/tools/kubebuilder_tools_$(KUBEBUILDER_ASSETS_VERSION)_$(HOST_OS)
528556 $(checkhash_script ) $(outfile ) $(kubebuilder_tools_$(HOST_OS ) _$(HOST_ARCH ) _SHA256SUM )
529557
530558$(DOWNLOAD_DIR ) /tools/etcd@$(KUBEBUILDER_ASSETS_VERSION ) _$(HOST_OS ) _$(HOST_ARCH ) : $(DOWNLOAD_DIR ) /tools/kubebuilder_tools_$(KUBEBUILDER_ASSETS_VERSION ) _$(HOST_OS ) _$(HOST_ARCH ) .tar.gz | $(DOWNLOAD_DIR ) /tools
559+ @# Extract specific file from tarball using tar's -O flag (output to stdout)
531560 @source $(lock_script ) $@ ; \
532561 tar xfO $< controller-tools/envtest/etcd > $(outfile ) && chmod 775 $(outfile )
533562
534563$(DOWNLOAD_DIR ) /tools/kube-apiserver@$(KUBEBUILDER_ASSETS_VERSION ) _$(HOST_OS ) _$(HOST_ARCH ) : $(DOWNLOAD_DIR ) /tools/kubebuilder_tools_$(KUBEBUILDER_ASSETS_VERSION ) _$(HOST_OS ) _$(HOST_ARCH ) .tar.gz | $(DOWNLOAD_DIR ) /tools
564+ @# Extract specific file from tarball using tar's -O flag (output to stdout)
535565 @source $(lock_script ) $@ ; \
536566 tar xfO $< controller-tools/envtest/kube-apiserver > $(outfile ) && chmod 775 $(outfile )
537567
538- kyverno_linux_amd64_SHA256SUM =edb9ec84406704a39e6eced5089df2da75c81dde3d8422255af294bd5e0bc52f
539- kyverno_linux_arm64_SHA256SUM =c7897ad466917f0c5a3cc5bb39142929388f739e20bb9e7e3cd422ef90214973
540- kyverno_darwin_amd64_SHA256SUM =c6f7052569527498728d8c19551fa985378107c785391c6d601d1aa452bbb101
541- kyverno_darwin_arm64_SHA256SUM =cac8aefd5de5e23431dc8f1a7d0acf8233ce66462446f23f2d5575cafedcf7b8
568+ kyverno_linux_amd64_SHA256SUM =0c0216e4c3bb535eaf94ea1c2e13e4d66f7be2ec6446c37aee6c3133650167e7
569+ kyverno_linux_arm64_SHA256SUM =c1d349a272c2adf1bc9d2caf23a354ff4edc10687664c7a04da6fb84ce502c20
570+ kyverno_darwin_amd64_SHA256SUM =7985d522952e88adf7f21058439099b0e27c099baab0589b3a501862daebe842
571+ kyverno_darwin_arm64_SHA256SUM =25a704a74683a3da5bb50cb9e7a11a4df686121674d1271f49c0261618c94f1d
542572
543573.PRECIOUS : $(DOWNLOAD_DIR ) /tools/kyverno@$(KYVERNO_VERSION ) _$(HOST_OS ) _$(HOST_ARCH )
544574$(DOWNLOAD_DIR ) /tools/kyverno@$(KYVERNO_VERSION ) _$(HOST_OS ) _$(HOST_ARCH ) : | $(DOWNLOAD_DIR ) /tools
575+ @# Kyverno uses x86_64 instead of amd64 in download URLs, so translate the architecture
545576 $(eval ARCH := $(subst amd64,x86_64,$(HOST_ARCH ) ) )
546577
547578 @source $(lock_script) $@; \
@@ -570,6 +601,7 @@ ko_darwin_arm64_SHA256SUM=2efa5796986e38994a3a233641b98404fa071a76456e3c99b3c00d
570601
571602.PRECIOUS : $(DOWNLOAD_DIR ) /tools/ko@$(KO_VERSION ) _$(HOST_OS ) _$(HOST_ARCH )
572603$(DOWNLOAD_DIR ) /tools/ko@$(KO_VERSION ) _$(HOST_OS ) _$(HOST_ARCH ) : | $(DOWNLOAD_DIR ) /tools
604+ @# Ko uses capitalized OS names (Linux/Darwin) and x86_64 instead of amd64
573605 $(eval OS := $(subst linux,Linux,$(subst darwin,Darwin,$(HOST_OS ) ) ) )
574606 $(eval ARCH := $(subst amd64,x86_64,$(HOST_ARCH ) ) )
575607
@@ -587,6 +619,7 @@ protoc_darwin_arm64_SHA256SUM=db7e66ff7f9080614d0f5505a6b0ac488cf89a15621b6a3616
587619
588620.PRECIOUS : $(DOWNLOAD_DIR ) /tools/protoc@$(PROTOC_VERSION ) _$(HOST_OS ) _$(HOST_ARCH )
589621$(DOWNLOAD_DIR ) /tools/protoc@$(PROTOC_VERSION ) _$(HOST_OS ) _$(HOST_ARCH ) : | $(DOWNLOAD_DIR ) /tools
622+ @# Protoc uses different naming: darwin->osx, amd64->x86_64, arm64->aarch_64
590623 $(eval OS := $(subst darwin,osx,$(HOST_OS ) ) )
591624 $(eval ARCH := $(subst arm64,aarch_64,$(subst amd64,x86_64,$(HOST_ARCH ) ) ) )
592625
@@ -597,13 +630,14 @@ $(DOWNLOAD_DIR)/tools/protoc@$(PROTOC_VERSION)_$(HOST_OS)_$(HOST_ARCH): | $(DOWN
597630 chmod +x $(outfile); \
598631 rm -f $(outfile).zip
599632
600- trivy_linux_amd64_SHA256SUM =546511a5514afc813c0b72e4abeea2c16a32228a13a1e5114d927c190e76b1f9
601- trivy_linux_arm64_SHA256SUM =e4f28390b06cdaaed94f8c49cce2c4c847938b5188aefdeb82453f2e933e57cb
602- trivy_darwin_amd64_SHA256SUM =4a5b936a8d89b508ecdc6edd65933b6fe3e9a368796cbdf917fd0df393f26542
603- trivy_darwin_arm64_SHA256SUM =6b3163667f29fc608a2ed647c1bd42023af5779349286148190a168c5b3f28f1
633+ trivy_linux_amd64_SHA256SUM =63e37242088e418651931f891963c19554faa19f0591fe6b40b606152051df2f
634+ trivy_linux_arm64_SHA256SUM =b29ea550f573afbcae3c86fb2b5e0ebba76b7cb0965e3787c4e8cb884d2c1d57
635+ trivy_darwin_amd64_SHA256SUM =d5b5bd3b3c3626d223c3981cc40f4709f00a6327a681b588d2fc64a3aa9d02c5
636+ trivy_darwin_arm64_SHA256SUM =4dd3d2e74e1b6f6f7fd5fbf55489727698f586d6a6a0cff3421031a05b80bcac
604637
605638.PRECIOUS : $(DOWNLOAD_DIR ) /tools/trivy@$(TRIVY_VERSION ) _$(HOST_OS ) _$(HOST_ARCH )
606639$(DOWNLOAD_DIR ) /tools/trivy@$(TRIVY_VERSION ) _$(HOST_OS ) _$(HOST_ARCH ) : | $(DOWNLOAD_DIR ) /tools
640+ @# Trivy uses unusual naming: Linux/macOS for OS, 64bit/ARM64 for architecture
607641 $(eval OS := $(subst linux,Linux,$(subst darwin,macOS,$(HOST_OS ) ) ) )
608642 $(eval ARCH := $(subst amd64,64bit,$(subst arm64,ARM64,$(HOST_ARCH ) ) ) )
609643
@@ -633,6 +667,7 @@ rclone_darwin_arm64_SHA256SUM=8396a06f793668da6cf0d8cf2e6a2da4c971bcbc7584286ffd
633667
634668.PRECIOUS : $(DOWNLOAD_DIR ) /tools/rclone@$(RCLONE_VERSION ) _$(HOST_OS ) _$(HOST_ARCH )
635669$(DOWNLOAD_DIR ) /tools/rclone@$(RCLONE_VERSION ) _$(HOST_OS ) _$(HOST_ARCH ) : | $(DOWNLOAD_DIR ) /tools
670+ @# Rclone uses "osx" instead of "darwin" in download URLs
636671 $(eval OS := $(subst darwin,osx,$(HOST_OS ) ) )
637672
638673 @source $(lock_script) $@; \
@@ -649,6 +684,7 @@ istioctl_darwin_arm64_SHA256SUM=593f8d58571ff4cddcd069041d2c398da4e0d6fc80558907
649684
650685.PRECIOUS : $(DOWNLOAD_DIR ) /tools/istioctl@$(ISTIOCTL_VERSION ) _$(HOST_OS ) _$(HOST_ARCH )
651686$(DOWNLOAD_DIR ) /tools/istioctl@$(ISTIOCTL_VERSION ) _$(HOST_OS ) _$(HOST_ARCH ) : | $(DOWNLOAD_DIR ) /tools
687+ @# Istio uses "osx" instead of "darwin" in download URLs
652688 $(eval OS := $(subst darwin,osx,$(HOST_OS ) ) )
653689
654690 @source $(lock_script) $@; \
@@ -695,6 +731,9 @@ $(DOWNLOAD_DIR)/tools/operator-sdk@$(OPERATOR-SDK_VERSION)_$(HOST_OS)_$(HOST_ARC
695731# about go being missing even though abc itself depends on vendor-go!
696732# That means we need to pass vendor-go at the top level if go is not installed (i.e. "make vendor-go abc")
697733
734+ # Check for required system tools by testing if each command exists
735+ # If a command is missing, echo its name. The && chains mean all tests run,
736+ # and "missing" will contain a space-separated list of any missing tools.
698737missing =$(shell (command -v curl >/dev/null || echo curl) \
699738 && (command -v sha256sum >/dev/null || command -v shasum >/dev/null || echo sha256sum) \
700739 && (command -v git >/dev/null || echo git) \
0 commit comments