@@ -18,10 +18,14 @@ default: help
18
18
# - Test your changes with `make -d ...`! It should be reasonable!
19
19
20
20
# temporary build products and book-keeping targets that are always good to / safe to clean.
21
- BUILD := .build
22
- # less-than-temporary build products, e.g. tools.
23
- # usually unnecessary to clean, and may require downloads to restore, so this folder is not automatically cleaned.
24
- BIN := .bin
21
+ #
22
+ # the go version is embedded in the path, so changing Go's version or arch triggers rebuilds.
23
+ # other things can be added if necessary, but hopefully only go's formatting behavior matters?
24
+ # converts: "go version go1.19.5 darwin/arm64" -> "go1.19.5_darwin_arm64"
25
+ BUILD := .build/$(shell go version | cut -d' ' -f3- | sed 's/[^a-zA-Z0-9.]/_/g')
26
+ # tools that can be easily re-built on demand, and may be sensitive to dependency or go versions.
27
+ # currently this covers all needs. if not, consider STABLE_BIN like github.com/uber/cadence has.
28
+ BIN := $(BUILD ) /bin
25
29
26
30
# current (when committed) version of Go used in CI, and ideally also our docker images.
27
31
# this generally does not matter, but can impact goimports or formatting output.
@@ -45,14 +49,14 @@ endif
45
49
# recipes and any other prerequisites are defined only once, further below.
46
50
# ====================================
47
51
48
- # all bins depend on: $(BUILD)/lint
49
- # note that vars that do not yet exist are empty, so any prerequisites defined below are ineffective here.
52
+ # note that vars that do not yet exist are empty, so stick to BUILD/BIN and probably nothing else.
50
53
$(BUILD ) /lint : $(BUILD ) /fmt $(BUILD ) /dummy # lint will fail if fmt or dummy fails, so run them first
51
54
$(BUILD ) /dummy : $(BUILD ) /fmt # do a build after fmt-ing
52
55
$(BUILD ) /fmt : $(BUILD ) /copyright # formatting must occur only after all other go-file-modifications are done
53
56
$(BUILD ) /copyright : $(BUILD ) /codegen # must add copyright to generated code
54
57
$(BUILD ) /codegen : $(BUILD ) /thrift # thrift is currently the only codegen, but this way it's easier to extend
55
- $(BUILD ) /thrift :
58
+ $(BUILD ) /thrift : $(BUILD ) /go_mod_check
59
+ $(BUILD ) /go_mod_check : | $(BUILD ) $(BIN )
56
60
57
61
# ====================================
58
62
# helper vars
@@ -67,6 +71,30 @@ BIN_PATH := PATH="$(abspath $(BIN)):$$PATH"
67
71
# default test args, easy to override
68
72
TEST_ARG ?= -v -race
69
73
74
+ # set a V=1 env var for verbose output. V=0 (or unset) disables.
75
+ # this is used to make two verbose flags:
76
+ # - $Q, to replace ALL @ use, so CI can be reliably verbose
77
+ # - $(verbose), to forward verbosity flags to commands via `$(if $(verbose),-v)` or similar
78
+ #
79
+ # SHELL='bash -x' is useful too, but can be more confusing to understand.
80
+ V ?= 0
81
+ ifneq (0,$(V ) )
82
+ verbose := 1
83
+ Q :=
84
+ else
85
+ verbose :=
86
+ Q := @
87
+ endif
88
+
89
+ # and enforce ^ that rule: grep the makefile for line-starting @ use, error if any exist.
90
+ # limit to one match because multiple look too weird.
91
+ _BAD_AT_USE =$(shell grep -n -m1 '^\s* @' $(MAKEFILE_LIST ) )
92
+ ifneq (,$(_BAD_AT_USE ) )
93
+ $(warning Makefile cannot use @ to silence commands, use $$Q instead :)
94
+ $(warning found on line $(_BAD_AT_USE))
95
+ $(error fix that line and try again)
96
+ endif
97
+
70
98
# automatically gather all source files that currently exist.
71
99
# works by ignoring everything in the parens (and does not descend into matching folders) due to `-prune`,
72
100
# and everything else goes to the other side of the `-o` branch, which is `-print`ed.
@@ -96,33 +124,49 @@ LINT_SRC := $(filter-out %_test.go ./.gen/% ./mock% ./tools.go ./internal/compat
96
124
# $(BIN) targets
97
125
# ====================================
98
126
127
+ # builds a go-gettable tool, versioned by internal/tools/go.mod, and installs it into
128
+ # the build folder, named the same as the last portion of the URL or the second arg.
129
+ define go_build_tool
130
+ $Q echo "building $(or $(2 ) , $(notdir $(1 ) ) ) from internal/tools/go.mod..."
131
+ $Q go build -mod=readonly -modfile=internal/tools/go.mod -o $(BIN ) /$(or $(2 ) , $(notdir $(1 ) ) ) $(1 )
132
+ endef
133
+
99
134
# utility target.
100
135
# use as an order-only prerequisite for targets that do not implicitly create these folders.
101
136
$(BIN ) $(BUILD ) :
102
- @mkdir -p $@
137
+ $Q mkdir -p $@
138
+
139
+ $(BIN ) /thriftrw : internal/tools/go.mod
140
+ $(call go_build_tool,go.uber.org/thriftrw)
103
141
104
- $(BIN ) /thriftrw: go.mod
105
- go build -mod=readonly -o $@ go.uber.org/thriftrw
142
+ $(BIN ) /thriftrw-plugin-yarpc : internal/tools/ go.mod
143
+ $( call go_build_tool, go.uber.org/yarpc/encoding/thrift/ thriftrw-plugin-yarpc)
106
144
107
- $(BIN ) /thriftrw-plugin-yarpc : go.mod
108
- go build -mod=readonly -o $@ go.uber. org/yarpc/encoding/thrift/thriftrw-plugin-yarpc
145
+ $(BIN ) /golint : internal/tools/ go.mod
146
+ $( call go_build_tool,golang. org/x/lint/golint)
109
147
110
- $(BIN ) /golint : go.mod
111
- go build -mod=readonly -o $@ golang.org/x/lint/golint
148
+ $(BIN ) /staticcheck : internal/tools/ go.mod
149
+ $( call go_build_tool,honnef.co/go/tools/cmd/staticcheck)
112
150
113
- $(BIN ) /staticcheck : go.mod
114
- go build -mod=readonly -o $@ honnef.co/go/tools/cmd/staticcheck
151
+ $(BIN ) /errcheck : internal/tools/ go.mod
152
+ $( call go_build_tool,github.com/kisielk/errcheck)
115
153
116
- $(BIN ) /errcheck : go.mod
117
- go build -mod=readonly -o $@ github.com/kisielk/errcheck
154
+ $(BIN ) /goveralls : internal/tools/ go.mod
155
+ $( call go_build_tool, github.com/mattn/goveralls)
118
156
119
157
# copyright header checker/writer. only requires stdlib, so no other dependencies are needed.
120
- $(BIN ) /copyright : internal/cmd/tools/copyright/licensegen.go go.mod
158
+ $(BIN ) /copyright : internal/cmd/tools/copyright/licensegen.go
121
159
go build -mod=readonly -o $@ ./internal/cmd/tools/copyright/licensegen.go
122
160
123
161
# dummy binary that ensures most/all packages build, without needing to wait for tests.
124
- $(BUILD ) /dummy : $(ALL_SRC ) go.mod
125
- go build -o $@ internal/cmd/dummy/dummy.go
162
+ $(BUILD ) /dummy : $(ALL_SRC ) $(BUILD ) /go_mod_check
163
+ go build -mod=readonly -o $@ internal/cmd/dummy/dummy.go
164
+
165
+ # ensures mod files are in sync for critical packages
166
+ $(BUILD ) /go_mod_check : go.mod internal/tools/go.mod
167
+ $Q # ensure both have the same apache/thrift replacement
168
+ $Q ./scripts/check-gomod-version.sh go.uber.org/thriftrw $(if $(verbose ) ,-v)
169
+ $Q touch $@
126
170
127
171
# ====================================
128
172
# Codegen targets
@@ -139,35 +183,35 @@ endef
139
183
140
184
# codegen is done when thrift is done (it's just a naming-convenience, $(BUILD)/thrift would be fine too)
141
185
$(BUILD ) /codegen : $(BUILD ) /thrift | $(BUILD )
142
- @ touch $@
186
+ $Q touch $@
143
187
144
188
THRIFT_FILES := idls/thrift/cadence.thrift idls/thrift/shadower.thrift
145
189
# book-keeping targets to build. one per thrift file.
146
- # idls/thrift/thing.thrift -> .build/thing.thrift
190
+ # idls/thrift/thing.thrift -> .build/go_version/ thing.thrift
147
191
# the reverse is done in the recipe.
148
- THRIFT_GEN := $(subst idls/thrift/,.build/ ,$(THRIFT_FILES ) )
192
+ THRIFT_GEN := $(subst idls/thrift, $( BUILD ) ,$(THRIFT_FILES ) )
149
193
150
194
# dummy targets to detect when the idls submodule does not exist, to provide a better error message
151
195
$(THRIFT_FILES ) :
152
196
$(call ensure_idl_submodule)
153
197
154
198
# thrift is done when all sub-thrifts are done.
155
- $(BUILD ) /thrift : $(THRIFT_GEN ) | $( BUILD )
156
- @ touch $@
199
+ $(BUILD ) /thrift : $(THRIFT_GEN )
200
+ $Q touch $@
157
201
158
202
# how to generate each thrift book-keeping file.
159
203
#
160
204
# note that each generated file depends on ALL thrift files - this is necessary because they can import each other.
161
205
# ideally this would --no-recurse like the server does, but currently that produces a new output file, and parallel
162
206
# compiling appears to work fine. seems likely it only risks rare flaky builds.
163
- $(THRIFT_GEN ) : $(THRIFT_FILES ) $(BIN ) /thriftrw $(BIN ) /thriftrw-plugin-yarpc | $( BUILD )
164
- @ echo ' thriftrw for $(subst .build/ ,idls/thrift/ ,$@)...'
165
- @ $(BIN_PATH ) $(BIN ) /thriftrw \
207
+ $(THRIFT_GEN ) : $(THRIFT_FILES ) $(BIN ) /thriftrw $(BIN ) /thriftrw-plugin-yarpc
208
+ $Q echo ' thriftrw for $(subst $(BUILD) ,idls/thrift,$@)...'
209
+ $Q $(BIN_PATH ) $(BIN ) /thriftrw \
166
210
--plugin=yarpc \
167
211
--pkg-prefix=$(PROJECT_ROOT ) /.gen/go \
168
212
--out=.gen/go \
169
- $(subst .build/ ,idls/thrift/ ,$@ )
170
- @ touch $@
213
+ $(subst $( BUILD ) ,idls/thrift,$@ )
214
+ $Q touch $@
171
215
172
216
# ====================================
173
217
# other intermediates
@@ -190,7 +234,7 @@ endef
190
234
# TODO: replace this with revive, like the server.
191
235
# keep in sync with `lint`
192
236
$(BUILD ) /lint : $(BIN ) /golint $(ALL_SRC )
193
- @ $(foreach pkg, \
237
+ $Q $(foreach pkg, \
194
238
$(sort $(dir $(LINT_SRC ) ) ) , \
195
239
$(call lint_if_present,$(filter $(wildcard $(pkg ) * .go) ,$(LINT_SRC ) ) ) || ERR=1; \
196
240
) test -z " $$ ERR" ; touch $@ ; exit $$ ERR
@@ -209,20 +253,18 @@ $(BUILD)/lint: $(BIN)/golint $(ALL_SRC)
209
253
MAYBE_TOUCH_COPYRIGHT =
210
254
211
255
# TODO: switch to goimports, so we can pin the version
212
- $(BUILD ) /fmt : $(ALL_SRC ) | $( BUILD )
213
- @ echo " gofmt..."
214
- @ # use FRESH_ALL_SRC so it won't miss any generated files produced earlier
215
- @ gofmt -w $(ALL_SRC )
216
- @ # ideally, mimic server: $(BIN)/goimports -local "go.uber.org/cadence" -w $(FRESH_ALL_SRC)
217
- @ touch $@
218
- @ $(MAYBE_TOUCH_COPYRIGHT )
219
-
220
- $(BUILD ) /copyright : $(ALL_SRC ) $(BIN ) /copyright | $( BUILD )
256
+ $(BUILD ) /fmt : $(ALL_SRC )
257
+ $Q echo " gofmt..."
258
+ $Q # use FRESH_ALL_SRC so it won't miss any generated files produced earlier
259
+ $Q gofmt -w $(ALL_SRC )
260
+ $Q # ideally, mimic server: $(BIN)/goimports -local "go.uber.org/cadence" -w $(FRESH_ALL_SRC)
261
+ $Q touch $@
262
+ $Q $(MAYBE_TOUCH_COPYRIGHT )
263
+
264
+ $(BUILD ) /copyright : $(ALL_SRC ) $(BIN ) /copyright
221
265
$(BIN ) /copyright --verifyOnly
222
- @$(eval MAYBE_TOUCH_COPYRIGHT=touch $@ )
223
- @touch $@
224
-
225
- $(BUILD ) /dummy : $(ALL_SRC ) go.mod
266
+ $Q $(eval MAYBE_TOUCH_COPYRIGHT=touch $@ )
267
+ $Q touch $@
226
268
227
269
# ====================================
228
270
# developer-oriented targets
@@ -239,8 +281,8 @@ build: $(BUILD)/dummy ## ensure all packages build
239
281
# useful to actually re-run to get output again, as the intermediate will not be run unless necessary.
240
282
# dummy is used only because it occurs before $(BUILD)/lint, fmt would likely be sufficient too.
241
283
# keep in sync with `$(BUILD)/lint`
242
- lint : $(BUILD ) /dummy # # (re)run golint
243
- @ $(foreach pkg, \
284
+ lint : $(BUILD ) /dummy $( BIN ) /golint # # (re)run golint
285
+ $Q $(foreach pkg, \
244
286
$(sort $(dir $(LINT_SRC ) ) ) , \
245
287
$(call lint_if_present,$(filter $(wildcard $(pkg ) * .go) ,$(LINT_SRC ) ) ) || ERR=1; \
246
288
) test -z " $$ ERR" ; touch $(BUILD ) /lint; exit $$ ERR
@@ -253,7 +295,7 @@ fmt: $(BUILD)/fmt ## run gofmt
253
295
# not identical to the intermediate target, but does provide the same codegen (or more).
254
296
copyright : $(BIN ) /copyright # # update copyright headers
255
297
$(BIN ) /copyright
256
- @ touch $(BUILD ) /copyright
298
+ $Q touch $(BUILD ) /copyright
257
299
258
300
.PHONY : staticcheck
259
301
staticcheck : $(BIN ) /staticcheck $(BUILD ) /fmt # # (re)run staticcheck
@@ -268,9 +310,10 @@ all: $(BUILD)/lint ## refresh codegen, lint, and ensure the dummy binary builds,
268
310
269
311
.PHONY : clean
270
312
clean :
271
- rm -Rf $(BUILD ) .gen
272
- @# remove old things (no longer in use). this can be removed "eventually", when we feel like they're unlikely to exist.
273
- rm -Rf .bins dummy
313
+ $Q # intentionally not using $(BUILD) as that covers only a single version
314
+ rm -Rf .build .gen
315
+ $Q # remove old things (no longer in use). this can be removed "eventually", when we feel like they're unlikely to exist.
316
+ rm -Rf .bin
274
317
275
318
# broken up into multiple += so I can interleave comments.
276
319
# this all becomes a single line of output.
@@ -295,20 +338,20 @@ JQ_DEPS_ONLY_DIRECT = | select(has("Indirect") | not)
295
338
296
339
.PHONY : deps
297
340
deps : # # Check for dependency updates, for things that are directly imported
298
- @ make --no-print-directory DEPS_FILTER=' $(JQ_DEPS_ONLY_DIRECT)' deps-all
341
+ $Q make --no-print-directory DEPS_FILTER=' $(JQ_DEPS_ONLY_DIRECT)' deps-all
299
342
300
343
.PHONY : deps-all
301
344
deps-all : # # Check for all dependency updates
302
- @ go list -u -m -json all \
345
+ $Q go list -u -m -json all \
303
346
| $(JQ_DEPS_AGE ) \
304
347
| sort -n
305
348
306
349
.PHONY : help
307
350
help :
308
- @ # print help first, so it's visible
309
- @ printf " \033[36m%-20s\033[0m %s\n" ' help' ' Prints a help message showing any specially-commented targets'
310
- @ # then everything matching "target: ## magic comments"
311
- @ cat $(MAKEFILE_LIST ) | grep -e " ^[a-zA-Z_\-]*:.* ## .*" | awk ' BEGIN {FS = ":.*? ## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}' | sort
351
+ $Q # print help first, so it's visible
352
+ $Q printf " \033[36m%-20s\033[0m %s\n" ' help' ' Prints a help message showing any specially-commented targets'
353
+ $Q # then everything matching "target: ## magic comments"
354
+ $Q cat $(MAKEFILE_LIST ) | grep -e " ^[a-zA-Z_\-]*:.* ## .*" | awk ' BEGIN {FS = ":.*? ## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}' | sort
312
355
313
356
# v==================== not yet cleaned up =======================v
314
357
@@ -325,9 +368,9 @@ UT_DIRS := $(filter-out $(INTEG_TEST_ROOT)%, $(sort $(dir $(filter %_test.go,$(A
325
368
test : unit_test integ_test_sticky_off integ_test_sticky_on # # run all tests (requires a running cadence instance)
326
369
327
370
unit_test : $(ALL_SRC ) # # run all unit tests
328
- @ mkdir -p $(COVER_ROOT )
329
- @ echo " mode: atomic" > $(UT_COVER_FILE )
330
- @ failed=0; \
371
+ $Q mkdir -p $(COVER_ROOT )
372
+ $Q echo " mode: atomic" > $(UT_COVER_FILE )
373
+ $Q failed=0; \
331
374
for dir in $( UT_DIRS) ; do \
332
375
mkdir -p $(COVER_ROOT ) /" $$ dir" ; \
333
376
go test " $$ dir" $(TEST_ARG ) -coverprofile=$(COVER_ROOT ) /" $$ dir" /cover.out || failed=1; \
@@ -336,26 +379,31 @@ unit_test: $(ALL_SRC) ## run all unit tests
336
379
exit $$ failed
337
380
338
381
integ_test_sticky_off : $(ALL_SRC )
339
- @ mkdir -p $(COVER_ROOT )
382
+ $Q mkdir -p $(COVER_ROOT )
340
383
STICKY_OFF=true go test $(TEST_ARG ) ./test -coverprofile=$(INTEG_STICKY_OFF_COVER_FILE ) -coverpkg=./...
341
384
342
385
integ_test_sticky_on : $(ALL_SRC )
343
- @ mkdir -p $(COVER_ROOT )
386
+ $Q mkdir -p $(COVER_ROOT )
344
387
STICKY_OFF=false go test $(TEST_ARG ) ./test -coverprofile=$(INTEG_STICKY_ON_COVER_FILE ) -coverpkg=./...
345
388
346
389
integ_test_grpc : $(ALL_SRC )
347
- @ mkdir -p $(COVER_ROOT )
390
+ $Q mkdir -p $(COVER_ROOT )
348
391
STICKY_OFF=false go test $(TEST_ARG ) ./test -coverprofile=$(INTEG_GRPC_COVER_FILE ) -coverpkg=./...
349
392
393
+ # intermediate product, ci needs a stable output, so use coverage_report.
394
+ # running this target requires coverage files to have already been created, e.g. run ^ the above by hand, which happens in ci.
350
395
$(COVER_ROOT ) /cover.out : $(UT_COVER_FILE ) $(INTEG_STICKY_OFF_COVER_FILE ) $(INTEG_STICKY_ON_COVER_FILE ) $(INTEG_GRPC_COVER_FILE )
351
- @ echo " mode: atomic" > $(COVER_ROOT ) /cover.out
396
+ $Q echo " mode: atomic" > $(COVER_ROOT ) /cover.out
352
397
cat $(UT_COVER_FILE ) | grep -v " mode: atomic" | grep -v " .gen" >> $(COVER_ROOT ) /cover.out
353
398
cat $(INTEG_STICKY_OFF_COVER_FILE ) | grep -v " mode: atomic" | grep -v " .gen" >> $(COVER_ROOT ) /cover.out
354
399
cat $(INTEG_STICKY_ON_COVER_FILE ) | grep -v " mode: atomic" | grep -v " .gen" >> $(COVER_ROOT ) /cover.out
355
400
cat $(INTEG_GRPC_COVER_FILE ) | grep -v " mode: atomic" | grep -v " .gen" >> $(COVER_ROOT ) /cover.out
356
401
402
+ coverage_report : $(COVER_ROOT ) /cover.out
403
+ cp $< $@
404
+
357
405
cover : $(COVER_ROOT ) /cover.out
358
406
go tool cover -html=$(COVER_ROOT ) /cover.out;
359
407
360
- cover_ci : $(COVER_ROOT ) /cover.out
361
- goveralls -coverprofile=$(COVER_ROOT ) /cover.out -service=buildkite || echo -e " \x1b[31mCoveralls failed\x1b[m" ;
408
+ cover_ci : $(COVER_ROOT ) /cover.out $( BIN ) /goveralls
409
+ $( BIN ) / goveralls -coverprofile=$(COVER_ROOT ) /cover.out -service=buildkite || echo -e " \x1b[31mCoveralls failed\x1b[m" ;
0 commit comments