-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathMakefile
More file actions
226 lines (192 loc) · 8.68 KB
/
Makefile
File metadata and controls
226 lines (192 loc) · 8.68 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
.DEFAULT_GOAL := help
VERSION := $(shell git describe --tags --always --dirty 2>/dev/null || echo "dev")
COMMIT := $(shell git rev-parse --short HEAD 2>/dev/null || echo "unknown")
BUILD_DATE := $(shell date -u +"%Y-%m-%dT%H:%M:%SZ")
LDFLAGS := -X main.version=$(VERSION) \
-X main.commit=$(COMMIT) \
-X main.buildDate=$(BUILD_DATE)
LDFLAGS_RELEASE := $(LDFLAGS) -s -w
EXE_SUFFIX := $(if $(filter windows,$(shell go env GOOS)),.exe,)
BINARY := middleman$(EXE_SUFFIX)
GOPATH_FIRST := $(shell go env GOPATH | sed -E 's/^([A-Za-z]:)?([^;:]*).*/\1\2/')
ROBOREV_SRC ?= $(HOME)/code/roborev
ROBOREV_REF ?= main
AIR_BIN := $(shell if command -v air >/dev/null 2>&1; then command -v air; \
elif [ -n "$$(go env GOBIN)" ] && [ -x "$$(go env GOBIN)/air$(EXE_SUFFIX)" ]; then printf "%s" "$$(go env GOBIN)/air$(EXE_SUFFIX)"; \
elif [ -x "$(GOPATH_FIRST)/bin/air$(EXE_SUFFIX)" ]; then printf "%s" "$(GOPATH_FIRST)/bin/air$(EXE_SUFFIX)"; \
fi)
.PHONY: ensure-embed-dir check-air air-install build build-release install \
frontend frontend-dev frontend-dev-bun frontend-check api-generate roborev-api-generate \
dev test test-short test-e2e test-e2e-roborev vet lint nilaway testify-helper-check tidy svelte-skills svelte-skills-sync clean install-hooks help
# Ensure go:embed has at least one file (no-op if frontend is built)
ensure-embed-dir:
@mkdir -p internal/web/dist
@test -n "$$(ls internal/web/dist/ 2>/dev/null)" \
|| echo ok > internal/web/dist/stub.html
# Build the binary (debug, with embedded frontend)
build: frontend
go build -ldflags="$(LDFLAGS)" -o $(BINARY) ./cmd/middleman
# Build with optimizations (release)
build-release: frontend
go build -ldflags="$(LDFLAGS_RELEASE)" -trimpath -o $(BINARY) ./cmd/middleman
# Install to ~/.local/bin, $GOBIN, or $GOPATH/bin
install: build-release
@if [ -d "$(HOME)/.local/bin" ]; then \
echo "Installing to ~/.local/bin/$(BINARY)"; \
cp $(BINARY) "$(HOME)/.local/bin/$(BINARY)"; \
else \
INSTALL_DIR="$${GOBIN:-$$(go env GOBIN)}"; \
if [ -z "$$INSTALL_DIR" ]; then \
INSTALL_DIR="$(GOPATH_FIRST)/bin"; \
fi; \
mkdir -p "$$INSTALL_DIR"; \
echo "Installing to $$INSTALL_DIR/$(BINARY)"; \
cp $(BINARY) "$$INSTALL_DIR/$(BINARY)"; \
fi
# Build frontend SPA and copy into embed directory
frontend:
cd frontend && bun install && bun run build
rm -rf internal/web/dist
cp -r frontend/dist internal/web/dist
printf 'ok\n' > internal/web/dist/stub.html
# Run Vite dev server with dependencies installed (use alongside `make dev`)
frontend-dev:
./scripts/frontend-dev.sh $(ARGS)
# Run Vite dev server with Bun (use alongside `make dev`)
frontend-dev-bun:
cd frontend && bun install && bun run dev
# Run TypeScript/Svelte lint and type checks
frontend-check:
cd packages/ui && bun run typecheck && bun run lint
cd frontend && bun run typecheck && bun run lint
# Regenerate the checked-in OpenAPI documents and generated clients
api-generate:
GOCACHE="$${GOCACHE:-/tmp/middleman-gocache}" go run ./cmd/middleman-openapi -out frontend/openapi/openapi.json
GOCACHE="$${GOCACHE:-/tmp/middleman-gocache}" go run ./cmd/middleman-openapi -out internal/apiclient/spec/openapi.json -version 3.0
cd packages/ui && bunx openapi-typescript ../../frontend/openapi/openapi.json -o src/api/generated/schema.ts
printf '%s\n' \
'/**' \
' * This file was auto-generated from frontend/openapi/openapi.json.' \
' * Do not make direct changes to the file.' \
' */' \
'' \
'import createClient, { type ClientOptions } from "openapi-fetch";' \
'import type { paths } from "./schema";' \
'' \
'export function createAPIClient(baseUrl: string, options: Pick<ClientOptions, "fetch" | "querySerializer"> = {}) {' \
' return createClient<paths>({ baseUrl, ...options });' \
'}' \
> packages/ui/src/api/generated/client.ts
GOCACHE="$${GOCACHE:-/tmp/middleman-gocache}" go generate ./internal/apiclient/generated
# Regenerate roborev TypeScript client types from checked-in OpenAPI spec
roborev-api-generate:
cd packages/ui && bunx openapi-typescript src/api/roborev/openapi.json -o src/api/roborev/generated/schema.ts
@echo "Roborev API types generated"
# Ensure air is installed for backend live reload
check-air:
@if [ -z "$(AIR_BIN)" ]; then \
echo "air not found. Install with: make air-install" >&2; \
exit 1; \
fi
# Install air for backend live reload
air-install:
go install github.com/air-verse/air@latest
# Run Go server in dev mode with live reload and API artifact refresh (use alongside `make frontend-dev`)
dev: ensure-embed-dir check-air
@if [ -n "$(MIDDLEMAN_CONFIG)" ]; then \
"$(AIR_BIN)" -c .air.toml -- -config "$(MIDDLEMAN_CONFIG)" $(ARGS); \
else \
"$(AIR_BIN)" -c .air.toml -- $(ARGS); \
fi
# Run tests
test: ensure-embed-dir
go test ./... -v -shuffle=on
# Run fast tests only
test-short: ensure-embed-dir
go test ./... -short -shuffle=on
# Run integration tests that execute real git commands (excluded from test-short)
test-integration: ensure-embed-dir
go test -tags integration ./... -v -shuffle=on
# Run full-stack E2E tests (Playwright against real Go server, excludes roborev)
test-e2e: frontend
GOFLAGS="$${GOFLAGS:+$$GOFLAGS }-buildvcs=false" go build -o ./cmd/e2e-server/e2e-server$(EXE_SUFFIX) ./cmd/e2e-server
cd frontend && bun run playwright test --config=playwright-e2e.config.ts --project=chromium
# Run roborev e2e tests with Docker (ROBOREV_SRC, ROBOREV_REF, ROBOREV_PORT configurable)
test-e2e-roborev:
ROBOREV_SRC="$(ROBOREV_SRC)" ROBOREV_REF="$(ROBOREV_REF)" \
./scripts/run-roborev-e2e.sh
# Vet
vet: ensure-embed-dir
go vet ./...
# Enforce testify helper usage for assertion-heavy tests
testify-helper-check: ensure-embed-dir
GOFLAGS="$${GOFLAGS:+$$GOFLAGS }-buildvcs=false" go run ./cmd/testify-helper-check ./...
# Lint Go code and auto-fix where possible
lint: ensure-embed-dir
@if ! command -v mise >/dev/null 2>&1; then \
echo "mise not found. Install with: brew install mise" >&2; \
exit 1; \
fi
GOCACHE="$${GOCACHE:-/tmp/middleman-gocache}" mise exec -- golangci-lint run --fix
GOFLAGS="$${GOFLAGS:+$$GOFLAGS }-buildvcs=false" go run ./cmd/testify-helper-check ./...
# Run NilAway against first-party Go packages
nilaway: ensure-embed-dir
@if ! command -v nilaway >/dev/null 2>&1; then \
echo "nilaway not found. Install with:" >&2; \
echo "go install go.uber.org/nilaway/cmd/nilaway@v0.0.0-20260318203545-ad240b12fb4c" >&2; \
exit 1; \
fi
@module_path="$$(go list -m)" || { \
echo "failed to determine module path" >&2; \
exit 1; \
}; \
nilaway -include-pkgs="$$module_path" -test=false ./...
# Tidy dependencies
tidy:
go mod tidy
# Install or update repo-local Svelte AI skills and per-agent symlinks
svelte-skills:
python3 scripts/update-svelte-skills.py $(ARGS)
# Alias for explicit sync wording
svelte-skills-sync: svelte-skills
# Install pre-commit and pre-push hooks via prek
install-hooks:
@if ! command -v prek >/dev/null 2>&1; then \
echo "prek not found. Install with: brew install prek" >&2; \
exit 1; \
fi
prek install -f
# Clean build artifacts
clean:
rm -f middleman middleman.exe
rm -rf internal/web/dist dist/
# Show help
help:
@echo "middleman build targets:"
@echo ""
@echo " build - Build with embedded frontend"
@echo " build-release - Release build (optimized, stripped)"
@echo " install - Build and install to ~/.local/bin or GOPATH"
@echo " air-install - Install air live reload tool"
@echo ""
@echo " dev - Run Go server with air live reload and API artifact refresh (honors MIDDLEMAN_CONFIG)"
@echo " frontend - Build frontend SPA"
@echo " frontend-dev - Install deps and run Vite dev server, logging to tmp/logs/frontend-dev.log (honors MIDDLEMAN_CONFIG)"
@echo " frontend-dev-bun - Install deps with Bun and run Vite dev server (honors MIDDLEMAN_CONFIG)"
@echo " frontend-check - Run TS/Svelte lint and typecheck for frontend and packages/ui"
@echo " api-generate - Regenerate checked-in OpenAPI and TS schema"
@echo ""
@echo " test - Run all tests"
@echo " test-short - Run fast tests only"
@echo " test-e2e - Run full-stack E2E Playwright tests"
@echo " test-e2e-roborev - Run roborev e2e tests with Docker (ROBOREV_SRC, ROBOREV_REF)"
@echo " vet - Run go vet"
@echo " lint - Run mise-managed golangci-lint (auto-fix)"
@echo " nilaway - Run NilAway against first-party Go packages"
@echo " testify-helper-check - Enforce Assert.New(t) in assertion-heavy Go tests"
@echo " tidy - Tidy go.mod"
@echo " svelte-skills - Sync repo-local Svelte AI skills and per-agent symlinks"
@echo " svelte-skills-sync - Alias for svelte-skills"
@echo ""
@echo " install-hooks - Install pre-commit and pre-push hooks (prek)"
@echo " clean - Remove build artifacts"