1EXAMPLES := $(shell ./get_main_pkgs.sh ./example)
2
3# All source code and documents. Used in spell check.
4ALL_DOCS := $(shell find . -name '*.md' -type f | sort)
5# All directories with go.mod files. Used in go mod tidy.
6ALL_GO_MOD_DIRS := $(shell find . -type f -name 'go.mod' -exec dirname {} \; | sort)
7ALL_COVERAGE_MOD_DIRS := $(shell find . -type f -name 'go.mod' -exec dirname {} \; | egrep -v '^./example' | sort)
8
9GOTEST_MIN = go test -v -timeout 30s
10GOTEST = $(GOTEST_MIN) -race
11GOTEST_WITH_COVERAGE = $(GOTEST) -coverprofile=coverage.txt -covermode=atomic
12
13.DEFAULT_GOAL := precommit
14
15.PHONY: precommit
16
17TOOLS_DIR := ./.tools
18
19$(TOOLS_DIR)/golangci-lint: go.mod go.sum tools.go
20	go build -o $(TOOLS_DIR)/golangci-lint github.com/golangci/golangci-lint/cmd/golangci-lint
21
22$(TOOLS_DIR)/misspell: go.mod go.sum tools.go
23	go build -o $(TOOLS_DIR)/misspell github.com/client9/misspell/cmd/misspell
24
25$(TOOLS_DIR)/stringer: go.mod go.sum tools.go
26	go build -o $(TOOLS_DIR)/stringer golang.org/x/tools/cmd/stringer
27
28precommit: lint generate build examples test
29
30.PHONY: test-with-coverage
31test-with-coverage:
32	set -e; for dir in $(ALL_COVERAGE_MOD_DIRS); do \
33	  echo "go test ./... + coverage in $${dir}"; \
34	  (cd "$${dir}" && \
35	    $(GOTEST_WITH_COVERAGE) ./... && \
36	    go tool cover -html=coverage.txt -o coverage.html); \
37	done
38
39.PHONY: ci
40ci: precommit check-clean-work-tree test-with-coverage test-386
41
42.PHONY: check-clean-work-tree
43check-clean-work-tree:
44	@if ! git diff --quiet; then \
45	  echo; \
46	  echo 'Working tree is not clean, did you forget to run "make precommit"?'; \
47	  echo; \
48	  git status; \
49	  exit 1; \
50	fi
51
52.PHONY: build
53build:
54	# TODO: Fix this on windows.
55	set -e; for dir in $(ALL_GO_MOD_DIRS); do \
56	  echo "compiling all packages in $${dir}"; \
57	  (cd "$${dir}" && \
58	    go build ./... && \
59	    go test -run xxxxxMatchNothingxxxxx ./... >/dev/null); \
60	done
61
62.PHONY: test
63test:
64	set -e; for dir in $(ALL_GO_MOD_DIRS); do \
65	  echo "go test ./... + race in $${dir}"; \
66	  (cd "$${dir}" && \
67	    $(GOTEST) ./...); \
68	done
69
70.PHONY: test-386
71test-386:
72	set -e; for dir in $(ALL_GO_MOD_DIRS); do \
73	  echo "go test ./... GOARCH 386 in $${dir}"; \
74	  (cd "$${dir}" && \
75	    GOARCH=386 $(GOTEST_MIN) ./...); \
76	done
77
78.PHONY: examples
79examples:
80	@set -e; for ex in $(EXAMPLES); do \
81	  echo "Building $${ex}"; \
82	  (cd "$${ex}" && \
83	   go build .); \
84	done
85
86.PHONY: lint
87lint: $(TOOLS_DIR)/golangci-lint $(TOOLS_DIR)/misspell $(TOOLS_DIR)/stringer
88	set -e; for dir in $(ALL_GO_MOD_DIRS); do \
89	  echo "golangci-lint in $${dir}"; \
90	  (cd "$${dir}" && \
91	    $(abspath $(TOOLS_DIR))/golangci-lint run --fix && \
92	    $(abspath $(TOOLS_DIR))/golangci-lint run); \
93	done
94	$(TOOLS_DIR)/misspell -w $(ALL_DOCS)
95	set -e; for dir in $(ALL_GO_MOD_DIRS); do \
96	  echo "go mod tidy in $${dir}"; \
97	  (cd "$${dir}" && \
98	    go mod tidy); \
99	done
100
101generate:
102	PATH="$(abspath $(TOOLS_DIR)):$${PATH}" go generate ./...
103