-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMakefile
More file actions
187 lines (164 loc) · 8.43 KB
/
Makefile
File metadata and controls
187 lines (164 loc) · 8.43 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
# GitQi — development and release tooling
# Requires: git, node (for syntax check), python3 (for local server), curl (for fonts), docker (for tests)
CURRENT_VERSION := $(shell cat VERSION)
# Load local secrets (GOOGLE_FONTS_API_KEY, …) from .env if present.
# .env is gitignored; see .env.example for the template.
-include .env
export
# ── Test container ────────────────────────────────────────────────────────────
# Playwright + Chromium live inside a Docker image so the host doesn't need
# Node / npm / browsers. See Dockerfile for the image definition.
TEST_IMAGE := gitqi-tests
TEST_DOCKERFILE := Dockerfile
# Mount the repo into /work; run as the host user so generated files
# (test-results/, playwright-report/) are owned by you, not root.
DOCKER_RUN_BASE := docker run --rm \
-v "$(CURDIR)":/work \
-w /work \
--user $(shell id -u):$(shell id -g) \
--init \
--ipc=host
.DEFAULT_GOAL := help
.PHONY: help serve check release fonts test test-build test-headed test-debug test-shell test-update-snapshots
# ── Help ──────────────────────────────────────────────────────────────────────
help: ## Show available commands
@awk 'BEGIN {FS = ":.*##"} /^[a-zA-Z_-]+:.*##/ { printf " \033[36m%-14s\033[0m %s\n", $$1, $$2 }' $(MAKEFILE_LIST)
@echo ""
@echo " Current version: \033[33mv$(CURRENT_VERSION)\033[0m"
# ── Development ───────────────────────────────────────────────────────────────
# ── Local dev server ──────────────────────────────────────────────────────────
#
# Mirrors GitHub Pages' `Access-Control-Allow-Origin: *` header so gitqi.js
# loaded from http://localhost:8080 can fetch google-fonts.json even when the
# test page is opened via file:// (origin `null`).
define CORS_HTTP_SERVER_PY
import http.server, socketserver, sys
PORT = int(sys.argv[1]) if len(sys.argv) > 1 else 8080
class Handler(http.server.SimpleHTTPRequestHandler):
def end_headers(self):
self.send_header("Access-Control-Allow-Origin", "*")
super().end_headers()
with socketserver.TCPServer(("", PORT), Handler) as httpd:
print(f"Serving at http://localhost:{PORT} (CORS: *)")
httpd.serve_forever()
endef
export CORS_HTTP_SERVER_PY
serve: ## Start a local HTTP server on port 8080 (CORS enabled)
@python3 -c "$$CORS_HTTP_SERVER_PY" 8080
check: ## Validate JavaScript syntax
@node --check gitqi.js && echo "gitqi.js — syntax OK"
# ── Tests ─────────────────────────────────────────────────────────────────────
#
# Playwright end-to-end tests run entirely inside a Docker container. The host
# only needs Docker — no Node, no npm, no browsers. The repo is bind-mounted
# at /work so test artifacts (results, reports) land in tests/test-results
# and tests/playwright-report on the host.
#
# The python http.server in Playwright's webServer config serves the repo
# root, so fixture pages can <script src="/gitqi.js"></script>.
test-build: ## Build the Playwright test container (run once, or after Dockerfile edits)
@docker build -t $(TEST_IMAGE) -f $(TEST_DOCKERFILE) .
test: ## Run the Playwright test suite (headless, in docker)
@docker image inspect $(TEST_IMAGE) >/dev/null 2>&1 || $(MAKE) test-build
@$(DOCKER_RUN_BASE) $(TEST_IMAGE)
test-headed: ## Run tests with a visible browser (requires X11 on host)
@docker image inspect $(TEST_IMAGE) >/dev/null 2>&1 || $(MAKE) test-build
@xhost +local:docker >/dev/null 2>&1 || true
@$(DOCKER_RUN_BASE) \
-e DISPLAY=$(DISPLAY) \
-v /tmp/.X11-unix:/tmp/.X11-unix \
$(TEST_IMAGE) \
playwright test --config=tests/playwright.config.cjs --headed
test-debug: ## Run a single test in inspector mode. Usage: make test-debug T=tests/e2e/edit-text.spec.js
@docker image inspect $(TEST_IMAGE) >/dev/null 2>&1 || $(MAKE) test-build
@xhost +local:docker >/dev/null 2>&1 || true
@$(DOCKER_RUN_BASE) \
-e DISPLAY=$(DISPLAY) \
-e PWDEBUG=1 \
-v /tmp/.X11-unix:/tmp/.X11-unix \
$(TEST_IMAGE) \
playwright test --config=tests/playwright.config.cjs $(T)
test-shell: ## Drop into the test container for poking around
@docker image inspect $(TEST_IMAGE) >/dev/null 2>&1 || $(MAKE) test-build
@$(DOCKER_RUN_BASE) -it --entrypoint /bin/bash $(TEST_IMAGE)
# ── Font manifest ─────────────────────────────────────────────────────────────
#
# Fetches the full Google Fonts catalog from the Developer API and writes a
# normalized manifest to google-fonts.json (sibling to gitqi.js, served via
# GitHub Pages at the same base URL).
#
# Requires GOOGLE_FONTS_API_KEY in .env (copy .env.example to .env).
define BUILD_FONTS_MANIFEST_PY
import sys, json
def weights(variants):
ws = set()
for v in variants:
if v == "regular": ws.add("400")
elif v.isdigit(): ws.add(v)
return ";".join(sorted(ws, key=int)) or "400"
data = json.load(sys.stdin)
# API is called with sort=popularity, so array order IS the popularity ranking.
# Consumers that want "top N most popular" can just slice from the front.
out = [
{"name": i["family"], "cat": i["category"], "weights": weights(i["variants"])}
for i in data["items"]
]
json.dump(out, sys.stdout, separators=(",", ":"))
endef
export BUILD_FONTS_MANIFEST_PY
fonts: ## Fetch Google Fonts catalog and regenerate google-fonts.json
ifndef GOOGLE_FONTS_API_KEY
$(error GOOGLE_FONTS_API_KEY not set — copy .env.example to .env and fill in your key)
endif
@echo "Fetching Google Fonts catalog..."
@curl -fsSL "https://www.googleapis.com/webfonts/v1/webfonts?key=$(GOOGLE_FONTS_API_KEY)&sort=popularity" \
| python3 -c "$$BUILD_FONTS_MANIFEST_PY" > google-fonts.json
@python3 -c 'import json, sys; print("Wrote google-fonts.json (%d families)" % len(json.load(sys.stdin)))' < google-fonts.json
# ── Release ───────────────────────────────────────────────────────────────────
#
# Usage: make release VERSION=1.2.0
#
# What it does:
# 1. Updates the version string in gitqi.js (comment + constant)
# 2. Writes the new version to the VERSION file
# 3. Creates a pinned copy: gitqi-<version>.js
# 4. Commits all three files
# 5. Tags the commit as v<version>
# 6. Pushes commits and tags (triggers GitHub Pages deploy)
#
# After pushing, sites can reference either:
# Latest: https://<user>.github.io/<repo>/gitqi.js
# Pinned: https://<user>.github.io/<repo>/gitqi-<version>.js
release: check ## Release a new version. Usage: make release VERSION=1.2.0
ifndef VERSION
$(error VERSION is required — usage: make release VERSION=1.2.0)
endif
@# Refuse if version is unchanged
@if [ "$(VERSION)" = "$(CURRENT_VERSION)" ]; then \
echo "Error: VERSION $(VERSION) is already the current version."; \
exit 1; \
fi
@echo "Releasing v$(VERSION) (was v$(CURRENT_VERSION))..."
@# Stamp the header comment
@sed -i "s|^/\* gitqi\.js — v.*|/* gitqi.js — v$(VERSION)|" gitqi.js; \
sed -i "s|^\( \* gitqi\.js — \)v[0-9][^ ]*|\1v$(VERSION)|" gitqi.js
@# Stamp the VERSION constant inside the IIFE
@sed -i "s|const VERSION = '[^']*'|const VERSION = '$(VERSION)'|" gitqi.js
@# Write the VERSION file
@echo "$(VERSION)" > VERSION
@# Create the pinned versioned copy
@cp gitqi.js gitqi-$(VERSION).js
@echo " Created gitqi-$(VERSION).js"
@# Commit
@git add gitqi.js gitqi-$(VERSION).js VERSION
@git commit -m "Release v$(VERSION)"
@# Tag
@git tag v$(VERSION)
@echo " Tagged v$(VERSION)"
@# Push
@git push
@git push --tags
@echo ""
@echo "Done. GitHub Pages will deploy shortly."
@echo "Latest URL: https://\$$(git remote get-url origin | sed 's|.*github.com[:/]||;s|\.git$$||' | awk -F/ '{print $$1\".github.io/\"$$2}')/gitqi.js"
@echo "Pinned URL: https://\$$(git remote get-url origin | sed 's|.*github.com[:/]||;s|\.git$$||' | awk -F/ '{print $$1\".github.io/\"$$2}')/gitqi-$(VERSION).js"