1# Copyright The OpenTelemetry Authors 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15EXAMPLES := $(shell ./get_main_pkgs.sh ./example) 16TOOLS_MOD_DIR := ./internal/tools 17 18# All source code and documents. Used in spell check. 19ALL_DOCS := $(shell find . -name '*.md' -type f | sort) 20# All directories with go.mod files related to opentelemetry library. Used for building, testing and linting. 21ALL_GO_MOD_DIRS := $(filter-out $(TOOLS_MOD_DIR), $(shell find . -type f -name 'go.mod' -exec dirname {} \; | egrep -v '^./example' | sort)) $(shell find ./example -type f -name 'go.mod' -exec dirname {} \; | sort) 22ALL_COVERAGE_MOD_DIRS := $(shell find . -type f -name 'go.mod' -exec dirname {} \; | egrep -v '^./example|^$(TOOLS_MOD_DIR)' | sort) 23 24GO = go 25TIMEOUT = 60 26 27.DEFAULT_GOAL := precommit 28 29.PHONY: precommit ci 30precommit: dependabot-check license-check lint build examples test-default 31ci: precommit check-clean-work-tree test-coverage 32 33# Tools 34 35TOOLS = $(CURDIR)/.tools 36 37$(TOOLS): 38 @mkdir -p $@ 39$(TOOLS)/%: | $(TOOLS) 40 cd $(TOOLS_MOD_DIR) && \ 41 $(GO) build -o $@ $(PACKAGE) 42 43CROSSLINK = $(TOOLS)/crosslink 44$(TOOLS)/crosslink: PACKAGE=go.opentelemetry.io/otel/$(TOOLS_MOD_DIR)/crosslink 45 46GOLANGCI_LINT = $(TOOLS)/golangci-lint 47$(TOOLS)/golangci-lint: PACKAGE=github.com/golangci/golangci-lint/cmd/golangci-lint 48 49MISSPELL = $(TOOLS)/misspell 50$(TOOLS)/misspell: PACKAGE= github.com/client9/misspell/cmd/misspell 51 52STRINGER = $(TOOLS)/stringer 53$(TOOLS)/stringer: PACKAGE=golang.org/x/tools/cmd/stringer 54 55$(TOOLS)/gojq: PACKAGE=github.com/itchyny/gojq/cmd/gojq 56 57.PHONY: tools 58tools: $(CROSSLINK) $(GOLANGCI_LINT) $(MISSPELL) $(STRINGER) $(TOOLS)/gojq 59 60 61# Build 62 63.PHONY: examples generate build 64examples: 65 @set -e; for dir in $(EXAMPLES); do \ 66 echo "$(GO) build $${dir}/..."; \ 67 (cd "$${dir}" && \ 68 $(GO) build .); \ 69 done 70 71generate: $(STRINGER) 72 set -e; for dir in $(ALL_GO_MOD_DIRS); do \ 73 echo "$(GO) generate $${dir}/..."; \ 74 (cd "$${dir}" && \ 75 PATH="$(TOOLS):$${PATH}" $(GO) generate ./...); \ 76 done 77 78build: generate 79 # Build all package code including testing code. 80 set -e; for dir in $(ALL_GO_MOD_DIRS); do \ 81 echo "$(GO) build $${dir}/..."; \ 82 (cd "$${dir}" && \ 83 $(GO) build ./... && \ 84 $(GO) list ./... \ 85 | grep -v third_party \ 86 | xargs $(GO) test -vet=off -run xxxxxMatchNothingxxxxx >/dev/null); \ 87 done 88 89# Tests 90 91TEST_TARGETS := test-default test-bench test-short test-verbose test-race 92.PHONY: $(TEST_TARGETS) test 93test-default: ARGS=-v -race 94test-bench: ARGS=-run=xxxxxMatchNothingxxxxx -test.benchtime=1ms -bench=. 95test-short: ARGS=-short 96test-verbose: ARGS=-v 97test-race: ARGS=-race 98$(TEST_TARGETS): test 99test: 100 @set -e; for dir in $(ALL_GO_MOD_DIRS); do \ 101 echo "$(GO) test -timeout $(TIMEOUT)s $(ARGS) $${dir}/..."; \ 102 (cd "$${dir}" && \ 103 $(GO) list ./... \ 104 | grep -v third_party \ 105 | xargs $(GO) test -timeout $(TIMEOUT)s $(ARGS)); \ 106 done 107 108COVERAGE_MODE = atomic 109COVERAGE_PROFILE = coverage.out 110.PHONY: test-coverage 111test-coverage: 112 @set -e; \ 113 printf "" > coverage.txt; \ 114 for dir in $(ALL_COVERAGE_MOD_DIRS); do \ 115 echo "$(GO) test -coverpkg=./... -covermode=$(COVERAGE_MODE) -coverprofile="$(COVERAGE_PROFILE)" $${dir}/..."; \ 116 (cd "$${dir}" && \ 117 $(GO) list ./... \ 118 | grep -v third_party \ 119 | xargs $(GO) test -coverpkg=./... -covermode=$(COVERAGE_MODE) -coverprofile="$(COVERAGE_PROFILE)" && \ 120 $(GO) tool cover -html=coverage.out -o coverage.html); \ 121 [ -f "$${dir}/coverage.out" ] && cat "$${dir}/coverage.out" >> coverage.txt; \ 122 done; \ 123 sed -i.bak -e '2,$$ { /^mode: /d; }' coverage.txt 124 125.PHONY: lint 126lint: misspell lint-modules | $(GOLANGCI_LINT) 127 set -e; for dir in $(ALL_GO_MOD_DIRS); do \ 128 echo "golangci-lint in $${dir}"; \ 129 (cd "$${dir}" && \ 130 $(GOLANGCI_LINT) run --fix && \ 131 $(GOLANGCI_LINT) run); \ 132 done 133 134.PHONY: misspell 135misspell: | $(MISSPELL) 136 $(MISSPELL) -w $(ALL_DOCS) 137 138.PHONY: lint-modules 139lint-modules: | $(CROSSLINK) 140 set -e; for dir in $(ALL_GO_MOD_DIRS) $(TOOLS_MOD_DIR); do \ 141 echo "$(GO) mod tidy in $${dir}"; \ 142 (cd "$${dir}" && \ 143 $(GO) mod tidy); \ 144 done 145 echo "cross-linking all go modules" 146 $(CROSSLINK) 147 148.PHONY: license-check 149license-check: 150 @licRes=$$(for f in $$(find . -type f \( -iname '*.go' -o -iname '*.sh' \) ! -path '**/third_party/*' ! -path './exporters/otlp/internal/opentelemetry-proto/*') ; do \ 151 awk '/Copyright The OpenTelemetry Authors|generated|GENERATED/ && NR<=3 { found=1; next } END { if (!found) print FILENAME }' $$f; \ 152 done); \ 153 if [ -n "$${licRes}" ]; then \ 154 echo "license header checking failed:"; echo "$${licRes}"; \ 155 exit 1; \ 156 fi 157 158.PHONY: dependabot-check 159dependabot-check: 160 @result=$$( \ 161 for f in $$( find . -type f -name go.mod -exec dirname {} \; | sed 's/^.\/\?/\//' ); \ 162 do grep -q "$$f" .github/dependabot.yml \ 163 || echo "$$f"; \ 164 done; \ 165 ); \ 166 if [ -n "$$result" ]; then \ 167 echo "missing go.mod dependabot check:"; echo "$$result"; \ 168 exit 1; \ 169 fi 170 171.PHONY: check-clean-work-tree 172check-clean-work-tree: 173 @if ! git diff --quiet; then \ 174 echo; \ 175 echo 'Working tree is not clean, did you forget to run "make precommit"?'; \ 176 echo; \ 177 git status; \ 178 exit 1; \ 179 fi 180