-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMakefile
More file actions
252 lines (187 loc) · 7.93 KB
/
Copy pathMakefile
File metadata and controls
252 lines (187 loc) · 7.93 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
248
249
250
251
252
TMP_DIR ?= ./tmp
BIN_DIR ?= ./bin
GOEXE := $(shell go env GOEXE)
BUILD_FLAGS ?=
DOCKER_COMPOSE ?= docker compose
APP_SERVICE := server
DB_SERVICE := db
MIGRATE_SERVICE := migrate
WAIT_DB_READY := sh scripts/wait-db-ready.sh
MIGRATE := sh scripts/migrate.sh
MERGE_CODE := sh scripts/merge-code.sh
SWAG_SOURCE_DIRS := ./cmd/$(APP_SERVICE) ./internal/model ./internal/api
SWAG_SOURCES := $(filter-out %_test.go,$(wildcard $(addsuffix /*.go,$(SWAG_SOURCE_DIRS))))
SWAG_DEST_DIR := ./pkg/api/docs
# source and dest for merge, patch, etc...
SRC ?= .
DST ?= 1
EMPTY :=
SPACE := $(EMPTY) $(EMPTY)
COMMA := ,
# Escape-последовательности терминала
CHECK_COLOR := $(shell [ -n "$(MAKE_TERMOUT)" ] && echo "$(TERM)" | grep -EE "color|256|xterm" >/dev/null && echo "yes")
# use color output (yes|no)
COLOR ?= $(CHECK_COLOR)
E_RSET := $(if $(COLOR),\033[0m)
E_BOLD := $(if $(COLOR),\033[1m)
E_CMD :=
E_RED := \033[31m
E_GREEN := \033[32m
E_YELLOW := \033[33m
E_BLUE := \033[34m
# Dark Modern Theme (TrueColor)
E_KEY := $(if $(COLOR),\033[38;2;86;156;214m)
E_VAR := $(if $(COLOR),\033[38;2;156;220;254m)
E_FUN := $(if $(COLOR),\033[38;2;230;230;170m)
E_COM := $(if $(COLOR),\033[38;2;106;153;85m)
.PHONY: all
all: help
# ============================================
# RUN
# ============================================
.PHONY: run docker-run
run: generate test build db-up migrate-up ## run server (local)
$(BIN_DIR)/server
docker-run: docker-build docker-up ## run server in docker
$(DOCKER_COMPOSE) logs -f $(APP_SERVICE) $(MIGRATE_SERVICE)
# ============================================
# DOCKER COMMANDS
# ============================================
.PHONY: docker-build docker-up docker-down docker-down-volumes docker-logs
.PHONY: docker-db-up docker-db-down docker-db-down-volumes docker-db-shell
docker-build: ## build docker images
$(DOCKER_COMPOSE) build
docker-up: ## start all services in docker
$(DOCKER_COMPOSE) up -d $(APP_SERVICE)
@echo "Waiting for services to be ready..."
@sleep 1
$(DOCKER_COMPOSE) ps
docker-down: ## stop all docker services
$(DOCKER_COMPOSE) down
docker-down-volumes: ## stop docker and remove volumes
$(DOCKER_COMPOSE) down -v
docker-logs: ## show docker logs
$(DOCKER_COMPOSE) logs -f
docker-db-up:
$(DOCKER_COMPOSE) up -d $(DB_SERVICE)
docker-db-down: ## stop database container
$(DOCKER_COMPOSE) down $(DB_SERVICE)
docker-db-down-volumes: ## stop database and remove volumes
$(DOCKER_COMPOSE) down -v $(DB_SERVICE)
docker-db-shell: ## open psql in db container
$(DOCKER_COMPOSE) exec $(DB_SERVICE) psql -U $${DB_USER:-postgres} -d $${DB_NAME:-postgres}
# ============================================
# DEVELOPMENT COMMANDS (local)
# ============================================
.PHONY: deps check-goose check-swag check-stringer check-enumer check-tools build swag-generate go-generate generate test clean merge
deps: ## update deps
go mod tidy
check-goose: ## install goose if need
@which goose 2>/dev/null || go install github.com/pressly/goose/v3/cmd/goose@v3.27.1
check-swag: ## install swag if need
@which swag 2>/dev/null || go install github.com/swaggo/swag/cmd/swag@v1.16.4
check-enumer: ## install enumer if need
@which enumer 2>/dev/null || go install github.com/dmarkham/enumer@v1.6.3
check-tools: check-goose check-swag check-stringer check-enumer
# Находим все поддиректории в cmd, которые потенциально могут быть бинарниками
CMDS := $(wildcard cmd/*)
# Генерируем список целей для бинарников
BINARIES := $(patsubst cmd/%,$(BIN_DIR)/%,$(CMDS))
# Шаблонное правило для сборки любого бинарника
$(BIN_DIR)/%: FORCE
@mkdir -p $(@D)
go build $(BUILD_FLAGS) -o $@$(GOEXE) ./cmd/$(notdir $@)
build: $(BINARIES) ## build all binaries
swag-generate: .swag-generate.done ## generate Swagger docs
.swag-generate.done: $(SWAG_SOURCES)
swag fmt -d $(subst $(SPACE),$(COMMA),$(SWAG_SOURCE_DIRS))
swag init -d $(subst $(SPACE),$(COMMA),$(SWAG_SOURCE_DIRS)) -o $(SWAG_DEST_DIR)
@touch $@
go-generate:
go generate ./...
generate: go-generate swag-generate ## generate all
test: ## run tests
go test ./internal/...
test-integration: ## run integration tests on real database
go test ./tests/...
clean: ## remove temporary and binary files
-rm -rf $(BIN_DIR) $(TMP_DIR) .*-generate.done
# ============================================
# DATABASE (local)
# ============================================
.PHONY: db-up db-down db-down-volumes db-shell
db-up: ## start database container for local dev
@if [ -z "$$($(DOCKER_COMPOSE) ps -q $(DB_SERVICE))" ]; then \
$(DOCKER_COMPOSE) up -d $(DB_SERVICE) && \
DOCKER_COMPOSE='$(DOCKER_COMPOSE)' $(WAIT_DB_READY); \
else \
echo "Database already running"; \
fi
db-down: docker-db-down ## alias for docker-db-down
db-down-volumes: docker-db-down-volumes ## alias for docker-db-down-volumes
db-shell: docker-db-shell ## alias for docker-db-shell
# ============================================
# MIGRATIONS (local)
# ============================================
.PHONY: migrate-up migrate-down migrate-status
migrate-up: ## apply all migrations (local)
$(MIGRATE) up
migrate-down: ## rollback last migration (local)
$(MIGRATE) down 1
migrate-status: ## show migration status (local)
$(MIGRATE) status
# ============================================
# UTILS
# ============================================
.PHONY: FORCE help
FORCE:
merge: ## merge code to file for AI review
@mkdir -p $(TMP_DIR)
$(MERGE_CODE) $(SRC) > $(TMP_DIR)/$(DST).code
patch: deps generate test ## make precommit patch
@mkdir -p $(TMP_DIR)
@(set -e; \
staged_list="$(TMP_DIR)/staged_list.$$$$"; \
unstaged_list="$(TMP_DIR)/unstaged_list.$$$$"; \
git diff --staged --name-only -- $(SRC) > "$$staged_list"; \
git diff --name-only -- $(SRC) > "$$unstaged_list"; \
intersection=$$(grep -Fxf "$$staged_list" "$$unstaged_list" || true); \
rm -f "$$staged_list" "$$unstaged_list"; \
if [ -n "$$intersection" ]; then \
printf "\n" >&2; \
printf "$(E_BOLD)WARNING:$(E_RSET) the following files have changes not staged for commit:\n" >&2; \
printf " (use \"git add <file>...\" to update what will be committed)\n" >&2; \
printf "$(E_RED)%s$(E_RSET)\n" $$intersection | sed 's/^/ /' >&2; \
printf "\n" >&2; \
fi)
git diff --staged -- $(SRC) > $(TMP_DIR)/$(DST).patch
@printf "Patch saved to $(TMP_DIR)/$(DST).patch\n"
help: ## show this help
@printf "$(E_BOLD)Usage:$(E_RSET)\n"
@printf " $(E_CMD)make$(E_RSET) [$(E_VAR)VARIABLE$(E_RSET)=value ...] [$(E_FUN)target$(E_RSET) ...]\n"
@printf "\n$(E_BOLD)Variables:$(E_RSET)\n"
@awk 'BEGIN {comment=""} \
/^[a-zA-Z0-9_-]+[[:space:]]*\?=/ { \
split($$0, a, /\?=/); \
gsub(/^[ \t]+|[ \t]+$$/, "", a[1]); \
gsub(/^[ \t]+|[ \t]+$$/, "", a[2]); \
if ( prev ~ /^#/ ) { \
gsub(/^[ \t]+|[ \t]+$$/, "", prev); \
printf " $(E_VAR)%-14s$(E_RSET) = %-14s $(E_COM)%s$(E_RSET)\n", a[1], a[2], prev; \
} else { \
printf " $(E_VAR)%-14s$(E_RSET) = %-14s\n", a[1], a[2]; \
} \
} \
{ prev=$$0 }' \
$(MAKEFILE_LIST)
@printf "\n$(E_BOLD)Targets:$(E_RSET)\n"
@awk 'BEGIN {FS = ":.*?## "} \
/^[a-zA-Z0-9_-]+:.*?## / \
{printf " $(E_FUN)%-22s$(E_RSET) - %s\n", $$1, $$2}' \
$(MAKEFILE_LIST)
@printf "\n$(E_BOLD)Examples:$(E_RSET)\n"
@printf " $(E_CMD)make$(E_RSET) $(E_FUN)test$(E_RSET) $(E_COM)# run tests$(E_RSET)\n"
@printf " $(E_CMD)make$(E_RSET) $(E_FUN)test-integration$(E_RSET) $(E_COM)# test service on real database$(E_RSET)\n"
@printf " $(E_CMD)make$(E_RSET) $(E_FUN)run$(E_RSET) $(E_COM)# run server locally$(E_RSET)\n"
@printf " $(E_CMD)make$(E_RSET) $(E_FUN)docker-run$(E_RSET) $(E_COM)# run server in docker$(E_RSET)\n"
@printf " $(E_CMD)make$(E_RSET) $(E_FUN)docker-build docker-run$(E_RSET) $(E_COM)# rebuild docker images and restart$(E_RSET)\n"