github.com/noqcks/syft@v0.0.0-20230920222752-a9e2c4e288e5/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.54.2 14 GOSIMPORTS_VERSION := v0.3.8 15 BOUNCER_VERSION := v0.4.0 16 CHRONICLE_VERSION := v0.7.0 17 GORELEASER_VERSION := v1.20.0 18 YAJSV_VERSION := v1.4.1 19 COSIGN_VERSION := v2.2.0 20 QUILL_VERSION := v0.4.1 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 -race -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 go run -race cmd/syft/main.go alpine:latest 158 159 .PHONY: validate-cyclonedx-schema 160 validate-cyclonedx-schema: 161 cd schema/cyclonedx && make 162 163 .PHONY: cli 164 cli: $(SNAPSHOT_DIR) ## Run CLI tests 165 chmod 755 "$(SNAPSHOT_BIN)" 166 $(SNAPSHOT_BIN) version 167 SYFT_BINARY_LOCATION='$(SNAPSHOT_BIN)' \ 168 go test -count=1 -timeout=15m -v ./test/cli 169 170 171 ## Benchmark test targets ################################# 172 173 .PHONY: benchmark 174 benchmark: $(TEMP_DIR) ## Run benchmark tests and compare against the baseline (if available) 175 $(call title,Running benchmark tests) 176 go test -p 1 -run=^Benchmark -bench=. -count=7 -benchmem ./... | tee $(TEMP_DIR)/benchmark-$(VERSION).txt 177 (test -s $(TEMP_DIR)/benchmark-main.txt && \ 178 $(TEMP_DIR)/benchstat $(TEMP_DIR)/benchmark-main.txt $(TEMP_DIR)/benchmark-$(VERSION).txt || \ 179 $(TEMP_DIR)/benchstat $(TEMP_DIR)/benchmark-$(VERSION).txt) \ 180 | tee $(TEMP_DIR)/benchstat.txt 181 182 .PHONY: show-benchstat 183 show-benchstat: 184 @cat $(TEMP_DIR)/benchstat.txt 185 186 187 ## Test-fixture-related targets ################################# 188 189 # note: this is used by CI to determine if various test fixture cache should be restored or recreated 190 fingerprints: 191 $(call title,Creating all test cache input fingerprints) 192 193 # for IMAGE integration test fixtures 194 cd test/integration/test-fixtures && \ 195 make cache.fingerprint 196 197 # for BINARY test fixtures 198 cd syft/pkg/cataloger/binary/test-fixtures && \ 199 make cache.fingerprint 200 201 # for JAVA BUILD test fixtures 202 cd syft/pkg/cataloger/java/test-fixtures/java-builds && \ 203 make cache.fingerprint 204 205 # for GO BINARY test fixtures 206 cd syft/pkg/cataloger/golang/test-fixtures/archs && \ 207 make binaries.fingerprint 208 209 # for RPM test fixtures 210 cd syft/pkg/cataloger/rpm/test-fixtures && \ 211 make rpms.fingerprint 212 213 # for Kernel test fixtures 214 cd syft/pkg/cataloger/kernel/test-fixtures && \ 215 make cache.fingerprint 216 217 # for INSTALL integration test fixtures 218 cd test/install && \ 219 make cache.fingerprint 220 221 # for CLI test fixtures 222 cd test/cli/test-fixtures && \ 223 make cache.fingerprint 224 225 .PHONY: fixtures 226 fixtures: 227 $(call title,Generating test fixtures) 228 cd syft/pkg/cataloger/java/test-fixtures/java-builds && make 229 cd syft/pkg/cataloger/rpm/test-fixtures && make 230 cd syft/pkg/cataloger/binary/test-fixtures && make 231 232 .PHONY: show-test-image-cache 233 show-test-image-cache: ## Show all docker and image tar cache 234 $(call title,Docker daemon cache) 235 @docker images --format '{{.ID}} {{.Repository}}:{{.Tag}}' | grep stereoscope-fixture- | sort 236 237 $(call title,Tar cache) 238 @find . -type f -wholename "**/test-fixtures/cache/stereoscope-fixture-*.tar" | sort 239 240 .PHONY: show-test-snapshots 241 show-test-snapshots: ## Show all test snapshots 242 $(call title,Test snapshots) 243 @find . -type f -wholename "**/test-fixtures/snapshot/*" | sort 244 245 246 ## install.sh testing targets ################################# 247 248 install-test: $(SNAPSHOT_DIR) 249 cd test/install && \ 250 make 251 252 install-test-cache-save: $(SNAPSHOT_DIR) 253 cd test/install && \ 254 make save 255 256 install-test-cache-load: $(SNAPSHOT_DIR) 257 cd test/install && \ 258 make load 259 260 install-test-ci-mac: $(SNAPSHOT_DIR) 261 cd test/install && \ 262 make ci-test-mac 263 264 .PHONY: generate-compare-file 265 generate-compare-file: 266 $(call title,Generating compare test file) 267 go run ./cmd/syft $(COMPARE_TEST_IMAGE) -o json > $(COMPARE_DIR)/test-fixtures/acceptance-centos-8.2.2004.json 268 269 # note: we cannot clean the snapshot directory since the pipeline builds the snapshot separately 270 .PHONY: compare-mac 271 compare-mac: $(TEMP_DIR) $(SNAPSHOT_DIR) ## Run compare tests on build snapshot binaries and packages (Mac) 272 $(call title,Running compare test: Run on Mac) 273 $(COMPARE_DIR)/mac.sh \ 274 $(SNAPSHOT_DIR) \ 275 $(COMPARE_DIR) \ 276 $(COMPARE_TEST_IMAGE) \ 277 $(TEMP_DIR) 278 279 # note: we cannot clean the snapshot directory since the pipeline builds the snapshot separately 280 .PHONY: compare-linux 281 compare-linux: compare-test-deb-package-install compare-test-rpm-package-install ## Run compare tests on build snapshot binaries and packages (Linux) 282 283 .PHONY: compare-test-deb-package-install 284 compare-test-deb-package-install: $(TEMP_DIR) $(SNAPSHOT_DIR) 285 $(call title,Running compare test: DEB install) 286 $(COMPARE_DIR)/deb.sh \ 287 $(SNAPSHOT_DIR) \ 288 $(COMPARE_DIR) \ 289 $(COMPARE_TEST_IMAGE) \ 290 $(TEMP_DIR) 291 292 .PHONY: compare-test-rpm-package-install 293 compare-test-rpm-package-install: $(TEMP_DIR) $(SNAPSHOT_DIR) 294 $(call title,Running compare test: RPM install) 295 $(COMPARE_DIR)/rpm.sh \ 296 $(SNAPSHOT_DIR) \ 297 $(COMPARE_DIR) \ 298 $(COMPARE_TEST_IMAGE) \ 299 $(TEMP_DIR) 300 301 302 ## Code and data generation targets ################################# 303 304 .PHONY: generate-json-schema 305 generate-json-schema: ## Generate a new json schema 306 cd syft/internal && go generate . && cd jsonschema && go run . 307 308 .PHONY: generate-license-list 309 generate-license-list: ## Generate an updated spdx license list 310 go generate ./internal/spdxlicense/... 311 gofmt -s -w ./internal/spdxlicense 312 313 .PHONY: generate-cpe-dictionary-index 314 generate-cpe-dictionary-index: ## Build the CPE index based off of the latest available CPE dictionary 315 $(call title,Building CPE index) 316 go generate ./syft/pkg/cataloger/common/cpe/dictionary 317 318 319 ## Build-related targets ################################# 320 321 .PHONY: build 322 build: 323 CGO_ENABLED=0 go build -trimpath -ldflags "$(LDFLAGS)" -o $@ ./cmd/syft 324 325 $(SNAPSHOT_DIR): ## Build snapshot release binaries and packages 326 $(call title,Building snapshot artifacts) 327 328 # create a config with the dist dir overridden 329 echo "dist: $(SNAPSHOT_DIR)" > $(TEMP_DIR)/goreleaser.yaml 330 cat .goreleaser.yaml >> $(TEMP_DIR)/goreleaser.yaml 331 332 # build release snapshots 333 $(SNAPSHOT_CMD) --config $(TEMP_DIR)/goreleaser.yaml 334 335 .PHONY: changelog 336 changelog: clean-changelog ## Generate and show the changelog for the current unreleased version 337 $(CHRONICLE_CMD) -vvv -n --version-file VERSION > $(CHANGELOG) 338 @$(GLOW_CMD) $(CHANGELOG) 339 340 $(CHANGELOG): 341 $(CHRONICLE_CMD) -vvv > $(CHANGELOG) 342 343 .PHONY: release 344 release: 345 @.github/scripts/trigger-release.sh 346 347 .PHONY: ci-release 348 ci-release: ci-check clean-dist $(CHANGELOG) 349 $(call title,Publishing release artifacts) 350 351 # create a config with the dist dir overridden 352 echo "dist: $(DIST_DIR)" > $(TEMP_DIR)/goreleaser.yaml 353 cat .goreleaser.yaml >> $(TEMP_DIR)/goreleaser.yaml 354 355 bash -c "\ 356 $(RELEASE_CMD) \ 357 --config $(TEMP_DIR)/goreleaser.yaml \ 358 --release-notes <(cat $(CHANGELOG)) \ 359 || (cat /tmp/quill-*.log && false)" 360 361 # upload the version file that supports the application version update check (excluding pre-releases) 362 .github/scripts/update-version-file.sh "$(DIST_DIR)" "$(VERSION)" 363 364 .PHONY: ci-check 365 ci-check: 366 @.github/scripts/ci-check.sh 367 368 ## Cleanup targets ################################# 369 370 .PHONY: clean 371 clean: clean-dist clean-snapshot clean-test-image-cache ## Remove previous builds, result reports, and test cache 372 $(call safe_rm_rf_children,$(TEMP_DIR)) 373 374 .PHONY: clean-snapshot 375 clean-snapshot: 376 $(call safe_rm_rf,$(SNAPSHOT_DIR)) 377 rm -f $(TEMP_DIR)/goreleaser.yaml 378 379 .PHONY: clean-dist 380 clean-dist: clean-changelog 381 $(call safe_rm_rf,$(DIST_DIR)) 382 rm -f $(TEMP_DIR)/goreleaser.yaml 383 384 .PHONY: clean-changelog 385 clean-changelog: 386 rm -f $(CHANGELOG) VERSION 387 388 clean-test-image-cache: clean-test-image-tar-cache clean-test-image-docker-cache ## Clean test image cache 389 390 .PHONY: clear-test-image-tar-cache 391 clean-test-image-tar-cache: ## Delete all test cache (built docker image tars) 392 find . -type f -wholename "**/test-fixtures/cache/stereoscope-fixture-*.tar" -delete 393 394 .PHONY: clear-test-image-docker-cache 395 clean-test-image-docker-cache: ## Purge all test docker images 396 docker images --format '{{.ID}} {{.Repository}}' | grep stereoscope-fixture- | awk '{print $$1}' | uniq | xargs -r docker rmi --force 397 398 ## Halp! ################################# 399 400 .PHONY: help 401 help: ## Display this help 402 @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "$(BOLD)$(CYAN)%-25s$(RESET)%s\n", $$1, $$2}'