-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathMakefile
More file actions
247 lines (210 loc) · 8.34 KB
/
Makefile
File metadata and controls
247 lines (210 loc) · 8.34 KB
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
# SPDX-FileCopyrightText: 2025 Forkbomb BV
#
# SPDX-License-Identifier: AGPL-3.0-or-later
PROJECT_NAME ?= credimi
ORGANIZATION ?= forkbombeu
ROOT_DIR ?= $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
COMPOSE_PROJECT_NAME ?= $(shell basename "$(ROOT_DIR)" | tr '[:upper:]' '[:lower:]' | sed -E 's/[^a-z0-9]+/-/g; s/^-+//; s/-+$$//')
COMPOSE_DEV_OVERRIDE_FILE ?= /tmp/$(COMPOSE_PROJECT_NAME)-docker-compose.dev.yaml
BINARY_NAME ?= $(PROJECT_NAME)
CLI_NAME ?= $(PROJECT_NAME)-cli
SUBDIRS ?= ./...
MAIN_SRC ?= $(ROOT_DIR)/main.go
CLI_SRC ?= $(ROOT_DIR)/cli/main.go
DATA ?= $(ROOT_DIR)/pb_data
WEBAPP ?= $(ROOT_DIR)/webapp
GO_SRC := $(wildcard **/*.go)
GODIRS := ./pkg/... ./cmd/...
UI_SRC := $(shell find $(WEBAPP)/src -type f \( -name '*.svelte' -o -name '*.js' -o -name '*.ts' -o -name '*.css' \) ! -name '*.generated.ts' ! -path 'webapp/src/modules/i18n/paraglide/*')
DOCS ?= $(ROOT_DIR)/docs
GOCMD ?= go
GOBUILD ?= $(GOCMD) build
GOCLEAN ?= $(GOCMD) clean
GOTEST ?= $(GOCMD) test
GOTOOL ?= $(GOCMD) tool
GOGET ?= $(GOCMD) get
GOFMT ?= $(GOCMD) fmt
GOMOD ?= $(GOCMD) mod
GOINST ?= $(GOCMD) install
GOGEN ?= $(GOCMD) generate
GOPATH ?= $(shell $(GOCMD) env GOPATH)
GOBIN ?= $(GOPATH)/bin
GOMOD_FILES := go.mod go.sum
COVOUT := coverage.out
COVERAGE_FILE ?= $(COVOUT)
COVERAGE_MIN ?= 80
COVERAGE_PKGS ?= ./...
# Submodules
WEBENV = $(WEBAPP)/.env
BIN = $(ROOT_DIR)/.bin
DEPS = mise git temporal wget
DEV_DEPS = pre-commit
TEST_DEPS = mise
# Generic tool checker
define require_tools
@missing=0; \
for t in $(1); do \
if ! command -v $$t >/dev/null 2>&1; then \
echo "🧧 \`$$t\` not found in PATH, please install it." >&2; \
missing=1; \
fi; \
done; \
if [ $$missing -ne 0 ]; then \
echo "🥶 Missing required tools, aborting."; \
exit 1; \
fi
endef
define write_compose_dev_override
@printf '%s\n' \
'services:' \
' elasticsearch:' \
' container_name: $(COMPOSE_PROJECT_NAME)-temporal-elasticsearch' \
' postgresql:' \
' container_name: $(COMPOSE_PROJECT_NAME)-temporal-postgresql' \
' temporal_ui:' \
' container_name: $(COMPOSE_PROJECT_NAME)-temporal-ui' \
> $(COMPOSE_DEV_OVERRIDE_FILE)
endef
all: help
.PHONY: submodules version dev test lint tidy purge build docker doc clean tools help w devtools coverage-check
$(BIN):
@mkdir -p $@
submodules:
git submodule update --recursive --init
## Hacking
GREEN := $(shell tput -Txterm setaf 2)
YELLOW := $(shell tput -Txterm setaf 3)
WHITE := $(shell tput -Txterm setaf 7)
CYAN := $(shell tput -Txterm setaf 6)
RESET := $(shell tput -Txterm sgr0)
VERSION_STRATEGY = semver # git, semver, date
VERSION := $(shell cat VERSION 2>/dev/null || echo "0.1.0")
GIT_COMMIT ?= $(shell git rev-parse --short HEAD 2>/dev/null || echo "unknown")
GIT_BRANCH ?= $(shell git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown")
BUILD_TIME ?= $(shell date -u '+%Y-%m-%d_%H:%M:%S')
BUILD_BY ?= $(shell whoami)
version: ## ℹ️ Display version information
@echo "$(CYAN)Version: $(RESET)$(VERSION)"
@echo "$(CYAN)Commit: $(RESET)$(GIT_COMMIT)"
@echo "$(CYAN)Branch: $(RESET)$(GIT_BRANCH)"
@echo "$(CYAN)Built: $(RESET)$(BUILD_TIME)"
@echo "$(CYAN)Built by: $(RESET)$(BUILD_BY)"
@echo "$(CYAN)Go version: $(RESET)$(shell $(GOCMD) version)"
$(WEBENV):
cp $(WEBAPP)/.env.example $(WEBAPP)/.env
$(DATA):
mkdir -p $(DATA)
dev: $(WEBENV) tools devtools submodules $(BIN) $(DATA) ## 🚀 run in watch mode
$(call require_tools,$(DEPS) $(DEV_DEPS))
$(call write_compose_dev_override)
COMPOSE_PROJECT_NAME=$(COMPOSE_PROJECT_NAME) COMPOSE_DEV_OVERRIDE_FILE=$(COMPOSE_DEV_OVERRIDE_FILE) bash -c 'trap "docker compose -f docker-compose.yaml $${COMPOSE_DEV_OVERRIDE_FILE:+-f $${COMPOSE_DEV_OVERRIDE_FILE}} stop elasticsearch postgresql temporal temporal_ui" EXIT; DEBUG=1 $(GOTOOL) hivemind -T Procfile.dev'
test: ## 🧪 run tests
$(call require_tools,$(TEST_DEPS))
bash ./scripts/test-summary.sh
ifeq (test.p, $(firstword $(MAKECMDGOALS)))
test_name := $(wordlist 2, $(words $(MAKECMDGOALS)), $(MAKECMDGOALS))
$(eval $(test_name):;@true)
endif
test.p: tools ## 🍷 watch tests and run on change for a certain folder
$(GOTOOL) gow test -run "^$(test_name)$$" $(GODIRS)
coverage: devtools # ☂️ run test and open code coverage report
$(GOTEST) -tags=unit -covermode=atomic -coverprofile=$(COVOUT) ./...
$(GOTOOL) cover -html=$(COVOUT) -o coverage.html
$(GOTOOL) go-cover-treemap -coverprofile $(COVOUT) > coverage.svg && open coverage.svg
coverage-check: ## ☂️ run tests and fail if total coverage is below COVERAGE_MIN
$(GOTEST) -tags=unit -covermode=atomic -coverprofile=$(COVERAGE_FILE) $(COVERAGE_PKGS)
@awk -v min="$(COVERAGE_MIN)" -v file="$(COVERAGE_FILE)" '\
BEGIN { covered = 0; total = 0 } \
NR == 1 && $$1 == "mode:" { next } \
NF >= 3 { \
n = $$2 + 0; \
c = $$3 + 0; \
total += n; \
if (c > 0) covered += n; \
} \
END { \
if (total == 0) { \
printf("Failed to compute coverage from %s: no statement data found\n", file) > "/dev/stderr"; \
exit 1; \
} \
cov = (covered * 100) / total; \
printf("Total coverage: %.1f%% (required: %s%%)\n", cov, min); \
if ((cov + 0) < (min + 0)) exit 1; \
} \
' $(COVERAGE_FILE)
lint: devtools ## 📑 lint rules checks
$(call require_tools,$(TEST_DEPS))
$(GOMOD) tidy -diff
$(GOMOD) verify
$(GOCMD) vet $(SUBDIRS)
$(GOTOOL) govulncheck $(SUBDIRS)
$(GOTOOL) golangci-lint run $(SUBDIRS)
fmt: devtools ## 🗿 format rules checks
$(GOFMT) $(GODIRS)
tidy: $(GOMOD_FILES)
@$(GOMOD) tidy
purge: ## ⛔ Purge the database
@echo "⛔ Purge the database"
$(call write_compose_dev_override)
@COMPOSE_PROJECT_NAME=$(COMPOSE_PROJECT_NAME) COMPOSE_DEV_OVERRIDE_FILE=$(COMPOSE_DEV_OVERRIDE_FILE) POSTGRESQL_VERSION=16 ELASTICSEARCH_VERSION=7.17.27 TEMPORAL_VERSION=1.29.1 TEMPORAL_UI_VERSION=2.43.2 docker compose -f docker-compose.yaml -f $(COMPOSE_DEV_OVERRIDE_FILE) down -v --remove-orphans
@rm -rf $(DATA)
@mkdir $(DATA)
## Deployment
$(BINARY_NAME): $(GO_SRC) tools tidy submodules $(WEBENV)
@$(GOBUILD) -o $(BINARY_NAME) $(MAIN_SRC)
$(WEBAPP)/build: $(UI_SRC)
@./$(BINARY_NAME) serve & \
PID=$$!; \
./scripts/wait-for-it.sh localhost:8090 --timeout=60; \
cd $(WEBAPP) && bun i && bun run build; \
kill $$PID;
$(BINARY_NAME)-ui: $(UI_SRC)
@./$(BINARY_NAME) serve & \
PID=$$!; \
./scripts/wait-for-it.sh localhost:8090 --timeout=60; \
cd $(WEBAPP) && bun i && bun run bin; \
kill $$PID;
docker: $(DATA) submodules ## 🐳 run docker with all the infrastructure services
COMPOSE_PROJECT_NAME=$(COMPOSE_PROJECT_NAME) docker compose build --build-arg PUBLIC_POCKETBASE_URL="http://localhost:8090"
COMPOSE_PROJECT_NAME=$(COMPOSE_PROJECT_NAME) docker compose up
## Misc
doc: ## 📚 Serve documentation on localhost with --host
cd $(DOCS) && bun i
cd $(DOCS) && bun run docs:dev --open --host
clean: ## 🧹 Clean files and caches
@$(GOCLEAN)
@rm -f $(BINARY_NAME)
@rm -f $(BINARY_NAME)-ui
@rm -fr $(WEBAPP)/build
@rm -fr $(WEBAPP)/node_modules
@rm -fr $(WEBAPP)/.svelte-kit
@rm -f $(DOCS)/.vitepress/config.ts.timestamp*
@rm -f $(COVOUT) coverage.html coverage.svg
@echo "🧹 cleaned"
generate: $(ROOT_DIR)/pkg/gen.go
$(GOGEN) $(ROOT_DIR)/pkg/gen.go
devtools: generate
pre-commit install
pre-commit autoupdate
tools: generate $(BIN) $(BIN)/stepci-captured-runner $(BIN)/et-tu-cesr
mise install
$(BIN)/stepci-captured-runner:
wget https://github.com/ForkbombEu/stepci-captured-runner/releases/latest/download/stepci-captured-runner-$(shell uname)-$(shell uname -m) -O $(BIN)/stepci-captured-runner && chmod +x $(BIN)/stepci-captured-runner
$(BIN)/et-tu-cesr:
wget https://github.com/ForkbombEu/et-tu-cesr/releases/latest/download/et-tu-cesr-$(shell go env GOOS)-$(shell go env GOARCH) -O $(BIN)/et-tu-cesr && chmod +x $(BIN)/et-tu-cesr
## Help:
help: ## Show this help.
@echo ''
@echo 'Usage:'
@echo ' ${YELLOW}make${RESET} ${GREEN}<target>${RESET}'
@echo ''
@echo 'Targets:'
@awk 'BEGIN {FS = ":.*?## "} { \
if (/^[a-zA-Z_-]+:.*?##.*$$/) {printf " ${YELLOW}%-20s${GREEN}%s${RESET}\n", $$1, $$2} \
else if (/^## .*$$/) {printf " ${CYAN}%s${RESET}\n", substr($$1,4)} \
}' $(MAKEFILE_LIST)
kill-pocketbase: ## 🔪 Kill any running PocketBase instance
@echo "Killing any existing PocketBase instance..."
@-lsof -ti:8090 -sTCP:LISTEN | xargs kill -9 2>/dev/null || true
seed: ## 🌱 Seed the database
@$(GOCMD) run main.go migrate up && $(GOCMD) run cmd/seeds/seed.go