github.com/kastenhq/syft@v0.0.0-20230821225854-0710af25cdbe/Makefile (about) 1 BIN := syft 2 TEMP_DIR := ./.tmp 3 4 # Command templates ################################# 5 LINT_CMD := $(TEMP_DIR)/golangci-lint run --tests=false 6 GOIMPORTS_CMD := $(TEMP_DIR)/gosimports -local github.com/anchore 7 RELEASE_CMD := $(TEMP_DIR)/goreleaser release --clean 8 SNAPSHOT_CMD := $(RELEASE_CMD) --skip-publish --skip-sign --snapshot 9 CHRONICLE_CMD = $(TEMP_DIR)/chronicle 10 GLOW_CMD = $(TEMP_DIR)/glow 11 12 # Tool versions ################################# 13 GOLANGCILINT_VERSION := v1.53.3 14 GOSIMPORTS_VERSION := v0.3.8 15 BOUNCER_VERSION := v0.4.0 16 CHRONICLE_VERSION := v0.7.0 17 GORELEASER_VERSION := v1.19.2 18 YAJSV_VERSION := v1.4.1 19 COSIGN_VERSION := v2.1.1 20 QUILL_VERSION := v0.2.0 21 GLOW_VERSION := v1.5.1 22 23 # Formatting variables ################################# 24 BOLD := $(shell tput -T linux bold) 25 PURPLE := $(shell tput -T linux setaf 5) 26 GREEN := $(shell tput -T linux setaf 2) 27 CYAN := $(shell tput -T linux setaf 6) 28 RED := $(shell tput -T linux setaf 1) 29 RESET := $(shell tput -T linux sgr0) 30 TITLE := $(BOLD)$(PURPLE) 31 SUCCESS := $(BOLD)$(GREEN) 32 33 # Test variables ################################# 34 COMPARE_DIR := ./test/compare 35 COMPARE_TEST_IMAGE := centos:8.2.2004 36 COVERAGE_THRESHOLD := 62 # the quality gate lower threshold for unit test total % coverage (by function statements) 37 38 ## Build variables ################################# 39 VERSION := $(shell git describe --dirty --always --tags) 40 DIST_DIR := ./dist 41 SNAPSHOT_DIR := ./snapshot 42 CHANGELOG := CHANGELOG.md 43 OS := $(shell uname | tr '[:upper:]' '[:lower:]') 44 SNAPSHOT_BIN := $(realpath $(shell pwd)/$(SNAPSHOT_DIR)/$(OS)-build_$(OS)_amd64_v1/$(BIN)) 45 46 ifndef VERSION 47 $(error VERSION is not set) 48 endif 49 50 define title 51 @printf '$(TITLE)$(1)$(RESET)\n' 52 endef 53 54 define safe_rm_rf 55 bash -c 'test -z "$(1)" && false || rm -rf $(1)' 56 endef 57 58 define safe_rm_rf_children 59 bash -c 'test -z "$(1)" && false || rm -rf $(1)/*' 60 endef 61 62 .DEFAULT_GOAL:=help 63 64 65 .PHONY: all 66 all: static-analysis test ## Run all linux-based checks (linting, license check, unit, integration, and linux compare tests) 67 @printf '$(SUCCESS)All checks pass!$(RESET)\n' 68 69 .PHONY: static-analysis 70 static-analysis: check-go-mod-tidy lint check-licenses check-json-schema-drift ## Run all static analysis checks 71 72 .PHONY: test 73 test: unit integration validate-cyclonedx-schema benchmark cli ## Run all tests (currently unit, integration, linux compare, and cli tests) 74 75 76 ## Bootstrapping targets ################################# 77 78 .PHONY: bootstrap 79 bootstrap: $(TEMP_DIR) bootstrap-go bootstrap-tools ## Download and install all tooling dependencies (+ prep tooling in the ./tmp dir) 80 $(call title,Bootstrapping dependencies) 81 82 .PHONY: bootstrap-tools 83 bootstrap-tools: $(TEMP_DIR) 84 curl -sSfL https://raw.githubusercontent.com/anchore/quill/main/install.sh | sh -s -- -b $(TEMP_DIR)/ $(QUILL_VERSION) 85 GO111MODULE=off GOBIN=$(realpath $(TEMP_DIR)) go get -u golang.org/x/perf/cmd/benchstat 86 curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(TEMP_DIR)/ $(GOLANGCILINT_VERSION) 87 curl -sSfL https://raw.githubusercontent.com/wagoodman/go-bouncer/master/bouncer.sh | sh -s -- -b $(TEMP_DIR)/ $(BOUNCER_VERSION) 88 curl -sSfL https://raw.githubusercontent.com/anchore/chronicle/main/install.sh | sh -s -- -b $(TEMP_DIR)/ $(CHRONICLE_VERSION) 89 .github/scripts/goreleaser-install.sh -d -b $(TEMP_DIR)/ $(GORELEASER_VERSION) 90 # the only difference between goimports and gosimports is that gosimports removes extra whitespace between import blocks (see https://github.com/golang/go/issues/20818) 91 GOBIN="$(realpath $(TEMP_DIR))" go install github.com/rinchsan/gosimports/cmd/gosimports@$(GOSIMPORTS_VERSION) 92 GOBIN="$(realpath $(TEMP_DIR))" go install github.com/neilpa/yajsv@$(YAJSV_VERSION) 93 GOBIN="$(realpath $(TEMP_DIR))" go install github.com/sigstore/cosign/v2/cmd/cosign@$(COSIGN_VERSION) 94 GOBIN="$(realpath $(TEMP_DIR))" go install github.com/charmbracelet/glow@$(GLOW_VERSION) 95 96 .PHONY: bootstrap-go 97 bootstrap-go: 98 go mod download 99 100 $(TEMP_DIR): 101 mkdir -p $(TEMP_DIR) 102 103 104 ## Static analysis targets ################################# 105 106 .PHONY: lint 107 lint: ## Run gofmt + golangci lint checks 108 $(call title,Running linters) 109 # ensure there are no go fmt differences 110 @printf "files with gofmt issues: [$(shell gofmt -l -s .)]\n" 111 @test -z "$(shell gofmt -l -s .)" 112 113 # run all golangci-lint rules 114 $(LINT_CMD) 115 @[ -z "$(shell $(GOIMPORTS_CMD) -d .)" ] || (echo "goimports needs to be fixed" && false) 116 117 # go tooling does not play well with certain filename characters, ensure the common cases don't result in future "go get" failures 118 $(eval MALFORMED_FILENAMES := $(shell find . | grep -e ':')) 119 @bash -c "[[ '$(MALFORMED_FILENAMES)' == '' ]] || (printf '\nfound unsupported filename characters:\n$(MALFORMED_FILENAMES)\n\n' && false)" 120 121 .PHONY: format 122 format: ## Auto-format all source code 123 $(call title,Running formatters) 124 gofmt -w -s . 125 $(GOIMPORTS_CMD) -w . 126 go mod tidy 127 128 .PHONY: lint-fix 129 lint-fix: format ## Auto-format all source code + run golangci lint fixers 130 $(call title,Running lint fixers) 131 $(LINT_CMD) --fix 132 133 .PHONY: check-licenses 134 check-licenses: ## Ensure transitive dependencies are compliant with the current license policy 135 $(call title,Checking for license compliance) 136 $(TEMP_DIR)/bouncer check ./... 137 138 check-go-mod-tidy: 139 @ .github/scripts/go-mod-tidy-check.sh && echo "go.mod and go.sum are tidy!" 140 141 check-json-schema-drift: 142 $(call title,Ensure there is no drift between the JSON schema and the code) 143 @.github/scripts/json-schema-drift-check.sh 144 145 ## Testing targets ################################# 146 147 .PHONY: unit 148 unit: $(TEMP_DIR) fixtures ## Run unit tests (with coverage) 149 $(call title,Running unit tests) 150 go test -coverprofile $(TEMP_DIR)/unit-coverage-details.txt $(shell go list ./... | grep -v anchore/syft/test) 151 @.github/scripts/coverage.py $(COVERAGE_THRESHOLD) $(TEMP_DIR)/unit-coverage-details.txt 152 153 .PHONY: integration 154 integration: ## Run integration tests 155 $(call title,Running integration tests) 156 go test -v ./test/integration 157 158 .PHONY: validate-cyclonedx-schema 159 validate-cyclonedx-schema: 160 cd schema/cyclonedx && make 161 162 .PHONY: cli 163 cli: $(SNAPSHOT_DIR) ## Run CLI tests 164 chmod 755 "$(SNAPSHOT_BIN)" 165 $(SNAPSHOT_BIN) version 166 SYFT_BINARY_LOCATION='$(SNAPSHOT_BIN)' \ 167 go test -count=1 -timeout=15m -v ./test/cli 168 169 170 ## Benchmark test targets ################################# 171 172 .PHONY: benchmark 173 benchmark: $(TEMP_DIR) ## Run benchmark tests and compare against the baseline (if available) 174 $(call title,Running benchmark tests) 175 go test -p 1 -run=^Benchmark -bench=. -count=7 -benchmem ./... | tee $(TEMP_DIR)/benchmark-$(VERSION).txt 176 (test -s $(TEMP_DIR)/benchmark-main.txt && \ 177 $(TEMP_DIR)/benchstat $(TEMP_DIR)/benchmark-main.txt $(TEMP_DIR)/benchmark-$(VERSION).txt || \ 178 $(TEMP_DIR)/benchstat $(TEMP_DIR)/benchmark-$(VERSION).txt) \ 179 | tee $(TEMP_DIR)/benchstat.txt 180 181 .PHONY: show-benchstat 182 show-benchstat: 183 @cat $(TEMP_DIR)/benchstat.txt 184 185 186 ## Test-fixture-related targets ################################# 187 188 # note: this is used by CI to determine if various test fixture cache should be restored or recreated 189 fingerprints: 190 $(call title,Creating all test cache input fingerprints) 191 192 # for IMAGE integration test fixtures 193 cd test/integration/test-fixtures && \ 194 make cache.fingerprint 195 196 # for BINARY test fixtures 197 cd syft/pkg/cataloger/binary/test-fixtures && \ 198 make cache.fingerprint 199 200 # for JAVA BUILD test fixtures 201 cd syft/pkg/cataloger/java/test-fixtures/java-builds && \ 202 make cache.fingerprint 203 204 # for GO BINARY test fixtures 205 cd syft/pkg/cataloger/golang/test-fixtures/archs && \ 206 make binaries.fingerprint 207 208 # for RPM test fixtures 209 cd syft/pkg/cataloger/rpm/test-fixtures && \ 210 make rpms.fingerprint 211 212 # for Kernel test fixtures 213 cd syft/pkg/cataloger/kernel/test-fixtures && \ 214 make cache.fingerprint 215 216 # for INSTALL integration test fixtures 217 cd test/install && \ 218 make cache.fingerprint 219 220 # for CLI test fixtures 221 cd test/cli/test-fixtures && \ 222 make cache.fingerprint 223 224 .PHONY: fixtures 225 fixtures: 226 $(call title,Generating test fixtures) 227 cd syft/pkg/cataloger/java/test-fixtures/java-builds && make 228 cd syft/pkg/cataloger/rpm/test-fixtures && make 229 cd syft/pkg/cataloger/binary/test-fixtures && make 230 231 .PHONY: show-test-image-cache 232 show-test-image-cache: ## Show all docker and image tar cache 233 $(call title,Docker daemon cache) 234 @docker images --format '{{.ID}} {{.Repository}}:{{.Tag}}' | grep stereoscope-fixture- | sort 235 236 $(call title,Tar cache) 237 @find . -type f -wholename "**/test-fixtures/cache/stereoscope-fixture-*.tar" | sort 238 239 .PHONY: show-test-snapshots 240 show-test-snapshots: ## Show all test snapshots 241 $(call title,Test snapshots) 242 @find . -type f -wholename "**/test-fixtures/snapshot/*" | sort 243 244 245 ## install.sh testing targets ################################# 246 247 install-test: $(SNAPSHOT_DIR) 248 cd test/install && \ 249 make 250 251 install-test-cache-save: $(SNAPSHOT_DIR) 252 cd test/install && \ 253 make save 254 255 install-test-cache-load: $(SNAPSHOT_DIR) 256 cd test/install && \ 257 make load 258 259 install-test-ci-mac: $(SNAPSHOT_DIR) 260 cd test/install && \ 261 make ci-test-mac 262 263 .PHONY: generate-compare-file 264 generate-compare-file: 265 $(call title,Generating compare test file) 266 go run ./cmd/syft $(COMPARE_TEST_IMAGE) -o json > $(COMPARE_DIR)/test-fixtures/acceptance-centos-8.2.2004.json 267 268 # note: we cannot clean the snapshot directory since the pipeline builds the snapshot separately 269 .PHONY: compare-mac 270 compare-mac: $(TEMP_DIR) $(SNAPSHOT_DIR) ## Run compare tests on build snapshot binaries and packages (Mac) 271 $(call title,Running compare test: Run on Mac) 272 $(COMPARE_DIR)/mac.sh \ 273 $(SNAPSHOT_DIR) \ 274 $(COMPARE_DIR) \ 275 $(COMPARE_TEST_IMAGE) \ 276 $(TEMP_DIR) 277 278 # note: we cannot clean the snapshot directory since the pipeline builds the snapshot separately 279 .PHONY: compare-linux 280 compare-linux: compare-test-deb-package-install compare-test-rpm-package-install ## Run compare tests on build snapshot binaries and packages (Linux) 281 282 .PHONY: compare-test-deb-package-install 283 compare-test-deb-package-install: $(TEMP_DIR) $(SNAPSHOT_DIR) 284 $(call title,Running compare test: DEB install) 285 $(COMPARE_DIR)/deb.sh \ 286 $(SNAPSHOT_DIR) \ 287 $(COMPARE_DIR) \ 288 $(COMPARE_TEST_IMAGE) \ 289 $(TEMP_DIR) 290 291 .PHONY: compare-test-rpm-package-install 292 compare-test-rpm-package-install: $(TEMP_DIR) $(SNAPSHOT_DIR) 293 $(call title,Running compare test: RPM install) 294 $(COMPARE_DIR)/rpm.sh \ 295 $(SNAPSHOT_DIR) \ 296 $(COMPARE_DIR) \ 297 $(COMPARE_TEST_IMAGE) \ 298 $(TEMP_DIR) 299 300 301 ## Code and data generation targets ################################# 302 303 .PHONY: generate-json-schema 304 generate-json-schema: ## Generate a new json schema 305 cd syft/internal && go generate . && cd jsonschema && go run . 306 307 .PHONY: generate-license-list 308 generate-license-list: ## Generate an updated spdx license list 309 go generate ./internal/spdxlicense/... 310 gofmt -s -w ./internal/spdxlicense 311 312 .PHONY: generate-cpe-dictionary-index 313 generate-cpe-dictionary-index: ## Build the CPE index based off of the latest available CPE dictionary 314 $(call title,Building CPE index) 315 go generate ./syft/pkg/cataloger/common/cpe/dictionary 316 317 318 ## Build-related targets ################################# 319 320 .PHONY: build 321 build: 322 CGO_ENABLED=0 go build -trimpath -ldflags "$(LDFLAGS)" -o $@ ./cmd/syft 323 324 $(SNAPSHOT_DIR): ## Build snapshot release binaries and packages 325 $(call title,Building snapshot artifacts) 326 327 # create a config with the dist dir overridden 328 echo "dist: $(SNAPSHOT_DIR)" > $(TEMP_DIR)/goreleaser.yaml 329 cat .goreleaser.yaml >> $(TEMP_DIR)/goreleaser.yaml 330 331 # build release snapshots 332 $(SNAPSHOT_CMD) --config $(TEMP_DIR)/goreleaser.yaml 333 334 .PHONY: changelog 335 changelog: clean-changelog ## Generate and show the changelog for the current unreleased version 336 $(CHRONICLE_CMD) -vvv -n --version-file VERSION > $(CHANGELOG) 337 @$(GLOW_CMD) $(CHANGELOG) 338 339 $(CHANGELOG): 340 $(CHRONICLE_CMD) -vvv > $(CHANGELOG) 341 342 .PHONY: release 343 release: 344 @.github/scripts/trigger-release.sh 345 346 .PHONY: ci-release 347 ci-release: ci-check clean-dist $(CHANGELOG) 348 $(call title,Publishing release artifacts) 349 350 # create a config with the dist dir overridden 351 echo "dist: $(DIST_DIR)" > $(TEMP_DIR)/goreleaser.yaml 352 cat .goreleaser.yaml >> $(TEMP_DIR)/goreleaser.yaml 353 354 bash -c "\ 355 $(RELEASE_CMD) \ 356 --config $(TEMP_DIR)/goreleaser.yaml \ 357 --release-notes <(cat $(CHANGELOG)) \ 358 || (cat /tmp/quill-*.log && false)" 359 360 # upload the version file that supports the application version update check (excluding pre-releases) 361 .github/scripts/update-version-file.sh "$(DIST_DIR)" "$(VERSION)" 362 363 .PHONY: ci-check 364 ci-check: 365 @.github/scripts/ci-check.sh 366 367 ## Cleanup targets ################################# 368 369 .PHONY: clean 370 clean: clean-dist clean-snapshot clean-test-image-cache ## Remove previous builds, result reports, and test cache 371 $(call safe_rm_rf_children,$(TEMP_DIR)) 372 373 .PHONY: clean-snapshot 374 clean-snapshot: 375 $(call safe_rm_rf,$(SNAPSHOT_DIR)) 376 rm -f $(TEMP_DIR)/goreleaser.yaml 377 378 .PHONY: clean-dist 379 clean-dist: clean-changelog 380 $(call safe_rm_rf,$(DIST_DIR)) 381 rm -f $(TEMP_DIR)/goreleaser.yaml 382 383 .PHONY: clean-changelog 384 clean-changelog: 385 rm -f $(CHANGELOG) VERSION 386 387 clean-test-image-cache: clean-test-image-tar-cache clean-test-image-docker-cache ## Clean test image cache 388 389 .PHONY: clear-test-image-tar-cache 390 clean-test-image-tar-cache: ## Delete all test cache (built docker image tars) 391 find . -type f -wholename "**/test-fixtures/cache/stereoscope-fixture-*.tar" -delete 392 393 .PHONY: clear-test-image-docker-cache 394 clean-test-image-docker-cache: ## Purge all test docker images 395 docker images --format '{{.ID}} {{.Repository}}' | grep stereoscope-fixture- | awk '{print $$1}' | uniq | xargs -r docker rmi --force 396 397 ## Halp! ################################# 398 399 .PHONY: help 400 help: ## Display this help 401 @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "$(BOLD)$(CYAN)%-25s$(RESET)%s\n", $$1, $$2}'