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}'