-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMakefile
More file actions
374 lines (347 loc) · 11 KB
/
Makefile
File metadata and controls
374 lines (347 loc) · 11 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
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
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
.PHONY: help quick-start up down restart logs build test test-coverage lint lint-fix swag migrate-create migrate-up migrate-down migrate-status migrate-goto migrate-force migrate-drop build-binary run-binary clean dev
# Container name (from docker-compose.yml)
CONTAINER_NAME := go_api_app
# Check if container is running
CONTAINER_RUNNING := $(shell docker ps --format '{{.Names}}' 2>/dev/null | grep -E '^$(CONTAINER_NAME)$$')
# Determine execution command
ifdef CONTAINER_RUNNING
EXEC_CMD = docker exec $(CONTAINER_NAME)
EXEC_CMD_INTERACTIVE = docker exec -i $(CONTAINER_NAME)
ENV_MSG = 🐳 Running in Docker container
else
EXEC_CMD =
EXEC_CMD_INTERACTIVE =
ENV_MSG = 💻 Running on host (Docker not available)
endif
## help: Show this help message
help:
@echo "Go REST API Boilerplate - Available Commands"
@echo "=============================================="
@echo ""
@echo "🚀 Quick Start:"
@echo " make quick-start - Complete setup and start (Docker required)"
@echo ""
@echo "🐳 Docker Commands:"
@echo " make up - Start containers"
@echo " make down - Stop containers"
@echo " make restart - Restart containers"
@echo " make logs - View container logs"
@echo " make build - Rebuild containers"
@echo ""
@echo "🧪 Development Commands:"
@echo " make test - Run tests"
@echo " make test-coverage - Run tests with coverage"
@echo " make lint - Run linter"
@echo " make lint-fix - Run linter and fix issues"
@echo " make swag - Generate Swagger docs"
@echo ""
@echo "📊️ Database Commands:"
@echo " make migrate-create NAME=<name> - Create new migration"
@echo " make migrate-up - Apply all pending migrations"
@echo " make migrate-down - Rollback last migration (or STEPS=N for N migrations)"
@echo " make migrate-status - Show current migration version"
@echo " make migrate-goto VERSION=<n> - Go to specific version"
@echo " make migrate-force VERSION=<n> - Force set version (recovery)"
@echo " make migrate-drop - Drop all tables"
@echo ""
@echo "⚙️ Native Build (requires Go on host):"
@echo " make dev - Run with hot-reload (air) loading .env"
@echo " make build-binary - Build Go binary directly (no Docker)"
@echo " make run-binary - Build and run binary directly (no Docker)"
@echo ""
@echo "🧹 Utility:"
@echo " make clean - Clean build artifacts"
@echo ""
@echo "💡 Most commands auto-detect Docker/host environment"
@echo "💡 Native build commands require Go installed on your machine"
## quick-start: Complete setup and start the project
quick-start:
@chmod +x scripts/quick-start.sh
@./scripts/quick-start.sh
## up: Start Docker containers
up:
@echo "🐳 Starting Docker containers..."
@docker compose up -d --build --wait
@echo "✅ Containers started and healthy"
@echo "📍 API: http://localhost:8080"
## down: Stop Docker containers
down:
@echo "🛑 Stopping Docker containers..."
@docker compose down
@echo "✅ Containers stopped"
## restart: Restart Docker containers
restart:
@echo "🔄 Restarting Docker containers..."
@docker compose restart
@echo "✅ Containers restarted"
## logs: View container logs
logs:
@docker compose logs -f app
## build: Rebuild Docker containers
build:
@echo "🔨 Building Docker containers..."
@docker compose build
@echo "✅ Build complete"
## test: Run tests
test:
ifdef CONTAINER_RUNNING
@echo "$(ENV_MSG)"
@$(EXEC_CMD) go test ./... -v
else
@if command -v go >/dev/null 2>&1; then \
echo "$(ENV_MSG)"; \
go test ./... -v; \
else \
echo "❌ Error: Docker container not running and Go not installed"; \
echo "Please run: make up"; \
exit 1; \
fi
endif
## test-coverage: Run tests with coverage
test-coverage:
ifdef CONTAINER_RUNNING
@echo "$(ENV_MSG)"
@$(EXEC_CMD) go test ./... -v -coverprofile=coverage.out
@$(EXEC_CMD) go tool cover -html=coverage.out -o coverage.html
@echo "✅ Coverage report: coverage.html"
else
@if command -v go >/dev/null 2>&1; then \
echo "$(ENV_MSG)"; \
go test ./... -v -coverprofile=coverage.out; \
go tool cover -html=coverage.out -o coverage.html; \
echo "✅ Coverage report: coverage.html"; \
else \
echo "❌ Error: Docker container not running and Go not installed"; \
echo "Please run: make up"; \
exit 1; \
fi
endif
## lint: Run linter
lint:
ifdef CONTAINER_RUNNING
@echo "$(ENV_MSG)"
@echo "🔍 Running golangci-lint..."
@$(EXEC_CMD) golangci-lint run --timeout=5m && echo "✅ No linting issues found!" || exit 1
else
@if command -v golangci-lint >/dev/null 2>&1; then \
echo "$(ENV_MSG)"; \
echo "🔍 Running golangci-lint..."; \
golangci-lint run --timeout=5m && echo "✅ No linting issues found!" || exit 1; \
else \
echo "❌ Error: Docker container not running and golangci-lint not installed"; \
echo "Please run: make up"; \
echo "Or install: go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest"; \
exit 1; \
fi
endif
## lint-fix: Run linter and fix issues
lint-fix:
ifdef CONTAINER_RUNNING
@echo "$(ENV_MSG)"
@echo "🔧 Running golangci-lint with auto-fix..."
@$(EXEC_CMD) golangci-lint run --fix --timeout=5m && echo "✅ Linting complete! Issues auto-fixed where possible." || exit 1
else
@if command -v golangci-lint >/dev/null 2>&1; then \
echo "$(ENV_MSG)"; \
echo "🔧 Running golangci-lint with auto-fix..."; \
golangci-lint run --fix --timeout=5m && echo "✅ Linting complete! Issues auto-fixed where possible." || exit 1; \
else \
echo "❌ Error: Docker container not running and golangci-lint not installed"; \
echo "Please run: make up"; \
exit 1; \
fi
endif
## swag: Generate Swagger documentation
swag:
ifdef CONTAINER_RUNNING
@echo "$(ENV_MSG)"
@$(EXEC_CMD) swag init -g ./cmd/server/main.go -o ./api/docs
@echo "✅ Swagger docs generated"
else
@if command -v swag >/dev/null 2>&1; then \
echo "$(ENV_MSG)"; \
swag init -g ./cmd/server/main.go -o ./api/docs; \
echo "✅ Swagger docs generated"; \
else \
echo "❌ Error: Docker container not running and swag not installed"; \
echo "Please run: make up"; \
echo "Or install: go install github.com/swaggo/swag/cmd/swag@latest"; \
exit 1; \
fi
endif
## migrate-create: Create a new migration
migrate-create:
ifndef NAME
@echo "❌ Error: NAME is required"
@echo "Usage: make migrate-create NAME=add_user_avatar"
@exit 1
endif
ifdef CONTAINER_RUNNING
@echo "$(ENV_MSG)"
@$(EXEC_CMD) go run cmd/migrate/main.go create $(NAME)
else
@if command -v go >/dev/null 2>&1; then \
echo "$(ENV_MSG)"; \
go run cmd/migrate/main.go create $(NAME); \
else \
echo "❌ Error: Docker container not running and Go not installed"; \
echo "Please run: make up"; \
exit 1; \
fi
endif
## migrate-up: Apply all pending migrations
migrate-up:
ifdef CONTAINER_RUNNING
@echo "$(ENV_MSG)"
@$(EXEC_CMD) go run cmd/migrate/main.go up
else
@if command -v go >/dev/null 2>&1; then \
echo "$(ENV_MSG)"; \
go run cmd/migrate/main.go up; \
else \
echo "❌ Error: Docker container not running and Go not installed"; \
echo "Please run: make up"; \
exit 1; \
fi
endif
## migrate-down: Rollback last migration (or N migrations with STEPS=N)
migrate-down:
ifdef CONTAINER_RUNNING
@echo "$(ENV_MSG)"
ifdef STEPS
@$(EXEC_CMD_INTERACTIVE) go run cmd/migrate/main.go down $(STEPS)
else
@$(EXEC_CMD_INTERACTIVE) go run cmd/migrate/main.go down
endif
else
@if command -v go >/dev/null 2>&1; then \
echo "$(ENV_MSG)"; \
ifdef STEPS
go run cmd/migrate/main.go down $(STEPS); \
else
go run cmd/migrate/main.go down; \
endif
else \
echo "❌ Error: Docker container not running and Go not installed"; \
echo "Please run: make up"; \
exit 1; \
fi
endif
## migrate-status: Show current migration version
migrate-status:
ifdef CONTAINER_RUNNING
@echo "$(ENV_MSG)"
@$(EXEC_CMD) go run cmd/migrate/main.go version
else
@if command -v go >/dev/null 2>&1; then \
echo "$(ENV_MSG)"; \
go run cmd/migrate/main.go version; \
else \
echo "❌ Error: Docker container not running and Go not installed"; \
echo "Please run: make up"; \
exit 1; \
fi
endif
## migrate-goto: Go to specific version
migrate-goto:
ifndef VERSION
@echo "❌ Error: VERSION is required"
@echo "Usage: make migrate-goto VERSION=5"
@exit 1
endif
ifdef CONTAINER_RUNNING
@echo "$(ENV_MSG)"
@$(EXEC_CMD) go run cmd/migrate/main.go goto $(VERSION)
else
@if command -v go >/dev/null 2>&1; then \
echo "$(ENV_MSG)"; \
go run cmd/migrate/main.go goto $(VERSION); \
else \
echo "❌ Error: Docker container not running and Go not installed"; \
echo "Please run: make up"; \
exit 1; \
fi
endif
## migrate-force: Force set version (recovery)
migrate-force:
ifndef VERSION
@echo "❌ Error: VERSION is required"
@echo "Usage: make migrate-force VERSION=1"
@exit 1
endif
ifdef CONTAINER_RUNNING
@echo "$(ENV_MSG)"
@$(EXEC_CMD_INTERACTIVE) go run cmd/migrate/main.go force $(VERSION)
else
@if command -v go >/dev/null 2>&1; then \
echo "$(ENV_MSG)"; \
go run cmd/migrate/main.go force $(VERSION); \
else \
echo "❌ Error: Docker container not running and Go not installed"; \
echo "Please run: make up"; \
exit 1; \
fi
endif
## migrate-drop: Drop all tables
migrate-drop:
ifdef CONTAINER_RUNNING
@echo "$(ENV_MSG)"
@$(EXEC_CMD_INTERACTIVE) go run cmd/migrate/main.go drop --force
else
@if command -v go >/dev/null 2>&1; then \
echo "$(ENV_MSG)"; \
go run cmd/migrate/main.go drop --force; \
else \
echo "❌ Error: Docker container not running and Go not installed"; \
echo "Please run: make up"; \
exit 1; \
fi
endif
## dev: Run server locally with hot-reload (air) loading .env
dev:
@if [ ! -f .env ]; then \
echo "❌ .env file not found. Copy .env.example to .env first."; \
exit 1; \
fi
@if ! command -v air >/dev/null 2>&1; then \
echo "❌ air not installed. Run: go install github.com/air-verse/air@latest"; \
exit 1; \
fi
@set -a && . ./.env && set +a && air
## build-binary: Build Go binary directly on host (requires Go)
build-binary:
@if ! command -v go >/dev/null 2>&1; then \
echo "❌ Error: Go is not installed on your machine"; \
echo ""; \
echo "Please install Go first:"; \
echo " https://golang.org/doc/install"; \
echo ""; \
echo "Or use Docker instead:"; \
echo " make up"; \
exit 1; \
fi
@echo "🔨 Building Go binary..."
@mkdir -p bin
@go build -o bin/server ./cmd/server
@echo "✅ Binary built successfully: bin/server"
@echo ""
@echo "To run the binary:"
@echo " make run-binary"
@echo " OR"
@echo " ./bin/server"
## run-binary: Build and run Go binary directly on host (requires Go)
run-binary: build-binary
@echo ""
@echo "🚀 Starting server..."
@echo ""
@echo "⚠️ Note: Ensure PostgreSQL is running on localhost:5432"
@echo "⚠️ Note: Set environment variables or use .env file"
@echo ""
@./bin/server
## clean: Clean build artifacts
clean:
@echo "🧹 Cleaning build artifacts..."
@rm -f coverage.out coverage.html
@rm -f bin/*
@docker compose down -v 2>/dev/null || true
@echo "✅ Clean complete"