|
1 | 1 | # https://github.com/aperturerobotics/template |
| 2 | +PROJECT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST)))) |
| 3 | +SHELL:=bash |
| 4 | +MAKEFLAGS += --no-print-directory |
2 | 5 |
|
3 | | -# Projects can override PROJECT_DIR with the path to their project. |
4 | | -COMMON_DIR = $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST)))) |
5 | | -PROJECT_DIR := $(COMMON_DIR) |
6 | | -PROJECT_DIR_REL = $(shell realpath --relative-to $(COMMON_DIR) $(PROJECT_DIR)) |
| 6 | +GO_VENDOR_DIR := ./vendor |
| 7 | +COMMON_DIR := $(GO_VENDOR_DIR)/github.com/aperturerobotics/common |
7 | 8 |
|
| 9 | +COMMON_MAKEFILE := $(COMMON_DIR)/Makefile |
8 | 10 | TOOLS_DIR := .tools |
9 | | -TOOLS_BIN := $(TOOLS_DIR)/bin |
10 | | - |
11 | | -PROJECT_TOOLS_DIR := $(PROJECT_DIR)/$(TOOLS_DIR) |
12 | | -PROJECT_TOOLS_DIR_REL = $(shell realpath --relative-to $(COMMON_DIR) $(PROJECT_TOOLS_DIR)) |
13 | | - |
14 | | -SHELL:=bash |
15 | | -MAKEFLAGS += --no-print-directory |
| 11 | +TOOLS_MAKEFILE := .tools/Makefile |
16 | 12 |
|
17 | 13 | export GO111MODULE=on |
18 | 14 | undefine GOARCH |
19 | 15 | undefine GOOS |
20 | 16 |
|
21 | | -.PHONY: all |
22 | | -all: protodeps |
23 | | - |
24 | | -# Setup node_modules |
25 | | -$(PROJECT_DIR)/node_modules: |
26 | | - cd $(PROJECT_DIR_REL); yarn install |
27 | | - |
28 | | -# Setup the .tools directory to hold the build tools in the project repo |
29 | | -$(PROJECT_TOOLS_DIR): |
30 | | - @cd $(PROJECT_DIR); go run -v github.com/aperturerobotics/common $(TOOLS_DIR) |
31 | | - |
32 | | -.PHONY: tools |
33 | | -tools: $(PROJECT_TOOLS_DIR) |
34 | | - |
35 | | -# Build tool rule |
36 | | -define build_tool |
37 | | -$(PROJECT_DIR)/$(1): $(PROJECT_TOOLS_DIR) |
38 | | - cd $(PROJECT_TOOLS_DIR_REL); \ |
39 | | - go build -mod=readonly -v \ |
40 | | - -o ./bin/$(shell basename $(1)) \ |
41 | | - $(2) |
42 | | - |
43 | | -.PHONY: $(1) |
44 | | -$(1): $(PROJECT_DIR)/$(1) |
45 | | -endef |
46 | | - |
47 | | -# List of available Go tool binaries |
48 | | -PROTOWRAP=$(TOOLS_BIN)/protowrap |
49 | | -PROTOC_GEN_GO=$(TOOLS_BIN)/protoc-gen-go-lite |
50 | | -PROTOC_GEN_GO_STARPC=$(TOOLS_BIN)/protoc-gen-go-starpc |
51 | | -GOIMPORTS=$(TOOLS_BIN)/goimports |
52 | | -GOFUMPT=$(TOOLS_BIN)/gofumpt |
53 | | -GOLANGCI_LINT=$(TOOLS_BIN)/golangci-lint |
54 | | -GO_MOD_OUTDATED=$(TOOLS_BIN)/go-mod-outdated |
55 | | -GORELEASER=$(TOOLS_BIN)/goreleaser |
56 | | -WASMBROWSERTEST=$(TOOLS_BIN)/wasmbrowsertest |
57 | | - |
58 | | -# Mappings for build tool to Go import path |
59 | | -$(eval $(call build_tool,$(PROTOC_GEN_GO),github.com/aperturerobotics/protobuf-go-lite/cmd/protoc-gen-go-lite)) |
60 | | -$(eval $(call build_tool,$(PROTOC_GEN_GO_STARPC),github.com/aperturerobotics/starpc/cmd/protoc-gen-go-starpc)) |
61 | | -$(eval $(call build_tool,$(GOIMPORTS),golang.org/x/tools/cmd/goimports)) |
62 | | -$(eval $(call build_tool,$(GOFUMPT),mvdan.cc/gofumpt)) |
63 | | -$(eval $(call build_tool,$(PROTOWRAP),github.com/aperturerobotics/goprotowrap/cmd/protowrap)) |
64 | | -$(eval $(call build_tool,$(GOLANGCI_LINT),github.com/golangci/golangci-lint/cmd/golangci-lint)) |
65 | | -$(eval $(call build_tool,$(GO_MOD_OUTDATED),github.com/psampaz/go-mod-outdated)) |
66 | | -$(eval $(call build_tool,$(GORELEASER),github.com/goreleaser/goreleaser)) |
67 | | -$(eval $(call build_tool,$(WASMBROWSERTEST),github.com/agnivade/wasmbrowsertest)) |
68 | | - |
69 | | -.PHONY: protodeps |
70 | | -protodeps: $(GOIMPORTS) $(PROTOWRAP) $(PROTOC_GEN_GO) $(PROTOC_GEN_GO_STARPC) $(PROJECT_DIR)/node_modules |
71 | | - |
72 | | -# Default protogen targets and arguments |
73 | | -PROTOGEN_TARGETS ?= ./*.proto |
74 | | -PROTOGEN_ARGS ?= |
75 | | -GO_LITE_OPT_FEATURES ?= marshal+unmarshal+size+equal+json+clone+text |
76 | | - |
77 | | -.PHONY: genproto |
78 | | -genproto: protodeps |
79 | | - @shopt -s globstar; \ |
80 | | - set -eo pipefail; \ |
81 | | - cd $(PROJECT_DIR); \ |
82 | | - export PROTOBUF_GO_TYPES_PKG=github.com/aperturerobotics/protobuf-go-lite/types; \ |
83 | | - export PROJECT=$$(go list -m); \ |
84 | | - export OUT=./vendor; \ |
85 | | - mkdir -p $${OUT}/$$(dirname $${PROJECT}); \ |
86 | | - rm -f ./vendor/$${PROJECT}; \ |
87 | | - ln -s $$(pwd) ./vendor/$${PROJECT}; \ |
88 | | - protogen() { \ |
89 | | - PROTO_FILES=$$(git ls-files "$$1"); \ |
90 | | - FMT_GO_FILES=(); \ |
91 | | - FMT_TS_FILES=(); \ |
92 | | - PROTOWRAP_OPTS=(); \ |
93 | | - if [ -f "go.mod" ]; then \ |
94 | | - PROTOWRAP_OPTS+=( \ |
95 | | - --plugin=$(PROTOC_GEN_GO) \ |
96 | | - --plugin=$(PROTOC_GEN_GO_STARPC) \ |
97 | | - --go-lite_out=$${OUT} \ |
98 | | - --go-lite_opt=features=$(GO_LITE_OPT_FEATURES) \ |
99 | | - --go-starpc_out=$${OUT} \ |
100 | | - ); \ |
101 | | - fi; \ |
102 | | - if [ -f "package.json" ]; then \ |
103 | | - PROTOWRAP_OPTS+=( \ |
104 | | - --plugin=./node_modules/.bin/protoc-gen-es \ |
105 | | - --plugin=./node_modules/.bin/protoc-gen-es-starpc \ |
106 | | - --es-lite_out=$${OUT} \ |
107 | | - --es-lite_opt target=ts \ |
108 | | - --es-lite_opt ts_nocheck=false \ |
109 | | - --es-starpc_out=$${OUT} \ |
110 | | - --es-starpc_opt target=ts \ |
111 | | - --es-starpc_opt ts_nocheck=false \ |
112 | | - ); \ |
113 | | - fi; \ |
114 | | - $(PROTOWRAP) \ |
115 | | - -I $${OUT} \ |
116 | | - "$${PROTOWRAP_OPTS[@]}" \ |
117 | | - --proto_path $${OUT} \ |
118 | | - --print_structure \ |
119 | | - --only_specified_files \ |
120 | | - $(PROTOGEN_ARGS) \ |
121 | | - $$(echo "$$PROTO_FILES" | xargs printf -- "./vendor/$${PROJECT}/%s "); \ |
122 | | - for proto_file in $${PROTO_FILES}; do \ |
123 | | - proto_dir=$$(dirname $$proto_file); \ |
124 | | - proto_name=$${proto_file%".proto"}; \ |
125 | | - GO_FILES=$$(git ls-files ":(glob)$${proto_dir}/${proto_name}*.pb.go"); \ |
126 | | - if [ -n "$$GO_FILES" ]; then FMT_GO_FILES+=($${GO_FILES[@]}); fi; \ |
127 | | - TS_FILES=$$(git ls-files ":(glob)$${proto_dir}/${proto_name}*.pb.ts"); \ |
128 | | - if [ -n "$$TS_FILES" ]; then FMT_TS_FILES+=($${TS_FILES[@]}); fi; \ |
129 | | - if [ -z "$$TS_FILES" ]; then continue; fi; \ |
130 | | - for ts_file in $${TS_FILES}; do \ |
131 | | - ts_file_dir=$$(dirname $$ts_file); \ |
132 | | - relative_path=$${ts_file_dir#"./"}; \ |
133 | | - depth=$$(echo $$relative_path | awk -F/ '{print NF+1}'); \ |
134 | | - prefix=$$(printf '../%0.s' $$(seq 1 $$depth)); \ |
135 | | - istmts=$$(grep -oE "from\s+\"$$prefix[^\"]+\"" $$ts_file) || continue; \ |
136 | | - if [ -z "$$istmts" ]; then continue; fi; \ |
137 | | - ipaths=$$(echo "$$istmts" | awk -F'"' '{print $$2}'); \ |
138 | | - for import_path in $$ipaths; do \ |
139 | | - rel_import_path=$$(realpath -s --relative-to=./vendor \ |
140 | | - "./vendor/$${PROJECT}/$${ts_file_dir}/$${import_path}"); \ |
141 | | - go_import_path=$$(echo $$rel_import_path | sed -e "s|^|@go/|"); \ |
142 | | - sed -i -e "s|$$import_path|$$go_import_path|g" $$ts_file; \ |
143 | | - done; \ |
144 | | - done; \ |
145 | | - done; \ |
146 | | - if [ -n "$${FMT_GO_FILES}" ]; then \ |
147 | | - $(GOIMPORTS) -w $${FMT_GO_FILES[@]}; \ |
148 | | - fi; \ |
149 | | - if [ -n "$${FMT_TS_FILES}" ]; then \ |
150 | | - prettier --config $(TOOLS_DIR)/.prettierrc.yaml -w $${FMT_TS_FILES[@]}; \ |
151 | | - fi; \ |
152 | | - }; \ |
153 | | - protogen "$(PROTOGEN_TARGETS)"; \ |
154 | | - rm -f ./vendor/$${PROJECT} |
155 | | - |
156 | | -.PHONY: gen |
157 | | -gen: genproto |
158 | | - |
159 | | -.PHONY: outdated |
160 | | -outdated: $(GO_MOD_OUTDATED) |
161 | | - cd $(PROJECT_DIR); \ |
162 | | - go list -mod=mod -u -m -json all | $(GO_MOD_OUTDATED) -update -direct |
163 | | - |
164 | | -.PHONY: list |
165 | | -list: $(GO_MOD_OUTDATED) |
166 | | - cd $(PROJECT_DIR); \ |
167 | | - go list -mod=mod -u -m -json all | $(GO_MOD_OUTDATED) |
168 | | - |
169 | | -.PHONY: lint |
170 | | -lint: $(GOLANGCI_LINT) |
171 | | - cd $(PROJECT_DIR); \ |
172 | | - $(GOLANGCI_LINT) run |
173 | | - |
174 | | -.PHONY: fix |
175 | | -fix: $(GOLANGCI_LINT) |
176 | | - cd $(PROJECT_DIR); \ |
177 | | - $(GOLANGCI_LINT) run --fix |
178 | | - |
179 | | -.PHONY: test |
180 | | -test: |
181 | | - cd $(PROJECT_DIR); \ |
182 | | - go test -v ./... |
| 17 | +.PHONY: $(MAKECMDGOALS) |
183 | 18 |
|
184 | | -.PHONY: test-browser |
185 | | -test-browser: $(WASMBROWSERTEST) |
186 | | - cd $(PROJECT_DIR); \ |
187 | | - GOOS=js GOARCH=wasm go test -exec $(WASMBROWSERTEST) -v ./... |
| 19 | +all: |
188 | 20 |
|
189 | | -.PHONY: format |
190 | | -format: $(GOFUMPT) $(GOIMPORTS) |
191 | | - cd $(PROJECT_DIR); \ |
192 | | - $(GOIMPORTS) -w ./; \ |
193 | | - $(GOFUMPT) -w ./ |
| 21 | +$(COMMON_MAKEFILE): vendor |
| 22 | + @if [ ! -f $(COMMON_MAKEFILE) ]; then \ |
| 23 | + echo "Please add github.com/aperturerobotics/common to your go.mod."; \ |
| 24 | + exit 1; \ |
| 25 | + fi |
194 | 26 |
|
195 | | -.PHONY: release |
196 | | -release: $(GORELEASER) |
197 | | - cd $(PROJECT_DIR); \ |
198 | | - $(GORELEASER) release $(GORELEASER_OPTS) |
| 27 | +$(TOOLS_MAKEFILE): $(COMMON_MAKEFILE) |
| 28 | + @$(MAKE) -C $(COMMON_DIR) TOOLS_DIR="$(TOOLS_DIR)" PROJECT_DIR="$(PROJECT_DIR)" tools |
199 | 29 |
|
200 | | -.PHONY: release-bundl\e |
201 | | -release-bundle: $(GORELEASER) |
202 | | - cd $(PROJECT_DIR); \ |
203 | | - $(GORELEASER) check; \ |
204 | | - $(GORELEASER) release --snapshot --clean --skip-publish $(GORELEASER_OPTS) |
| 30 | +$(MAKECMDGOALS): $(TOOLS_MAKEFILE) |
| 31 | + @$(MAKE) -C $(TOOLS_DIR) TOOLS_DIR="$(TOOLS_DIR)" PROJECT_DIR="$(PROJECT_DIR)" $@ |
205 | 32 |
|
206 | | -.PHONY: release-build |
207 | | -release-build: $(GORELEASER) |
208 | | - cd $(PROJECT_DIR); \ |
209 | | - $(GORELEASER) check; \ |
210 | | - $(GORELEASER) build --single-target --snapshot --clean $(GORELEASER_OPTS) |
| 33 | +%: $(TOOLS_MAKEFILE) |
| 34 | + @$(MAKE) -C $(TOOLS_DIR) TOOLS_DIR="$(TOOLS_DIR)" PROJECT_DIR="$(PROJECT_DIR)" $@ |
211 | 35 |
|
212 | | -.PHONY: release-check |
213 | | -release-check: $(GORELEASER) |
214 | | - cd $(PROJECT_DIR); \ |
215 | | - $(GORELEASER) check |
| 36 | +vendor: |
| 37 | + go mod vendor |
0 commit comments