-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathMakefile
More file actions
305 lines (248 loc) · 9.87 KB
/
Copy pathMakefile
File metadata and controls
305 lines (248 loc) · 9.87 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
# =============================================================================
# LocalGo Makefile
# =============================================================================
# ---------------------------------------------------------------------------
# Variables
# ---------------------------------------------------------------------------
BINARY_NAME := localgo
BUILD_DIR := ./cmd/localgo
COVER_DIR := .coverage
GO := go
GOFLAGS ?=
VERSION := $(shell git describe --tags --always --dirty 2>/dev/null || echo "dev")
GIT_COMMIT := $(shell git rev-parse --short HEAD 2>/dev/null || echo "unknown")
BUILD_DATE := $(shell date -u '+%Y-%m-%dT%H:%M:%SZ')
LD_BASE := -X main.Version=$(VERSION) -X main.GitCommit=$(GIT_COMMIT) -X main.BuildDate=$(BUILD_DATE)
LDFLAGS := -ldflags "-s -w $(LD_BASE)"
LDFLAGS_DEBUG := -ldflags "$(LD_BASE)"
TRIMFLAGS := -trimpath
# Colour helpers — silently degrade when not a tty
ifeq ($(TERM),)
_BOLD :=
_RESET :=
_GREEN :=
_CYAN :=
_YELLOW :=
else
_BOLD := $(shell tput bold 2>/dev/null)
_RESET := $(shell tput sgr0 2>/dev/null)
_GREEN := $(shell tput setaf 2 2>/dev/null)
_CYAN := $(shell tput setaf 6 2>/dev/null)
_YELLOW := $(shell tput setaf 3 2>/dev/null)
endif
define log
@printf '%s==> %s%s\n' '$(_BOLD)$(_CYAN)' '$(1)' '$(_RESET)'
endef
# ---------------------------------------------------------------------------
# Default
# ---------------------------------------------------------------------------
.DEFAULT_GOAL := help
.PHONY: all
all: fmt vet build ## Format, vet, and build
# ---------------------------------------------------------------------------
# Build
# ---------------------------------------------------------------------------
##@ Build
.PHONY: build
build: ## Build the binary for the current platform (stripped, release-style)
$(call log,Building $(BINARY_NAME) $(VERSION))
$(GO) build $(GOFLAGS) $(TRIMFLAGS) $(LDFLAGS) -o $(BINARY_NAME) $(BUILD_DIR)
@printf '%s binary: ./%s%s\n' '$(_GREEN)' '$(BINARY_NAME)' '$(_RESET)'
.PHONY: build-fast
build-fast: ## Build without ldflags (faster iteration, skips version embedding)
$(GO) build $(GOFLAGS) -o $(BINARY_NAME) $(BUILD_DIR)
.PHONY: snapshot
snapshot: ## Local test build via GoReleaser (no publish, no tag needed)
goreleaser release --snapshot --clean
.PHONY: release-check
release-check: ## Validate .goreleaser.yaml
goreleaser check
.PHONY: install
install: ## Install binary to $(GOPATH)/bin
$(call log,Installing $(BINARY_NAME))
$(GO) install $(GOFLAGS) $(LDFLAGS) $(BUILD_DIR)
# ---------------------------------------------------------------------------
# Dependencies
# ---------------------------------------------------------------------------
##@ Dependencies
.PHONY: deps
deps: ## Download and tidy Go modules
$(call log,Syncing dependencies)
$(GO) mod download
$(GO) mod tidy
.PHONY: deps-upgrade
deps-upgrade: ## Upgrade all direct dependencies to latest
$(call log,Upgrading dependencies)
$(GO) get -u ./...
$(GO) mod tidy
# ---------------------------------------------------------------------------
# Development
# ---------------------------------------------------------------------------
##@ Development
.PHONY: dev
dev: ## Live-reload dev server (requires: go install github.com/air-verse/air@latest)
$(call log,Starting dev server with live reload)
@command -v air >/dev/null 2>&1 || { \
printf '%s air not found — install with: go install github.com/air-verse/air@latest%s\n' \
'$(_YELLOW)' '$(_RESET)'; exit 1; }
air
.PHONY: run
run: build ## Build then run the server (HTTPS)
./$(BINARY_NAME) serve
.PHONY: run-http
run-http: build ## Build then run the server (HTTP, no TLS)
./$(BINARY_NAME) serve --http
# ---------------------------------------------------------------------------
# Code quality
# ---------------------------------------------------------------------------
##@ Code quality
.PHONY: fmt
fmt: ## Format all Go source files
$(call log,Formatting)
$(GO) fmt ./...
.PHONY: vet
vet: ## Run go vet
$(call log,Vetting)
$(GO) vet ./...
.PHONY: lint
lint: ## Run golangci-lint (install: https://golangci-lint.run/usage/install/)
$(call log,Linting)
@command -v golangci-lint >/dev/null 2>&1 || { \
printf '%s golangci-lint not found — see https://golangci-lint.run/usage/install/%s\n' \
'$(_YELLOW)' '$(_RESET)'; exit 1; }
golangci-lint run
.PHONY: check
check: fmt vet lint ## Run all code-quality checks (fmt + vet + lint)
# ---------------------------------------------------------------------------
# Testing
# ---------------------------------------------------------------------------
##@ Testing
.PHONY: test
test: ## Run all tests with race detector
$(call log,Testing)
$(GO) test -race -timeout 60s ./...
.PHONY: test-short
test-short: ## Run tests, skipping slow ones (-short)
$(GO) test -short -race -timeout 30s ./...
.PHONY: test-verbose
test-verbose: ## Run all tests with verbose output
$(GO) test -v -race -timeout 60s ./...
.PHONY: test-pkg
test-pkg: ## Run unit tests for pkg/ only
$(call log,Testing pkg/)
$(GO) test -race -timeout 60s ./pkg/...
.PHONY: test-cover
test-cover: ## Run tests and generate HTML coverage report
$(call log,Coverage)
@mkdir -p $(COVER_DIR)
$(GO) test -race -timeout 60s \
-coverprofile=$(COVER_DIR)/coverage.out \
-covermode=atomic ./...
$(GO) tool cover -html=$(COVER_DIR)/coverage.out -o $(COVER_DIR)/coverage.html
@printf '%s report: %s/coverage.html%s\n' '$(_GREEN)' '$(COVER_DIR)' '$(_RESET)'
.PHONY: test-cover-func
test-cover-func: test-cover ## Show per-function coverage in the terminal
$(GO) tool cover -func=$(COVER_DIR)/coverage.out
.PHONY: bench
bench: ## Run benchmarks
$(GO) test -run='^$$' -bench=. -benchmem ./...
# ---------------------------------------------------------------------------
# CI
# ---------------------------------------------------------------------------
##@ CI
.PHONY: ci
ci: deps check test build ## Full CI pipeline: deps → check → test → build
# ---------------------------------------------------------------------------
# Clean
# ---------------------------------------------------------------------------
##@ Clean
.PHONY: clean
clean: ## Remove local binary and coverage artefacts
@rm -f $(BINARY_NAME)
@rm -rf $(COVER_DIR)
@rm -rf dist
$(GO) clean -testcache
.PHONY: clean-all
clean-all: clean ## Remove everything (binary, coverage, dist, go build cache)
$(GO) clean -cache
# ---------------------------------------------------------------------------
# Docker / Podman
# ---------------------------------------------------------------------------
##@ Docker / Podman
CONTAINER_IMAGE ?= localgo:latest
.PHONY: docker-build
docker-build: ## Build Docker image
$(call log,Building Docker image $(CONTAINER_IMAGE))
docker build -t $(CONTAINER_IMAGE) .
.PHONY: docker-run
docker-run: ## Run Docker container in the foreground
docker run --rm --network=host \
-v "$$(pwd)/downloads:/app/downloads" \
-v "$$(pwd)/config:/app/config" \
$(CONTAINER_IMAGE)
.PHONY: docker-up
docker-up: ## Start via Docker Compose (detached)
PUID=$$(id -u) PGID=$$(id -g) docker compose up -d
.PHONY: docker-down
docker-down: ## Stop Docker Compose stack
docker compose down
.PHONY: docker-logs
docker-logs: ## Follow Docker Compose logs
docker compose logs -f
.PHONY: docker-clean
docker-clean: docker-down ## Stop stack and remove the image
docker rmi $(CONTAINER_IMAGE) 2>/dev/null || true
.PHONY: podman-build
podman-build: ## Build Podman image (rootless)
$(call log,Building Podman image $(CONTAINER_IMAGE))
podman build -f Containerfile -t $(CONTAINER_IMAGE) .
.PHONY: podman-run
podman-run: ## Run Podman container (rootless, foreground)
podman run --rm --userns=keep-id --network=host \
-v "$$(pwd)/downloads:/app/downloads" \
-v "$$(pwd)/config:/app/config" \
$(CONTAINER_IMAGE)
# ---------------------------------------------------------------------------
# Utilities
# ---------------------------------------------------------------------------
##@ Utilities
.PHONY: discover
discover: build ## Discover LocalGo devices on the network
./$(BINARY_NAME) discover
.PHONY: scan
scan: build ## Scan network for LocalGo devices (HTTP)
./$(BINARY_NAME) scan
.PHONY: send
send: build ## Send a file → make send FILE=<path> TO=<alias>
@test -n "$(FILE)" || { echo 'Usage: make send FILE=<path> TO=<alias>'; exit 1; }
@test -n "$(TO)" || { echo 'Usage: make send FILE=<path> TO=<alias>'; exit 1; }
./$(BINARY_NAME) send --file "$(FILE)" --to "$(TO)"
.PHONY: version
version: build ## Print the binary version string
@./$(BINARY_NAME) version
.PHONY: info
info: ## Print Makefile build variables
@printf '%sBuild info%s\n' '$(_BOLD)' '$(_RESET)'
@printf ' %-16s %s\n' 'Binary' '$(BINARY_NAME)'
@printf ' %-16s %s\n' 'Version' '$(VERSION)'
@printf ' %-16s %s\n' 'Commit' '$(GIT_COMMIT)'
@printf ' %-16s %s\n' 'Date' '$(BUILD_DATE)'
@printf ' %-16s %s\n' 'GOFLAGS' '$(GOFLAGS)'
@printf ' %-16s %s\n' 'LDFLAGS' '$(LDFLAGS)'
# ---------------------------------------------------------------------------
# Help (auto-generated from ## / ##@ comments)
# ---------------------------------------------------------------------------
##@ Help
.PHONY: help
help: ## Show this help
@printf '\n%sLocalGo — available targets%s\n' '$(_BOLD)' '$(_RESET)'
@awk 'BEGIN {FS = ":.*##"} \
/^##@/ { printf "\n%s%s%s\n", "$(_BOLD)", substr($$0, 5), "$(_RESET)"; next } \
/^[a-zA-Z0-9_-]+:.*##/ { \
printf " %s%-20s%s %s\n", "$(_CYAN)", $$1, "$(_RESET)", $$2 }' \
$(MAKEFILE_LIST)
@printf '\n%sVariables you can override:%s\n' '$(_BOLD)' '$(_RESET)'
@printf ' %s%-20s%s %s\n' '$(_CYAN)' 'GOFLAGS' '$(_RESET)' 'Extra flags for go build / go test'
@printf ' %s%-20s%s %s\n' '$(_CYAN)' 'CONTAINER_IMAGE' '$(_RESET)' 'Docker/Podman image tag (default: localgo:latest)'
@printf ' %s%-20s%s %s\n' '$(_CYAN)' 'FILE / TO' '$(_RESET)' 'Required by: make send'
@printf '\n'