Makefile (9147B)
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 15 TOOLS_MOD_DIR := ./internal/tools 16 17 ALL_DOCS := $(shell find . -name '*.md' -type f | sort) 18 ALL_GO_MOD_DIRS := $(shell find . -type f -name 'go.mod' -exec dirname {} \; | sort) 19 OTEL_GO_MOD_DIRS := $(filter-out $(TOOLS_MOD_DIR), $(ALL_GO_MOD_DIRS)) 20 ALL_COVERAGE_MOD_DIRS := $(shell find . -type f -name 'go.mod' -exec dirname {} \; | grep -E -v '^./example|^$(TOOLS_MOD_DIR)' | sort) 21 22 GO = go 23 TIMEOUT = 60 24 25 .DEFAULT_GOAL := precommit 26 27 .PHONY: precommit ci 28 precommit: generate dependabot-generate license-check vanity-import-fix misspell go-mod-tidy golangci-lint-fix test-default 29 ci: generate dependabot-check license-check lint vanity-import-check build test-default check-clean-work-tree test-coverage 30 31 # Tools 32 33 TOOLS = $(CURDIR)/.tools 34 35 $(TOOLS): 36 @mkdir -p $@ 37 $(TOOLS)/%: | $(TOOLS) 38 cd $(TOOLS_MOD_DIR) && \ 39 $(GO) build -o $@ $(PACKAGE) 40 41 MULTIMOD = $(TOOLS)/multimod 42 $(TOOLS)/multimod: PACKAGE=go.opentelemetry.io/build-tools/multimod 43 44 SEMCONVGEN = $(TOOLS)/semconvgen 45 $(TOOLS)/semconvgen: PACKAGE=go.opentelemetry.io/build-tools/semconvgen 46 47 CROSSLINK = $(TOOLS)/crosslink 48 $(TOOLS)/crosslink: PACKAGE=go.opentelemetry.io/build-tools/crosslink 49 50 SEMCONVKIT = $(TOOLS)/semconvkit 51 $(TOOLS)/semconvkit: PACKAGE=go.opentelemetry.io/otel/$(TOOLS_MOD_DIR)/semconvkit 52 53 DBOTCONF = $(TOOLS)/dbotconf 54 $(TOOLS)/dbotconf: PACKAGE=go.opentelemetry.io/build-tools/dbotconf 55 56 GOLANGCI_LINT = $(TOOLS)/golangci-lint 57 $(TOOLS)/golangci-lint: PACKAGE=github.com/golangci/golangci-lint/cmd/golangci-lint 58 59 MISSPELL = $(TOOLS)/misspell 60 $(TOOLS)/misspell: PACKAGE=github.com/client9/misspell/cmd/misspell 61 62 GOCOVMERGE = $(TOOLS)/gocovmerge 63 $(TOOLS)/gocovmerge: PACKAGE=github.com/wadey/gocovmerge 64 65 STRINGER = $(TOOLS)/stringer 66 $(TOOLS)/stringer: PACKAGE=golang.org/x/tools/cmd/stringer 67 68 PORTO = $(TOOLS)/porto 69 $(TOOLS)/porto: PACKAGE=github.com/jcchavezs/porto/cmd/porto 70 71 GOJQ = $(TOOLS)/gojq 72 $(TOOLS)/gojq: PACKAGE=github.com/itchyny/gojq/cmd/gojq 73 74 .PHONY: tools 75 tools: $(CROSSLINK) $(DBOTCONF) $(GOLANGCI_LINT) $(MISSPELL) $(GOCOVMERGE) $(STRINGER) $(PORTO) $(GOJQ) $(SEMCONVGEN) $(MULTIMOD) $(SEMCONVKIT) 76 77 # Virtualized python tools via docker 78 79 # The directory where the virtual environment is created. 80 VENVDIR := venv 81 82 # The directory where the python tools are installed. 83 PYTOOLS := $(VENVDIR)/bin 84 85 # The pip executable in the virtual environment. 86 PIP := $(PYTOOLS)/pip 87 88 # The directory in the docker image where the current directory is mounted. 89 WORKDIR := /workdir 90 91 # The python image to use for the virtual environment. 92 PYTHONIMAGE := python:3.11.3-slim-bullseye 93 94 # Run the python image with the current directory mounted. 95 DOCKERPY := docker run --rm -v "$(CURDIR):$(WORKDIR)" -w $(WORKDIR) $(PYTHONIMAGE) 96 97 # Create a virtual environment for Python tools. 98 $(PYTOOLS): 99 # The `--upgrade` flag is needed to ensure that the virtual environment is 100 # created with the latest pip version. 101 @$(DOCKERPY) bash -c "python3 -m venv $(VENVDIR) && $(PIP) install --upgrade pip" 102 103 # Install python packages into the virtual environment. 104 $(PYTOOLS)/%: | $(PYTOOLS) 105 @$(DOCKERPY) $(PIP) install -r requirements.txt 106 107 CODESPELL = $(PYTOOLS)/codespell 108 $(CODESPELL): PACKAGE=codespell 109 110 # Generate 111 112 .PHONY: generate 113 114 generate: $(OTEL_GO_MOD_DIRS:%=generate/%) 115 generate/%: DIR=$* 116 generate/%: | $(STRINGER) $(PORTO) 117 @echo "$(GO) generate $(DIR)/..." \ 118 && cd $(DIR) \ 119 && PATH="$(TOOLS):$${PATH}" $(GO) generate ./... && $(PORTO) -w . 120 121 # Build 122 123 .PHONY: build 124 125 build: $(OTEL_GO_MOD_DIRS:%=build/%) $(OTEL_GO_MOD_DIRS:%=build-tests/%) 126 build/%: DIR=$* 127 build/%: 128 @echo "$(GO) build $(DIR)/..." \ 129 && cd $(DIR) \ 130 && $(GO) build ./... 131 132 build-tests/%: DIR=$* 133 build-tests/%: 134 @echo "$(GO) build tests $(DIR)/..." \ 135 && cd $(DIR) \ 136 && $(GO) list ./... \ 137 | grep -v third_party \ 138 | xargs $(GO) test -vet=off -run xxxxxMatchNothingxxxxx >/dev/null 139 140 # Tests 141 142 TEST_TARGETS := test-default test-bench test-short test-verbose test-race 143 .PHONY: $(TEST_TARGETS) test 144 test-default test-race: ARGS=-race 145 test-bench: ARGS=-run=xxxxxMatchNothingxxxxx -test.benchtime=1ms -bench=. 146 test-short: ARGS=-short 147 test-verbose: ARGS=-v -race 148 $(TEST_TARGETS): test 149 test: $(OTEL_GO_MOD_DIRS:%=test/%) 150 test/%: DIR=$* 151 test/%: 152 @echo "$(GO) test -timeout $(TIMEOUT)s $(ARGS) $(DIR)/..." \ 153 && cd $(DIR) \ 154 && $(GO) list ./... \ 155 | grep -v third_party \ 156 | xargs $(GO) test -timeout $(TIMEOUT)s $(ARGS) 157 158 COVERAGE_MODE = atomic 159 COVERAGE_PROFILE = coverage.out 160 .PHONY: test-coverage 161 test-coverage: | $(GOCOVMERGE) 162 @set -e; \ 163 printf "" > coverage.txt; \ 164 for dir in $(ALL_COVERAGE_MOD_DIRS); do \ 165 echo "$(GO) test -coverpkg=go.opentelemetry.io/otel/... -covermode=$(COVERAGE_MODE) -coverprofile="$(COVERAGE_PROFILE)" $${dir}/..."; \ 166 (cd "$${dir}" && \ 167 $(GO) list ./... \ 168 | grep -v third_party \ 169 | grep -v 'semconv/v.*' \ 170 | xargs $(GO) test -coverpkg=./... -covermode=$(COVERAGE_MODE) -coverprofile="$(COVERAGE_PROFILE)" && \ 171 $(GO) tool cover -html=coverage.out -o coverage.html); \ 172 done; \ 173 $(GOCOVMERGE) $$(find . -name coverage.out) > coverage.txt 174 175 .PHONY: golangci-lint golangci-lint-fix 176 golangci-lint-fix: ARGS=--fix 177 golangci-lint-fix: golangci-lint 178 golangci-lint: $(OTEL_GO_MOD_DIRS:%=golangci-lint/%) 179 golangci-lint/%: DIR=$* 180 golangci-lint/%: | $(GOLANGCI_LINT) 181 @echo 'golangci-lint $(if $(ARGS),$(ARGS) ,)$(DIR)' \ 182 && cd $(DIR) \ 183 && $(GOLANGCI_LINT) run --allow-serial-runners $(ARGS) 184 185 .PHONY: crosslink 186 crosslink: | $(CROSSLINK) 187 @echo "Updating intra-repository dependencies in all go modules" \ 188 && $(CROSSLINK) --root=$(shell pwd) --prune 189 190 .PHONY: go-mod-tidy 191 go-mod-tidy: $(ALL_GO_MOD_DIRS:%=go-mod-tidy/%) 192 go-mod-tidy/%: DIR=$* 193 go-mod-tidy/%: | crosslink 194 @echo "$(GO) mod tidy in $(DIR)" \ 195 && cd $(DIR) \ 196 && $(GO) mod tidy -compat=1.19 197 198 .PHONY: lint-modules 199 lint-modules: go-mod-tidy 200 201 .PHONY: lint 202 lint: misspell lint-modules golangci-lint 203 204 .PHONY: vanity-import-check 205 vanity-import-check: | $(PORTO) 206 @$(PORTO) --include-internal -l . || echo "(run: make vanity-import-fix)" 207 208 .PHONY: vanity-import-fix 209 vanity-import-fix: | $(PORTO) 210 @$(PORTO) --include-internal -w . 211 212 .PHONY: misspell 213 misspell: | $(MISSPELL) 214 @$(MISSPELL) -w $(ALL_DOCS) 215 216 .PHONY: codespell 217 codespell: | $(CODESPELL) 218 @$(DOCKERPY) $(CODESPELL) 219 220 .PHONY: license-check 221 license-check: 222 @licRes=$$(for f in $$(find . -type f \( -iname '*.go' -o -iname '*.sh' \) ! -path '**/third_party/*' ! -path './.git/*' ) ; do \ 223 awk '/Copyright The OpenTelemetry Authors|generated|GENERATED/ && NR<=3 { found=1; next } END { if (!found) print FILENAME }' $$f; \ 224 done); \ 225 if [ -n "$${licRes}" ]; then \ 226 echo "license header checking failed:"; echo "$${licRes}"; \ 227 exit 1; \ 228 fi 229 230 DEPENDABOT_CONFIG = .github/dependabot.yml 231 .PHONY: dependabot-check 232 dependabot-check: | $(DBOTCONF) 233 @$(DBOTCONF) verify $(DEPENDABOT_CONFIG) || echo "(run: make dependabot-generate)" 234 235 .PHONY: dependabot-generate 236 dependabot-generate: | $(DBOTCONF) 237 @$(DBOTCONF) generate > $(DEPENDABOT_CONFIG) 238 239 .PHONY: check-clean-work-tree 240 check-clean-work-tree: 241 @if ! git diff --quiet; then \ 242 echo; \ 243 echo 'Working tree is not clean, did you forget to run "make precommit"?'; \ 244 echo; \ 245 git status; \ 246 exit 1; \ 247 fi 248 249 SEMCONVPKG ?= "semconv/" 250 .PHONY: semconv-generate 251 semconv-generate: | $(SEMCONVGEN) $(SEMCONVKIT) 252 [ "$(TAG)" ] || ( echo "TAG unset: missing opentelemetry specification tag"; exit 1 ) 253 [ "$(OTEL_SPEC_REPO)" ] || ( echo "OTEL_SPEC_REPO unset: missing path to opentelemetry specification repo"; exit 1 ) 254 $(SEMCONVGEN) -i "$(OTEL_SPEC_REPO)/semantic_conventions/." --only=span -p conventionType=trace -f trace.go -t "$(SEMCONVPKG)/template.j2" -s "$(TAG)" 255 $(SEMCONVGEN) -i "$(OTEL_SPEC_REPO)/semantic_conventions/." --only=attribute_group -p conventionType=trace -f attribute_group.go -t "$(SEMCONVPKG)/template.j2" -s "$(TAG)" 256 $(SEMCONVGEN) -i "$(OTEL_SPEC_REPO)/semantic_conventions/." --only=event -p conventionType=event -f event.go -t "$(SEMCONVPKG)/template.j2" -s "$(TAG)" 257 $(SEMCONVGEN) -i "$(OTEL_SPEC_REPO)/semantic_conventions/." --only=resource -p conventionType=resource -f resource.go -t "$(SEMCONVPKG)/template.j2" -s "$(TAG)" 258 $(SEMCONVKIT) -output "$(SEMCONVPKG)/$(TAG)" -tag "$(TAG)" 259 260 .PHONY: prerelease 261 prerelease: | $(MULTIMOD) 262 @[ "${MODSET}" ] || ( echo ">> env var MODSET is not set"; exit 1 ) 263 $(MULTIMOD) verify && $(MULTIMOD) prerelease -m ${MODSET} 264 265 COMMIT ?= "HEAD" 266 .PHONY: add-tags 267 add-tags: | $(MULTIMOD) 268 @[ "${MODSET}" ] || ( echo ">> env var MODSET is not set"; exit 1 ) 269 $(MULTIMOD) verify && $(MULTIMOD) tag -m ${MODSET} -c ${COMMIT}