Repository navigation
Expand file tree
/
Copy pathMakefile
More file actions
133 lines (111 loc) · 5.2 KB
/
Copy pathMakefile
File metadata and controls
133 lines (111 loc) · 5.2 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
# Container-first workflow. Every Node and pnpm command runs inside the node image, so nothing beyond Docker and
# GNU Make is installed on the host. The package.json scripts are the single source of truth for what each target runs.
SHELL := /bin/bash
.ONESHELL:
.SHELLFLAGS := -eu -o pipefail -c
.DEFAULT_GOAL := help
PROJECT_NAME := $(shell sed -n 's/^ "name": "\(.*\)",$$/\1/p' package.json)
NODE_VERSION := $(shell cat .nvmrc)
NODE_IMAGE := node:$(NODE_VERSION)
DEV_CONTAINER := $(PROJECT_NAME)-dev
PORT := 4321
SITE_URL := http://localhost:$(PORT)/
HOST_USER := $(shell id -u):$(shell id -g)
INTERACTIVE := $(shell [ -t 0 ] && echo -it)
OPEN_CMD := $(shell command -v sensible-browser 2>/dev/null || command -v xdg-open 2>/dev/null || echo open)
NODE_ENV_VARS = \
-u $(HOST_USER) \
-e HOME=/tmp \
-e COREPACK_HOME=/tmp/corepack \
-e COREPACK_ENABLE_DOWNLOAD_PROMPT=0 \
-e ASTRO_TELEMETRY_DISABLED=1 \
-e npm_config_store_dir=/tmp/pnpm-store \
-v $(CURDIR):/app -w /app
APP_RUN = docker run $(INTERACTIVE) --rm $(NODE_ENV_VARS) $(NODE_IMAGE) corepack pnpm
# ─── Setup and run ───────────────────────────────────────────
.PHONY: configure
configure: ## @setup Install dependencies
@$(APP_RUN) install --frozen-lockfile
.PHONY: configure-and-update
configure-and-update: ## @setup Update dependencies
@$(APP_RUN) update --latest
.PHONY: start
start: ## @setup Start the development server with live reload
@docker rm -f $(DEV_CONTAINER) > /dev/null 2>&1 || true
@docker run -d --rm --name $(DEV_CONTAINER) $(NODE_ENV_VARS) \
-p 127.0.0.1:$(PORT):$(PORT) \
$(NODE_IMAGE) corepack pnpm dev --host 0.0.0.0 --port $(PORT) > /dev/null
@echo "Development server at $(SITE_URL)"
.PHONY: stop
stop: ## @setup Stop the development server
@docker rm -f $(DEV_CONTAINER) > /dev/null 2>&1 || true
.PHONY: logs
logs: ## @setup Follow the development server logs
@docker logs -f $(DEV_CONTAINER)
.PHONY: build
build: ## @setup Build the static site and its search index into dist/
@$(APP_RUN) build
.PHONY: preview
preview: ## @setup Serve the built site, search included, on the development port
@docker rm -f $(DEV_CONTAINER) > /dev/null 2>&1 || true
@docker run -d --rm --name $(DEV_CONTAINER) $(NODE_ENV_VARS) \
-p 127.0.0.1:$(PORT):$(PORT) \
$(NODE_IMAGE) corepack pnpm preview --host 0.0.0.0 --port $(PORT) > /dev/null
@echo "Built site at $(SITE_URL)"
.PHONY: og-image
og-image: ## @setup Draw the link-preview cards into public/og-image.png and public/og/
@docker run --rm -u $(HOST_USER) -e HOME=/tmp -v $(CURDIR):/app -w /app python:3.12-slim \
sh -c "pip install --quiet --no-cache-dir --user pillow==11.3.0 && python tools/og-image.py"
# ─── Testing ─────────────────────────────────────────────────
.PHONY: tests
tests: ## @test Run the unit tests
@$(APP_RUN) test
.PHONY: budgets
budgets: ## @test Check the script every built page ships against its budget (run after build)
@$(APP_RUN) check:budgets
# ─── Code review ─────────────────────────────────────────────
.PHONY: review
review: ## @review Run the linter, the formatter check and the Astro and TypeScript checks
@$(APP_RUN) lint
@$(APP_RUN) typecheck
.PHONY: fix-review
fix-review: ## @review Apply the linter and formatter fixes
@$(APP_RUN) lint:fix
# ─── Reports ─────────────────────────────────────────────────
.PHONY: show-site
show-site: ## @reports Open the development server in the browser
@$(OPEN_CMD) $(SITE_URL)
.PHONY: show-outdated
show-outdated: ## @reports Show outdated direct dependencies
@$(APP_RUN) outdated
# ─── Maintenance ─────────────────────────────────────────────
.PHONY: clean
clean: ## @maintenance Remove dependencies and generated artifacts
@rm -rf node_modules dist .astro site
# ─── Help ────────────────────────────────────────────────────
.PHONY: help
help: ## @help Display this help message
@echo "Usage: make [target]"
@echo ""
@awk 'BEGIN { \
FS = ":.*?## @"; \
order[1]="setup"; order[2]="test"; order[3]="review"; order[4]="reports"; order[5]="maintenance"; \
order[6]="help"; \
title["setup"]="Setup and run"; title["test"]="Testing"; title["review"]="Code review"; \
title["reports"]="Reports"; title["maintenance"]="Maintenance"; title["help"]="Help"; \
} \
/^[a-zA-Z0-9_-]+:.*## @/ { \
split($$2, parts, " "); \
section = parts[1]; \
description = substr($$2, length(section) + 2); \
entries[section] = entries[section] sprintf("\033[36m%-24s\033[0m %s\n", $$1, description); \
} \
END { \
for (index_ = 1; index_ <= 6; index_++) { \
section = order[index_]; \
if (entries[section] != "") { \
printf "%s\n", title[section]; \
printf "%s\n", entries[section]; \
} \
} \
}' $(MAKEFILE_LIST)