-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathMakefile
More file actions
335 lines (286 loc) · 13.1 KB
/
Copy pathMakefile
File metadata and controls
335 lines (286 loc) · 13.1 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
# rangular developer targets
SHELL := /bin/bash
ROOT := $(abspath .)
DEMO_LEPTOS := $(ROOT)/demo-leptos
DEMO_TAURI := $(ROOT)/demo-tauri/src
CARGO ?= cargo
TRUNK := env -u NO_COLOR $(HOME)/.cargo/bin/trunk
CLIPPY_FLAGS := -D warnings -D clippy::all -D clippy::pedantic -D clippy::nursery
DEMO_PORT ?= 4180
DEMO_ADDR ?= 127.0.0.1
DOCKER_PORT ?= 8080
DOCKER_BUILDKIT ?= 1
APP_VERSION := $(shell awk '/^\[workspace.package\]/{p=1;next} p&&/^version = /{gsub(/"/,"",$$3); print $$3; exit}' Cargo.toml)
HUB_IMAGE := interchouette/rangular-demo
GHCR_PERSONAL_IMAGE := ghcr.io/groussac/rangular-demo
GHCR_WORKER_IMAGE := ghcr.io/interchouette/rangular-demo
GHCR_ORG_IMAGE := ghcr.io/interchouette-itc/rangular-demo
DOCKERFILE ?= docker/Dockerfile
TAG ?= dev
.DEFAULT_GOAL := help
.PHONY: help check test lint format format-check clean ci no-panic coverage \
coverage-summary coverage-html tarpaulin machete outdated fuzz fuzz-build geiger \
doc doc-open doc-clean \
demo demo-leptos demo-build demo-leptos-build demo-check demo-leptos-check \
demo-desktop demo-tauri demo-desktop-build demo-tauri-build \
docker-build docker-build-dev docker-run \
docker-push-dev-hub docker-push-dev-ghcr-personal docker-push-dev-ghcr-itc \
docker-push-release-hub docker-push-release-ghcr-personal docker-push-release-ghcr-itc \
version-show version-bump-patch version-bump-minor version-bump-major version-set \
audit deny
help:
@echo "rangular targets"
@echo ""
@echo " make check cargo check --workspace"
@echo " make test cargo test --workspace"
@echo " make no-panic garbage fixtures (parser/aot/runtime)"
@echo " make lint fmt check + clippy (workspace)"
@echo " make doc rustdoc → docs/api-rust/ (-D warnings)"
@echo " make doc-open build docs and open docs/api-rust/index.html"
@echo " make ci lint + test + no-panic + doc + audit + deny"
@echo " make coverage cargo llvm-cov lcov → coverage/lcov.info (CI / Codecov)"
@echo " make coverage-summary cargo llvm-cov --summary-only"
@echo " make coverage-html cargo llvm-cov HTML → coverage/html/"
@echo " make tarpaulin cargo tarpaulin → coverage/tarpaulin/ (local alternate)"
@echo " make machete cargo machete (unused deps)"
@echo " make outdated cargo outdated --workspace"
@echo " make fuzz cargo +nightly fuzz run $(FUZZ_TARGET) (FUZZ_TIME=$(FUZZ_TIME)s)"
@echo " make fuzz-build cargo +nightly fuzz build"
@echo " make geiger cargo geiger (unsafe dependency audit)"
@echo " make audit cargo audit"
@echo " make deny cargo deny check"
@echo " make format cargo fmt"
@echo " make clean cargo clean"
@echo ""
@echo "Demo Leptos (CSR / wasm):"
@echo " make demo / demo-leptos Trunk serve → http://$(DEMO_ADDR):$(DEMO_PORT)/"
@echo " make demo-build / demo-leptos-build"
@echo " make demo-check / demo-leptos-check"
@echo ""
@echo "Demo Tauri:"
@echo " make demo-tauri / demo-desktop Tauri window (reuses :$(DEMO_PORT) if up)"
@echo " make demo-tauri-build / demo-desktop-build"
@echo ""
@echo "Docker (browser SPA for Render):"
@echo " make docker-build Build $(HUB_IMAGE):$(APP_VERSION) + :latest"
@echo " make docker-build-dev Tag :dev + :latest (Hub + GHCR names)"
@echo " make docker-run Run image on :$(DOCKER_PORT)"
@echo ""
@echo "Version:"
@echo " make version-show"
@echo " make version-bump-patch|minor|major"
@echo " make version-set VERSION=x.y.z"
@echo " Release: wait until CI + tip Docker are green, then create GitHub Release tag v\$$(APP_VERSION)"
@echo ""
@echo "Overrides: DEMO_PORT=$(DEMO_PORT) DEMO_ADDR=$(DEMO_ADDR) DOCKER_PORT=$(DOCKER_PORT)"
check:
cd $(ROOT) && $(CARGO) check --workspace
test:
cd $(ROOT) && $(CARGO) test --workspace
no-panic:
cd $(ROOT) && $(CARGO) test -p rangular-parser garbage_input_never_panics -- --exact
cd $(ROOT) && $(CARGO) test -p rangular-aot garbage_input_returns_issues_not_empty_code -- --exact
cd $(ROOT) && $(CARGO) test -p rangular-runtime garbage_never_panics -- --exact
format:
cd $(ROOT) && $(CARGO) fmt
format-check:
cd $(ROOT) && $(CARGO) fmt --check
lint: format-check
cd $(ROOT) && $(CARGO) clippy --workspace --all-targets -- $(CLIPPY_FLAGS)
## Requires `cargo install cargo-audit`.
audit:
cd $(ROOT) && $(CARGO) audit
## Requires `cargo install cargo-deny`.
deny:
cd $(ROOT) && $(CARGO) deny check
## Requires `cargo install cargo-llvm-cov`. Writes `coverage/lcov.info` (CI / Codecov).
## demo hosts are workspace-excluded; regex keeps accidental paths out of lcov.
COVERAGE_IGNORE := demo-leptos/|demo-tauri/
coverage:
cd $(ROOT) && mkdir -p coverage && RUSTUP_TOOLCHAIN=stable $(CARGO) llvm-cov --workspace --locked --lcov \
--ignore-filename-regex '$(COVERAGE_IGNORE)' \
--output-path coverage/lcov.info
## Terminal summary only (fast local check).
coverage-summary:
cd $(ROOT) && RUSTUP_TOOLCHAIN=stable $(CARGO) llvm-cov --workspace --locked --summary-only \
--ignore-filename-regex '$(COVERAGE_IGNORE)'
## HTML report → `coverage/html/`.
coverage-html:
cd $(ROOT) && mkdir -p coverage && RUSTUP_TOOLCHAIN=stable $(CARGO) llvm-cov --workspace --locked --html \
--ignore-filename-regex '$(COVERAGE_IGNORE)' \
--output-dir coverage/html
## Alternate local coverage via tarpaulin (not used by CI; Codecov stays on llvm-cov).
## Requires `cargo install cargo-tarpaulin`.
tarpaulin:
cd $(ROOT) && mkdir -p coverage/tarpaulin && $(CARGO) tarpaulin --workspace --locked \
--exclude-files 'demo-leptos/*' 'demo-tauri/*' \
--out Html --out Xml --output-dir coverage/tarpaulin
## Unused workspace dependencies. Requires `cargo install cargo-machete`.
machete:
cd $(ROOT) && $(CARGO) machete
## Outdated crates report. Requires `cargo install cargo-outdated`.
outdated:
cd $(ROOT) && $(CARGO) outdated --workspace
## Default fuzz target: rangular_parser::parse (Angular-subset HTML).
## Requires nightly + `cargo install cargo-fuzz`. Override: FUZZ_TARGET=… FUZZ_TIME=…
FUZZ_TARGET ?= parse-html
FUZZ_TIME ?= 10
fuzz-build:
cd $(ROOT) && cargo +nightly fuzz build
fuzz:
cd $(ROOT) && cargo +nightly fuzz run $(FUZZ_TARGET) -- -max_total_time=$(FUZZ_TIME)
## Unsafe Rust surface in deps + workspace. Requires `cargo install cargo-geiger`.
geiger:
cd $(ROOT) && $(CARGO) geiger --workspace
ci: lint test no-panic doc audit deny
## rustdoc → `docs/api-rust/` (GitHub Pages publish folder).
DOC_OUT ?= $(ROOT)/target/doc
DOC_CRATE ?= rangular
RUSTDOCFLAGS ?= -D warnings
doc:
cd $(ROOT) && RUSTDOCFLAGS="$(RUSTDOCFLAGS)" $(CARGO) doc --workspace --no-deps
@test -d "$(DOC_OUT)" || (echo "missing $(DOC_OUT)"; exit 1)
@rm -rf $(ROOT)/docs/api-rust
@mkdir -p $(ROOT)/docs/api-rust
@cp -a "$(DOC_OUT)/." $(ROOT)/docs/api-rust/
@printf '%s\n' \
'<!DOCTYPE html>' \
'<html lang="en">' \
'<head>' \
'<meta charset="utf-8">' \
'<meta http-equiv="refresh" content="0; url=$(DOC_CRATE)/index.html">' \
'<title>rangular - Rust API docs</title>' \
'<link rel="canonical" href="$(DOC_CRATE)/index.html">' \
'<script>location.replace("$(DOC_CRATE)/index.html");</script>' \
'</head>' \
'<body><p><a href="$(DOC_CRATE)/index.html">rangular API documentation</a></p></body>' \
'</html>' \
> $(ROOT)/docs/api-rust/index.html
@touch $(ROOT)/docs/api-rust/.nojekyll
@printf '%s\n' \
'# Rust API documentation (rustdoc)' \
'' \
'Open [`$(DOC_CRATE)/index.html`]($(DOC_CRATE)/index.html) (root [`index.html`](index.html) redirects there).' \
> $(ROOT)/docs/api-rust/README.md
@echo "docs/api-rust/ updated - open docs/api-rust/index.html"
doc-open: doc
@xdg-open $(ROOT)/docs/api-rust/index.html 2>/dev/null \
|| open $(ROOT)/docs/api-rust/index.html 2>/dev/null \
|| echo "Open docs/api-rust/index.html in a browser"
doc-clean:
rm -rf $(ROOT)/docs/api-rust
mkdir -p $(ROOT)/docs/api-rust
@printf '%s\n' \
'# Rust API documentation (rustdoc)' \
'' \
'Generated by `make doc`. Open [`index.html`](index.html) after building.' \
> $(ROOT)/docs/api-rust/README.md
clean:
cd $(ROOT) && $(CARGO) clean
demo demo-leptos:
@if ss -tlnp 2>/dev/null | grep -q ':$(DEMO_PORT) '; then \
echo "Port $(DEMO_PORT) already in use - reuse that server or set DEMO_PORT"; \
exit 1; \
fi
cd $(DEMO_LEPTOS) && $(TRUNK) serve --release --port $(DEMO_PORT) --address $(DEMO_ADDR)
demo-build demo-leptos-build:
cd $(DEMO_LEPTOS) && $(TRUNK) build --release
demo-check demo-leptos-check: format-check
cd $(DEMO_LEPTOS) && $(CARGO) clippy --target wasm32-unknown-unknown --all-targets -- $(CLIPPY_FLAGS)
demo-desktop demo-tauri:
@if pgrep -f 'rangular-demo-tauri' >/dev/null 2>&1; then \
echo "rangular-demo-tauri already running - reuse that window"; \
exit 0; \
fi
@if ss -tlnp 2>/dev/null | grep -q ':$(DEMO_PORT) '; then \
echo "Port $(DEMO_PORT) in use - Tauri will attach without starting Trunk"; \
cd $(DEMO_TAURI) && $(CARGO) tauri dev --config '{"build":{"beforeDevCommand":""}}'; \
else \
cd $(DEMO_TAURI) && $(CARGO) tauri dev; \
fi
demo-desktop-build demo-tauri-build:
cd $(DEMO_TAURI) && $(CARGO) tauri build
docker-build:
DOCKER_BUILDKIT=$(DOCKER_BUILDKIT) docker build --pull --network=host \
-f $(DOCKERFILE) -t $(HUB_IMAGE):$(APP_VERSION) $(ROOT)
docker tag $(HUB_IMAGE):$(APP_VERSION) $(HUB_IMAGE):latest
docker-build-dev:
DOCKER_BUILDKIT=$(DOCKER_BUILDKIT) docker build --pull --network=host \
-f $(DOCKERFILE) -t $(HUB_IMAGE):dev $(ROOT)
docker tag $(HUB_IMAGE):dev $(HUB_IMAGE):latest
docker tag $(HUB_IMAGE):dev $(GHCR_PERSONAL_IMAGE):dev
docker tag $(HUB_IMAGE):dev $(GHCR_PERSONAL_IMAGE):latest
docker tag $(HUB_IMAGE):dev $(GHCR_WORKER_IMAGE):dev
docker tag $(HUB_IMAGE):dev $(GHCR_WORKER_IMAGE):latest
docker tag $(HUB_IMAGE):dev $(GHCR_ORG_IMAGE):dev
docker tag $(HUB_IMAGE):dev $(GHCR_ORG_IMAGE):latest
docker-run: docker-build-dev
@if ss -tlnp 2>/dev/null | grep -q ':$(DOCKER_PORT) '; then \
echo "Port $(DOCKER_PORT) already in use"; \
exit 1; \
fi
docker run --rm -p $(DOCKER_PORT):8080 -e PORT=8080 $(HUB_IMAGE):latest
docker-push-dev-hub:
docker push $(HUB_IMAGE):dev
docker push $(HUB_IMAGE):latest
docker-push-dev-ghcr-personal:
docker push $(GHCR_PERSONAL_IMAGE):dev
docker push $(GHCR_PERSONAL_IMAGE):latest
docker-push-dev-ghcr-itc:
docker push $(GHCR_WORKER_IMAGE):dev
docker push $(GHCR_WORKER_IMAGE):latest
docker push $(GHCR_ORG_IMAGE):dev
docker push $(GHCR_ORG_IMAGE):latest
docker-push-release-hub:
docker push $(HUB_IMAGE):$(APP_VERSION)
docker push $(HUB_IMAGE):latest
docker-push-release-ghcr-personal:
docker tag $(HUB_IMAGE):$(APP_VERSION) $(GHCR_PERSONAL_IMAGE):$(APP_VERSION)
docker tag $(HUB_IMAGE):latest $(GHCR_PERSONAL_IMAGE):latest
docker push $(GHCR_PERSONAL_IMAGE):$(APP_VERSION)
docker push $(GHCR_PERSONAL_IMAGE):latest
docker-push-release-ghcr-itc:
docker tag $(HUB_IMAGE):$(APP_VERSION) $(GHCR_WORKER_IMAGE):$(APP_VERSION)
docker tag $(HUB_IMAGE):latest $(GHCR_WORKER_IMAGE):latest
docker tag $(HUB_IMAGE):$(APP_VERSION) $(GHCR_ORG_IMAGE):$(APP_VERSION)
docker tag $(HUB_IMAGE):latest $(GHCR_ORG_IMAGE):latest
docker push $(GHCR_WORKER_IMAGE):$(APP_VERSION)
docker push $(GHCR_WORKER_IMAGE):latest
docker push $(GHCR_ORG_IMAGE):$(APP_VERSION)
docker push $(GHCR_ORG_IMAGE):latest
# Version helpers (workspace + demos + tauri.conf); release via GitHub Release tag v$$(APP_VERSION)
version-show:
@echo "Current version: $(APP_VERSION)"; \
echo "demo-leptos: $$(awk '/^version = /{gsub(/"/,"",$$3); print $$3; exit}' demo-leptos/Cargo.toml)"; \
echo "demo-tauri: $$(awk '/^version = /{gsub(/"/,"",$$3); print $$3; exit}' demo-tauri/src/Cargo.toml)"; \
echo "tauri.conf.json: $$(python3 -c "import json; print(json.load(open('demo-tauri/src/tauri.conf.json'))['version'])")"; \
echo ""; \
echo "Suggested GitHub Release tag:"; \
echo " v$(APP_VERSION)"; \
echo ""; \
echo "When creating a GitHub Release, use the Tag field (not only the title)."
define version-apply
@current="$(APP_VERSION)"; \
new="$(1)"; \
if [ -z "$$new" ]; then echo "empty version"; exit 1; fi; \
sed -i "s/version = \"$$current\"/version = \"$$new\"/g" Cargo.toml; \
sed -i "s/^version = \"$$current\"/version = \"$$new\"/" demo-leptos/Cargo.toml; \
sed -i "s/^version = \"$$current\"/version = \"$$new\"/" demo-tauri/src/Cargo.toml; \
python3 -c "import json; p='demo-tauri/src/tauri.conf.json'; c=json.load(open(p)); c['version']='$$new'; json.dump(c, open(p,'w'), indent=2); open(p,'a').write('\n')"; \
$(CARGO) metadata --format-version 1 --no-deps >/dev/null; \
$(CARGO) metadata --manifest-path demo-leptos/Cargo.toml --format-version 1 --no-deps >/dev/null; \
$(CARGO) metadata --manifest-path demo-tauri/src/Cargo.toml --format-version 1 --no-deps >/dev/null; \
echo "Version $$current → $$new (workspace + demos + tauri.conf)"
endef
version-bump-patch:
$(call version-apply,$(shell echo "$(APP_VERSION)" | awk -F. '{print $$1"."$$2"."($$3+1)}'))
version-bump-minor:
$(call version-apply,$(shell echo "$(APP_VERSION)" | awk -F. '{print $$1"."($$2+1)".0"}'))
version-bump-major:
$(call version-apply,$(shell echo "$(APP_VERSION)" | awk -F. '{print ($$1+1)".0.0"}'))
version-set:
@if [ -z "$(VERSION)" ]; then \
echo "Usage: make version-set VERSION=x.y.z"; \
exit 1; \
fi
$(call version-apply,$(VERSION))