This repository has been archived by the owner on Mar 24, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Makefile
332 lines (271 loc) · 8.5 KB
/
Makefile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
## ----- VARIABLES -----
PKG_NAME = $(shell basename "$$(pwd)")
ifeq ($(shell ls -1 go.mod 2> /dev/null),go.mod) # use module name from go.mod, if applicable
PKG_NAME = $(shell basename "$$(cat go.mod | grep module | awk '{print $$2}')")
endif
VERSION = $(shell git describe --tags | cut -c 2-)
## Directory of the 'main' package.
# MAINDIR = "."
## Output directory to place artifacts from 'build' and 'build-all'.
# OUTDIR = "."
## Enable Go modules for this project.
MODULE = true
## Enable `go generate` for this project.
GENERATE = false
## Enable goreleaser for this project.
GORELEASER = false
## Enable git-secret for this project.
SECRETS = true
## Custom Go linker flags:
# LDFLAGS = -X github.com/stevenxie/$(PKG_NAME)/cmd.Version=$(VERSION)
## Source configs:
SRC_FILES = $(shell find . -type f -name '*.go' -not -path "./vendor/*")
SRC_PKGS = $(shell go list ./... | grep -v /vendor/)
## Testing configs:
TEST_TIMEOUT = 20s
COVER_OUT = coverage.out
## ------ COMMANDS -----
.PHONY: default setup init
## Default target when no arguments are given to make (build and run program).
default: build-run
## Sets up this project on a new device.
setup: hooks-setup
@if [ "$(SECRETS)" == true ]; then $(SECRETS_REVEAL_CM); fi
@if [ "$(MODULE)" == true ]; \
then $(DL_CMD); \
else $(GET_CMD); \
fi
## Initializes this project from scratch.
## Variables: MODPATH
init: mod-init secrets-init goreleaser-init
## [Git, git-secret]
.PHONY: hooks-setup secrets-hide secrets-reveal
## Configure Git to use .githooks (for shared githooks).
hooks-setup:
@echo "Configuring githooks..."
@git config core.hooksPath .githooks && echo "done"
## Initialize git-secret.
secrets-init:
@if [ "$(SECRETS)" == true ]; then \
echo "Initializing git..." && git init && \
echo "Initializing git-secret..." && \
git-secret init; \
fi
## Hide modified secret files using git-secret.
secrets-hide:
@echo "Hiding modified secret files..."
@git secret hide -m
## Reveal files hidden by git-secret.
SECRETS_REVEAL_CM = git secret reveal
secrets-reveal:
@echo "Revealing hidden secret files..."
@$(SECRETS_REVEAL_CM)
## [Go: modules]
.PHONY: mod-init verify dl vendor tidy update fix
## Initializes a Go module in the current directory.
## Variables: MODPATH (module source path)
MODPATH =
mod-init:
@if [ "$(MODULE)" == true ]; then \
echo "Initializing Go module..." && \
go mod init $(MODPATH); \
fi
## Verifies that Go module dependencies are satisfied.
VERIFY_CMD = echo "Verifying Go module dependencies..." && go mod verify
verify:
@$(VERIFY_CMD)
## Downloads Go module dependencies.
DL_CMD = echo "Downloading Go module dependencies..." && \
go mod download && echo "done"
dl:
@$(DL_CMD)
## Vendors Go module dependencies.
vendor:
@echo "Vendoring Go module dependencies..."
@go mod vendor && echo "done"
## Tidies Go module dependencies.
tidy:
@echo "Tidying Go module dependencies..."
@go mod tidy && echo "done"
## Installs and updates package dependencies.
## Variables:
## UMODE (Update Mode, choose between 'patch' and 'minor').
UMODE =
update:
@echo 'Updating module dependencies with "go get -u"...'
@go get -u $(UMODE) && echo "done"
## Fixes deprecated Go code using "go fix", by rewriting old APIS to use
## newer ones.
fix:
@echo 'Fixing deprecated Go code with "go fix"... '
@go fix && echo "done"
## [Go: legacy setup]
.PHONY: get
## Downloads and installs all subpackages (legacy).
GET_CMD = echo "Installing dependencies... " && \
go get ./... && echo "done"
get:
@$(GET_CMD)
## [Go: setup, running]
.PHONY: build build-all build-run generate run clean install
## Runs the built program.
## Sources .env.sh if it exists.
## Variables: SRCENV (boolean which determines whether or not to check and
## source .env.sh)
SRCENV = true
OUTPATH = $(OUTDIR)/$(PKG_NAME)
RUN_CMD = \
if [ -f ".env.sh" ] && [ "$(SRCENV)" == true ]; then \
echo 'Configuring environment variables by sourcing ".env.sh"...' && \
. .env.sh && \
printf "done\n\n"; \
fi; \
if [ -f "$(OUTPATH)" ]; then \
echo 'Running "$(PKG_NAME)"...' && \
./$(OUTPATH); \
else \
echo 'run: could not find program "$(OUTPATH)".' >&2; \
exit 1; \
fi
run:
@$(RUN_CMD)
generate:
@if [ "$(GENERATE)" == true ]; then \
echo "Generating Go code using 'go generate'..." && \
go generate ./...; \
fi
## Builds (compiles) the program for this system.
## Variables:
## - OUTDIR (output directory to place built binaries)
## - MAINDIR (directory of the main package)
## - BUILDARGS (additional arguments to pass to "go build")
BUILDARGS =
BUILD_CMD = \
echo 'Building "$(PKG_NAME)" for this system...' && \
go build \
-o "$$(echo $(OUTDIR) | tr -s '/')/$(PKG_NAME)" \
-ldflags "$(LDFLAGS)" \
$(BUILDARGS) $(MAINDIR) && \
echo "done"
build: generate
@$(BUILD_CMD)
## Builds (cross-compiles) the program for all systems.
## Variables:
## - OUTDIR (output path to place built binaries)
## - MAINDIR (directory of the main package)
## - BUILDARGS (additional arguments to pass to "go build")
build-all: generate
@echo 'Building "$(PKG_NAME)" for all systems:'
@for GOOS in darwin linux windows; do \
for GOARCH in amd64 386; do \
printf "Building GOOS=$$GOOS GOARCH=$$GOARCH... " && \
OUTNAME="$(PKG_NAME)-$$GOOS-$$GOARCH"; \
if [ $$GOOS == windows ]; then \
OUTNAME="$$OUTNAME.exe"; \
fi; \
GOBUILD_OUT="$$(GOOS=$$GOOS GOARCH=$$GOARCH && \
go build \
-o "$$(echo $(OUTDIR) | tr -s '/')/$$OUTNAME" \
-ldflags "$(LDFLAGS)" \
$(BUILDARGS) $(MAINDIR) 2>&1)"; \
if [ -n "$$GOBUILD_OUT" ]; then \
printf "\nError during build:\n" >&2 && \
echo "$$GOBUILD_OUT" >&2 && \
exit 1; \
else printf "\tdone\n"; \
fi; \
done; \
done
## Builds (compiles) the program for this system, and runs it.
## Sources .env.sh before running, if it exists.
build-run:
@$(BUILD_CMD) && echo "" && $(RUN_CMD)
## Cleans build artifacts (executables, object files, etc.).
clean:
@echo 'Cleaning build artifacts with "go clean"...'
@go clean && echo "done"
## Installs the program using "go install".
install:
@echo 'Installing program using "go install"... '
@go install && echo "done"
## [Go: code checking]
.PHONY: fmt lint vet check
## Formats the source code using "gofmt".
FMT_CMD = \
if ! command -v gofmt > /dev/null; then \
echo '"gofmt" is required to format source code.'; \
else \
echo 'Formatting source code using "gofmt"...' && \
gofmt -l -s -w . && echo "done"; \
fi
fmt:
@$(FMT_CMD)
## Lints the source code using "golint".
LINT_CMD = \
if ! command -v golint > /dev/null; then \
echo '"golint" is required to lint soure code.' >&2; \
else \
echo 'Formatting source code using "golint"...' && \
golint ./... && echo "done"; \
fi
lint:
@$(LINT_CMD)
## Checks for suspicious code using "go vet".
VET_CMD = echo 'Checking for suspicious code using "go vet"...' && \
go vet && echo "done"
vet:
@$(VET_CMD)
## Checks for formatting, linting, and suspicious code.
CHECK_CMD = $(FMT_CMD) && echo "" && $(LINT_CMD) && echo "" && $(VET_CMD)
check:
@$(CHECK_CMD)
## [Go: testing]
.PHONY: test test-v test-race test-race-v bench bench-v
TEST_CMD = go test ./... -coverprofile=$(COVER_OUT) \
-covermode=atomic \
-timeout=$(TEST_TIMEOUT)
test:
@echo "Testing:"
@$(TEST_CMD)
test-v:
@echo "Testing (verbose):"
@$(TEST_CMD) -v
TEST_CMD_RACE = $(TEST_CMD) -race
test-race:
@echo "Testing (race):"
@$(TEST_CMD_RACE)
test-race-v:
@echo "Testing (race, verbose):"
@$(TEST_CMD_RACE) -v
BENCH_CMD = $(TEST_CMD) ./... -run=^$$ -bench=. -benchmem
bench:
@echo "Benchmarking:"
@$(BENCH_CMD)
bench-v:
@echo "Benchmarking (verbose):"
@$(BENCH_CMD) -v
## [Go: reviewing]
.PHONY: review review-race review-bench
__review_base:
@$(VERIFY_CMD) && echo "" && $(CHECK_CMD) && echo ""
## Formats, checks, and tests the code.
review: __review_base test
review-v: __review_base test-v
## Like "review", but tests for race conditions.
review-race: __review_base test-race
review-race-v: __review_base test-race-v
## Like "review-race", but includes benchmarks.
review-bench: review-race bench
review-bench-v: review-race bench-v
## [Goreleaser]
.PHONY: goreleaser-init release
goreleaser-init:
@if [ "$(GORELEASER)" == true ]; then \
echo "Initializing goreleaser..." && \
goreleaser init; \
fi
release:
@echo "Releasing with 'goreleaser'..." && goreleaser --rm-dist
snapshot:
@echo "Making snapshot with 'goreleaser'..." && \
goreleaser --snapshot --rm-dist