Repository navigation
Expand file tree
/
Copy pathMakefile
More file actions
313 lines (260 loc) · 11.2 KB
/
Copy pathMakefile
File metadata and controls
313 lines (260 loc) · 11.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
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
# OS Detection
OS := $(shell uname -s)
ARCH := $(shell uname -m)
# Paths
PROJECT_DIR ?= $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST)))))
CARGO_HOME ?= $(HOME)/.cargo
CARGO_BIN_DIR ?= $(CARGO_HOME)/bin
# Tool Commands
resolve_tool = $(or $(shell command -v $(1) 2>/dev/null),$(CARGO_BIN_DIR)/$(1))
RUSTUP ?= $(call resolve_tool,rustup)
CARGO ?= $(call resolve_tool,cargo)
CROSS ?= $(call resolve_tool,cross)
TRUNK ?= $(call resolve_tool,trunk)
WASM_BINDGEN ?= $(call resolve_tool,wasm-bindgen)
CARGO_SET_VERSION ?= $(call resolve_tool,cargo-set-version)
CARGO_MACHETE ?= $(call resolve_tool,cargo-machete)
MDBOOK ?= $(call resolve_tool,mdbook)
PINNED_NIGHTLY_TOOLCHAIN := nightly-2026-09-21
NIGHTLY_TOOLCHAIN ?= $(shell \
if $(RUSTUP) toolchain list 2>/dev/null | grep -q '^$(PINNED_NIGHTLY_TOOLCHAIN)'; then \
echo $(PINNED_NIGHTLY_TOOLCHAIN); \
else \
INSTALLED_NIGHTLY=$$($(RUSTUP) toolchain list 2>/dev/null | grep '^nightly' | head -n1 | cut -d' ' -f1 | sed -E 's/-(x86_64|aarch64|arm|i686|riscv64).*//'); \
if [ -n "$$INSTALLED_NIGHTLY" ]; then echo "$$INSTALLED_NIGHTLY"; else echo nightly; fi; \
fi)
# Explicitly force stable/nightly to avoid system-wide overrides
CARGO_STABLE := $(CARGO) +stable
CARGO_NIGHTLY := $(CARGO) +$(NIGHTLY_TOOLCHAIN)
# Colors for terminal output
AQUA := \033[36m
RESET := \033[0m
BOLD := \033[1m
.DEFAULT_GOAL := help
# Number of CPUs (portable): try GNU `nproc`, then POSIX `getconf`, then macOS `sysctl`
CPU_COUNT := $(shell nproc 2>/dev/null || getconf _NPROCESSORS_ONLN 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 1)
CARGO_BUILD_JOBS := $(CPU_COUNT)
# Support positional argument for serve / run-be: make serve <settings_folder>
ifneq ($(filter $(firstword $(MAKECMDGOALS)),serve run-be),)
SETTINGS_ARG := $(word 2,$(MAKECMDGOALS))
ifneq ($(SETTINGS_ARG),)
SETTINGS_FOLDER ?= $(SETTINGS_ARG)
EXTRA_GOALS := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS))
$(eval .PHONY: $(EXTRA_GOALS))
$(eval $(EXTRA_GOALS):;@:)
endif
endif
SETTINGS_FOLDER ?= $(settings_folder)
ifeq ($(SETTINGS_FOLDER),)
SETTINGS_FOLDER := $(TULIPROX_HOME)
endif
.PHONY: help
help: ## Display this help
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make $(AQUA)<target>$(RESET)\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " $(AQUA)%-26s$(RESET) %s\n", $$1, $$2 } /^##@/ { printf "\n$(BOLD)%s$(RESET)\n", substr($$0, 5) } ' $(MAKEFILE_LIST)
##@ Prerequisites:
.PHONY: install-tools
install-tools: rustup install-nightly-fmt cross trunk wasm-bindgen cargo-set-version cargo-machete mdbook markdownlint ## Install required development tools
.PHONY: install-nightly-fmt
install-nightly-fmt: ## Install nightly toolchain specifically for formatting and clippy
@echo "📦 Ensuring nightly rustfmt and clippy are available"
@$(RUSTUP) toolchain install $(NIGHTLY_TOOLCHAIN) --component rustfmt --component clippy --profile minimal
@echo "✅ Nightly rustfmt and clippy ready"
.PHONY: rustup
rustup: $(RUSTUP) ## Install Rust toolchain and cargo
$(RUSTUP):
@echo "📦 Installing cargo"
@curl -sL https://sh.rustup.rs | sh -s -- -y
@echo "✅ Cargo installed"
.PHONY: cross
cross: $(CROSS) ## Install cross (multi-platform build tool)
$(CROSS):
@echo "📦 Installing cross"
@$(CARGO) install cross
@echo "✅ Cross installed"
.PHONY: trunk
trunk: $(TRUNK) ## Install trunk (frontend build tool)
$(TRUNK):
@echo "📦 Installing trunk"
@$(CARGO) install trunk
@echo "✅ Trunk installed"
.PHONY: wasm-bindgen
wasm-bindgen: $(WASM_BINDGEN) ## Install wasm-bindgen CLI (for frontend builds)
$(WASM_BINDGEN):
@echo "📦 Installing wasm-bindgen CLI"
@$(CARGO) install wasm-bindgen-cli
@echo "✅ wasm-bindgen CLI installed"
.PHONY: cargo-set-version
cargo-set-version: $(CARGO_SET_VERSION) ## Install cargo-set-version (for version management)
$(CARGO_SET_VERSION):
@echo "📦 Installing $@"
@$(CARGO) install cargo-edit
@echo "✅ $@ installed"
.PHONY: mdbook
mdbook: $(MDBOOK) ## Install mdBook (documentation generator)
$(MDBOOK):
@echo "📦 Installing mdBook"
@$(CARGO) install mdbook
@echo "✅ mdBook installed"
.PHONY: cargo-machete
cargo-machete: $(CARGO_MACHETE) ## Install cargo-machete (unused dependency detector)
$(CARGO_MACHETE):
@echo "📦 Installing $@"
@$(CARGO) install cargo-machete
@echo "✅ $@ installed"
.PHONY: markdownlint
markdownlint: ## Install markdownlint-cli2 (requires npm)
@echo "📦 Installing markdownlint-cli2"
@command -v npm >/dev/null 2>&1 || { \
echo "❌ npm not found. Please install Node.js and npm first."; \
exit 1; \
}
@npm install -g markdownlint-cli2
@echo "✅ markdownlint-cli2 installed"
##@ Development:
.PHONY: verify validate ci
verify: ## Run format, clippy, markdown lint, tests, and trunk build (stops on error)
@$(MAKE) fmt
@$(MAKE) lint
@$(MAKE) markdown-lint
@$(MAKE) test
@$(MAKE) trunk-build
@$(MAKE) cargo-machete-check
validate: verify ## Alias for verify
ci: verify ## Alias for verify
.PHONY: trunk-build
trunk-build: ## Build frontend with Trunk (WASM)
@echo "==> Building frontend (trunk)"
@cd frontend && NO_COLOR=true $(TRUNK) build
.PHONY: run-fe
run-fe: ## Run frontend development server with Trunk
@echo "==> Serving frontend (trunk)"
@cd frontend && $(TRUNK) serve
.PHONY: cargo-machete-check
cargo-machete-check: ## Detect unused dependencies across all crates (auto-installs cargo-machete if missing)
@echo "==> Detecting unused dependencies"
@command -v $(CARGO_MACHETE) >/dev/null 2>&1 || { \
echo "📦 cargo-machete not found, installing..."; \
$(CARGO) install cargo-machete; \
echo "✅ cargo-machete installed"; \
}
@$(CARGO_MACHETE)
.PHONY: test
test: ## Run all workspace tests (Stable) — use detected CPU count for parallelism
@echo "==> Running tests (stable) with $(CPU_COUNT) jobs/threads"
@TMPDIR="$${TMPDIR:-/tmp}" RUST_TEST_THREADS=$(CPU_COUNT) ./bin/test.sh -j$(CPU_COUNT) --workspace -- --test-threads=$(CPU_COUNT)
.PHONY: admission-test
admission-test: ## Verify admission, provider-slot, seek/reopen, shared-stream, and cleanup invariants
@echo "==> Running HTTP admission and provider lifecycle tests"
@$(CARGO_STABLE) test --package tuliprox api_utils::tests:: -- --test-threads=1
@echo "==> Running client stream lifecycle tests"
@$(CARGO_STABLE) test --package tuliprox api::model::streams::active_client_stream::tests:: -- --test-threads=1
@echo "==> Running session, eviction, and provider-slot lifecycle tests"
@$(CARGO_STABLE) test --package tuliprox-session -- --test-threads=1
.PHONY: testkit-test
testkit-test: ## Run unit tests in tuliprox-testkit
@echo "==> Running testkit unit tests"
@$(CARGO_STABLE) test --package tuliprox-testkit
.PHONY: testkit-e2e
testkit-e2e: ## Run testkit E2E scenario suite against freshly built SUT
@echo "==> Building tuliprox and tuliprox-testkit"
@$(CARGO_STABLE) build --package tuliprox --package tuliprox-testkit
@echo "==> Executing testkit scenario suite"
@./bin/run-testkit-scenarios.sh
.PHONY: testkit-scenario
testkit-scenario: ## Run one testkit scenario: make testkit-scenario SCENARIO=<name> [RUN_ID=<id>]
@if [ -z "$(SCENARIO)" ]; then \
echo "❌ Error: SCENARIO is required."; \
echo "Usage: make testkit-scenario SCENARIO=<scenario-name>"; \
echo "Available scenarios:"; \
ls test/fixtures/testkit/scenarios/*.yml | xargs -n1 basename | sed 's/\.yml$$//' | sed 's/^/ - /'; \
exit 1; \
fi
@if [ ! -f "test/fixtures/testkit/scenarios/$(SCENARIO).yml" ]; then \
echo "❌ Unknown scenario: $(SCENARIO)"; \
exit 1; \
fi
@echo "==> Building tuliprox and tuliprox-testkit"
@$(CARGO_STABLE) build --package tuliprox --package tuliprox-testkit
@mkdir -p testkit-report/$(SCENARIO)
@echo "==> Running scenario $(SCENARIO)"
@TULIPROX_TESTKIT_SUT_BINARY="$(PROJECT_DIR)/target/debug/tuliprox" \
./target/debug/tuliprox-testkit controller \
--scenario test/fixtures/testkit/scenarios/$(SCENARIO).yml \
--report-directory testkit-report/$(SCENARIO) \
$(if $(RUN_ID),--run-id $(RUN_ID),)
@echo "==> Report: testkit-report/$(SCENARIO)/summary.txt"
.PHONY: build
build: ## Build the entire workspace in parallel using detected CPU count
@echo "==> Building workspace with $(CARGO_BUILD_JOBS) jobs"
@TMPDIR="$${TMPDIR:-/tmp}" $(CARGO_STABLE) build -j$(CARGO_BUILD_JOBS) --workspace
.PHONY: serve run-be
serve: ## Run tuliprox server with settings folder: make serve <settings_folder>
@if [ -z "$(SETTINGS_FOLDER)" ]; then \
echo "❌ Error: Settings folder is required."; \
echo "Usage: make serve <settings_folder> OR make serve SETTINGS_FOLDER=<settings_folder>"; \
exit 1; \
fi
@echo "==> Starting tuliprox server with TULIPROX_HOME=$(SETTINGS_FOLDER)"
TULIPROX_HOME="$(SETTINGS_FOLDER)" $(CARGO) run --manifest-path $(PROJECT_DIR)/Cargo.toml --package tuliprox --bin tuliprox -- -s
.PHONY: serve-fe
serve-fe: ## Run frontend dev server with Trunk: make serve-fe
@echo "==> Starting frontend dev server (trunk serve)"
@cd $(PROJECT_DIR)/frontend && $(TRUNK) serve --address 127.0.0.1
run-be: serve ## Alias for serve
.PHONY: architecture-check
architecture-check: ## Verify workspace dependency direction
@echo "==> Checking the architecture gate itself"
./bin/check-workspace-deps-test.sh
@echo "==> Checking workspace dependency direction"
./bin/check-workspace-deps.sh
.PHONY: doctor-check
doctor-check: ## Verify the DVR doctor still matches the routes it reports on
@echo "==> Checking bin/dvr_doctor.sh"
./bin/dvr_doctor-test.sh
.PHONY: lint
lint: ## Run clippy linter (Nightly)
@echo "==> Running clippy (nightly)"
$(CARGO_NIGHTLY) clippy --workspace --all-targets -- -D warnings
.PHONY: lint-fix
lint-fix: ## Automatically fix clippy suggestions (Nightly)
@echo "==> Applying clippy auto-fixes"
$(CARGO_NIGHTLY) clippy --fix --workspace --allow-dirty --allow-staged -- -D clippy::uninlined_format_args
.PHONY: fmt
fmt: ## Format all code using nightly rules (Compact)
@echo "==> Formatting code (nightly)"
$(CARGO_NIGHTLY) fmt --all
.PHONY: fmt-check
fmt-check: ## Check if code follows formatting rules (Nightly)
@echo "==> Checking formatting (nightly)"
$(CARGO_NIGHTLY) fmt --all -- --check
@echo "==> Checking git diff for whitespace errors"
git diff --check
.PHONY: markdown-lint mdlint
markdown-lint: ## Lint markdown files
@echo "==> Linting markdown files"
# @command -v markdownlint-cli2 >/dev/null 2>&1 || { \
# echo "❌ markdownlint-cli2 not found. Install with: npm install -g markdownlint-cli2"; \
# exit 1; \
# }
@npx markdownlint-cli2 "docs/src/**/*.md" "README.md" "CHANGELOG.md" "CONTRIBUTING.md" "docker/README.md"
@echo "✅ Markdown linting complete"
mdlint: markdown-lint ## Alias for markdown-lint
.PHONY: docs
docs: mdbook ## Build static documentation into frontend/build/docs
@echo "==> Building documentation"
@$(MDBOOK) build
@echo "✅ Documentation built at frontend/build/docs"
.PHONY: docs-serve
docs-serve: mdbook ## Serve documentation locally with mdBook
@echo "==> Serving documentation"
@$(MDBOOK) serve --open
.PHONY: docs-clean
docs-clean: ## Remove generated documentation output
@echo "==> Removing generated documentation"
@rm -rf frontend/build/docs
@echo "✅ Documentation output removed"
.PHONY: web-dist
web-dist: mdbook trunk ## Build static documentation and frontend assets
@echo "==> Building web assets"
@./bin/build_fe.sh release
@echo "✅ Web assets built"