-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathMakefile
More file actions
338 lines (286 loc) · 14.7 KB
/
Makefile
File metadata and controls
338 lines (286 loc) · 14.7 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
336
337
338
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
#
# Copyright 2026 Edgecast Cloud LLC.
# Triton Rust Monorepo Makefile
# Common development commands for working with trait-based Dropshot APIs
RUST_USE_BOOTSTRAP = false
RUST_CLIPPY_ARGS = --all-targets --all-features -- -D warnings
# Coverage thresholds
COVERAGE_LINE_THRESHOLD = 40
COVERAGE_TIMEOUT = 300
ENGBLD_REQUIRE := $(shell git submodule update --init deps/eng)
include ./deps/eng/tools/mk/Makefile.defs
TOP ?= $(error Unable to access eng.git submodule Makefiles.)
include ./deps/eng/tools/mk/Makefile.deps
include ./deps/eng/tools/mk/Makefile.targ
include ./deps/eng/tools/mk/Makefile.rust.defs
include ./deps/eng/tools/mk/Makefile.rust.targ
.PHONY: help build build-release test clean lint format audit audit-update
.PHONY: api-new service-new client-new
.PHONY: service-build service-test service-run
.PHONY: client-build client-test
.PHONY: package-build package-test
.PHONY: triton-test triton-test-api triton-test-all
.PHONY: triton-compare triton-compare-payload triton-compare-api triton-compare-all
.PHONY: openapi-generate openapi-list openapi-check
.PHONY: dev-setup workspace-test integration-test
.PHONY: list coverage arch-lint doc-lint
.PHONY: clients-generate clients-check
# Default target
help: ## Show this help message
@echo "Triton Rust Monorepo Development Commands"
@echo "=========================================="
@echo ""
@echo "Trait-Based API Architecture:"
@echo " 1. Define API trait in apis/"
@echo " 2. Register in openapi-manager"
@echo " 3. Implement in services/"
@echo " 4. Generate and commit OpenAPI specs"
@echo " 5. Build clients (they read checked-in specs)"
@echo ""
@awk 'BEGIN {FS = ":.*##"} /^[a-zA-Z_-]+:.*##/ { printf " %-20s %s\n", $$1, $$2 }' $(MAKEFILE_LIST)
# Workspace commands
build: | $(CARGO_EXEC) ## Build all APIs, services and clients
$(CARGO) build
build-release: | $(CARGO_EXEC) ## Build all APIs, services and clients
$(CARGO) build --release
test: | $(CARGO_NEXTEST_EXEC) ## Run all tests
TRITON_CONFIG_DIR=/nonexistent $(CARGO) nextest run
clean:: | $(CARGO_EXEC) ## Clean build artifacts
$(CARGO) clean
lint:: arch-lint doc-lint clippy
clippy: | $(CARGO_EXEC) ## Run clippy linter
$(CARGO) clippy $(RUST_CLIPPY_ARGS)
clippy-fix: | $(CARGO_EXEC) ## Run clippy linter
$(CARGO) clippy --fix --allow-dirty $(RUST_CLIPPY_ARGS)
format: | $(CARGO_EXEC) ## Format all code
$(CARGO) fmt
audit: | $(CARGO_EXEC) ## Run security audit on dependencies
$(CARGO) audit
audit-update: | $(CARGO_EXEC) ## Update advisory database and run audit
$(CARGO) audit --update
workspace-test: | $(CARGO_EXEC) ## Run all workspace tests
$(CARGO) test --workspace
# API development commands
api-new: ## Create new API trait (usage: make api-new API=my-service-api)
@if [ -z "$(API)" ]; then echo "Usage: make api-new API=my-service-api"; exit 1; fi
@if [ -d "apis/$(API)" ]; then echo "API $(API) already exists"; exit 1; fi
cp -r apis/api-template apis/$(API)
sed -i 's/example-api/$(API)/g' apis/$(API)/Cargo.toml
sed -i 's/ExampleApi/$(shell echo $(API) | sed 's/-/ /g' | sed 's/\b\(.\)/\u\1/g' | sed 's/ //g')/g' apis/$(API)/src/lib.rs
@echo "Created new API: apis/$(API)"
@echo ""
@echo "Next steps:"
@echo " 1. Add 'apis/$(API)' to workspace Cargo.toml members list"
@echo " 2. Define your API types and trait in apis/$(API)/src/lib.rs"
@echo " 3. Register in openapi-manager/src/main.rs"
@echo " 4. Run: make openapi-generate"
# Service development commands
service-new: ## Create new service (usage: make service-new SERVICE=my-service API=my-service-api)
@if [ -z "$(SERVICE)" ]; then echo "Usage: make service-new SERVICE=my-service API=my-service-api"; exit 1; fi
@if [ -d "services/$(SERVICE)" ]; then echo "Service $(SERVICE) already exists"; exit 1; fi
cp -r services/service-template services/$(SERVICE)
sed -i 's/service-template/$(SERVICE)/g' services/$(SERVICE)/Cargo.toml
@if [ ! -z "$(API)" ]; then \
echo "$$API = { path = \"../../apis/$$API\" }" >> services/$(SERVICE)/Cargo.toml; \
echo "Added dependency on $(API)"; \
fi
@echo "Created new service: services/$(SERVICE)"
@echo ""
@echo "Next steps:"
@echo " 1. Add 'services/$(SERVICE)' to workspace Cargo.toml members list"
@echo " 2. Implement the API trait in services/$(SERVICE)/src/main.rs"
@echo " 3. Test: make service-run SERVICE=$(SERVICE)"
service-build: | $(CARGO_EXEC) ## Build specific service (usage: make service-build SERVICE=my-service)
@if [ -z "$(SERVICE)" ]; then echo "Usage: make service-build SERVICE=my-service"; exit 1; fi
$(CARGO) build -p $(SERVICE)
service-test: | $(CARGO_EXEC) ## Test specific service (usage: make service-test SERVICE=my-service)
@if [ -z "$(SERVICE)" ]; then echo "Usage: make service-test SERVICE=my-service"; exit 1; fi
$(CARGO) test -p $(SERVICE)
service-run: | $(CARGO_EXEC) ## Run specific service (usage: make service-run SERVICE=my-service)
@if [ -z "$(SERVICE)" ]; then echo "Usage: make service-run SERVICE=my-service"; exit 1; fi
$(CARGO) run -p $(SERVICE)
# Client development commands
client-new: ## Create new client (usage: make client-new CLIENT=my-service-client API=my-api)
@if [ -z "$(CLIENT)" ]; then echo "Usage: make client-new CLIENT=my-service-client API=my-api"; exit 1; fi
@if [ -d "clients/internal/$(CLIENT)" ]; then echo "Client $(CLIENT) already exists"; exit 1; fi
cp -r clients/internal/client-template clients/internal/$(CLIENT)
sed -i 's/client-template/$(CLIENT)/g' clients/internal/$(CLIENT)/Cargo.toml
sed -i 's/client_template/$(shell echo $(CLIENT) | tr '-' '_')/g' clients/internal/$(CLIENT)/Cargo.toml
@echo "Created new client: clients/internal/$(CLIENT)"
@echo ""
@echo "Next steps:"
@echo " 1. Register the client in client-generator/src/main.rs"
@echo " 2. Add 'clients/internal/$(CLIENT)' to workspace Cargo.toml members list"
@echo " 3. Run: make clients-generate"
@echo " 4. Run: make client-build CLIENT=$(CLIENT)"
client-build: | $(CARGO_EXEC) ## Build specific client (usage: make client-build CLIENT=my-service-client)
@if [ -z "$(CLIENT)" ]; then echo "Usage: make client-build CLIENT=my-service-client"; exit 1; fi
$(CARGO) build -p $(CLIENT)
client-test: | $(CARGO_EXEC) ## Test specific client (usage: make client-test CLIENT=my-service-client)
@if [ -z "$(CLIENT)" ]; then echo "Usage: make client-test CLIENT=my-service-client"; exit 1; fi
$(CARGO) test -p $(CLIENT)
# Generic package commands (for any crate in the workspace)
package-build: | $(CARGO_EXEC) ## Build specific package (usage: make package-build PACKAGE=my-package)
@if [ -z "$(PACKAGE)" ]; then echo "Usage: make package-build PACKAGE=my-package"; exit 1; fi
$(CARGO) build -p $(PACKAGE)
package-test: | $(CARGO_EXEC) ## Test specific package (usage: make package-test PACKAGE=my-package)
@if [ -z "$(PACKAGE)" ]; then echo "Usage: make package-test PACKAGE=my-package"; exit 1; fi
$(CARGO) test -p $(PACKAGE)
# Triton CLI test commands
triton-test: | $(CARGO_EXEC) ## Run triton-cli offline tests (no API required)
TRITON_CONFIG_DIR=/nonexistent $(CARGO) test -p triton-cli
triton-test-api: | $(CARGO_EXEC) ## Run triton-cli API tests (requires tests/config.json)
@if [ ! -f cli/triton-cli/tests/config.json ]; then \
echo "Error: cli/triton-cli/tests/config.json not found"; \
echo "Copy config.json.sample and configure for your environment"; \
exit 1; \
fi
$(CARGO) test -p triton-cli -- --ignored
triton-test-all: | $(CARGO_NEXTEST_EXEC) $(CARGO_EXEC) ## Run all triton-cli tests (offline + API)
@if [ ! -f cli/triton-cli/tests/config.json ]; then \
echo "Warning: No config.json - API tests will fail"; \
fi
$(CARGO) nextest run -p triton-cli --no-fail-fast -- --include-ignored
triton-test-file: | $(CARGO_EXEC) ## Run specific triton-cli test file (usage: make triton-test-file TEST=cli_vlans)
@if [ -z "$(TEST)" ]; then echo "Usage: make triton-test-file TEST=cli_vlans"; exit 1; fi
$(CARGO) test -p triton-cli --test $(TEST)
# Triton CLI comparison tests (Node.js vs Rust)
triton-compare: build ## Compare Node.js vs Rust triton (offline tests)
cli/triton-cli/tests/comparison/triton-compare.sh --tier offline
triton-compare-payload: build ## Compare Node.js vs Rust triton (payload tests)
cli/triton-cli/tests/comparison/triton-compare.sh --tier payload
triton-compare-api: build ## Compare Node.js vs Rust triton (API tests, needs PROFILE=name)
@if [ -z "$(PROFILE)" ]; then echo "Usage: make triton-compare-api PROFILE=demo"; exit 1; fi
cli/triton-cli/tests/comparison/triton-compare.sh --tier api --profile $(PROFILE)
triton-compare-all: build ## Compare Node.js vs Rust triton (all tests, needs PROFILE=name)
@if [ -z "$(PROFILE)" ]; then echo "Usage: make triton-compare-all PROFILE=demo"; exit 1; fi
cli/triton-cli/tests/comparison/triton-compare.sh --tier all --profile $(PROFILE)
# OpenAPI management commands (using dropshot-api-manager)
openapi-generate: | $(CARGO_EXEC) ## Generate OpenAPI specs from API traits
@echo "Generating OpenAPI specs using dropshot-api-manager..."
$(CARGO) run -p openapi-manager -- generate
@echo "OpenAPI specs generated in openapi-specs/generated/"
@echo "Patched client specs in openapi-specs/patched/"
@echo ""
@echo " Don't forget to commit the updated specs:"
@echo " git add openapi-specs/generated/ openapi-specs/patched/"
@echo " git commit -m 'Update OpenAPI specs'"
openapi-list: | $(CARGO_EXEC) ## List all managed APIs
$(CARGO) run -p openapi-manager -- list
openapi-check: | $(CARGO_EXEC) ## Check that OpenAPI specs are up-to-date (use in CI)
$(CARGO) run -p openapi-manager -- check
openapi-debug: | $(CARGO_EXEC) ## Debug OpenAPI manager configuration
$(CARGO) run -p openapi-manager -- debug
integration-test: | $(CARGO_EXEC) ## Run integration tests across all services
$(CARGO) test --workspace integration
# Development setup
dev-setup: | $(CARGO_EXEC) ## Set up development environment
@echo "Setting up development environment..."
@echo "Building openapi-manager..."
$(CARGO) build -p openapi-manager
@echo "Running initial build..."
$(CARGO) build
@echo "Generating OpenAPI specs..."
$(MAKE) openapi-generate
@echo "Running tests to ensure everything works..."
$(CARGO) test
@echo ""
@echo "Development environment ready!"
@echo ""
@echo "Quick start:"
@echo " - List APIs: make list"
@echo " - Create API: make api-new API=my-api"
@echo " - Create service: make service-new SERVICE=my-service API=my-api"
@echo " - Generate specs: make openapi-generate"
# Quick commands for common workflows
dev: service-build service-test ## Build and test specific service (usage: make dev SERVICE=my-service)
quick-check:: $(_CHECK_COPYRIGHT_TARGET) format lint test ## Run format, lint, and test quickly
# Full workflow for new API
new-api-workflow: ## Create complete API+Service+Client (usage: make new-api-workflow NAME=myapp)
@if [ -z "$(NAME)" ]; then echo "Usage: make new-api-workflow NAME=myapp"; exit 1; fi
@echo "Creating full stack for $(NAME)..."
$(MAKE) api-new API=$(NAME)-api
@echo ""
@echo "Manual step: Add 'apis/$(NAME)-api' to workspace Cargo.toml and define your API trait"
@echo "Then register it in openapi-manager/src/main.rs"
@read -p "Press enter when ready to continue..."
$(MAKE) openapi-generate
$(MAKE) service-new SERVICE=$(NAME)-service API=$(NAME)-api
$(MAKE) client-new CLIENT=$(NAME)-client API=$(NAME)-api
@echo ""
@echo "Created complete stack for $(NAME):"
@echo " API: apis/$(NAME)-api"
@echo " Service: services/$(NAME)-service"
@echo " Client: clients/internal/$(NAME)-client"
@echo ""
@echo "Next: Implement the API trait in services/$(NAME)-service/src/main.rs"
# List available APIs, services and clients
list: ## List all APIs, services and clients
@echo "APIs:"
@ls -1 apis/ 2>/dev/null | grep -v api-template || echo " No APIs found"
@echo ""
@echo "Services:"
@ls -1 services/ 2>/dev/null | grep -v service-template || echo " No services found"
@echo ""
@echo "Internal Clients:"
@ls -1 clients/internal/ 2>/dev/null | grep -v client-template || echo " No internal clients found"
@echo ""
@echo "Managed OpenAPI Specs:"
@ls -1 openapi-specs/generated/ 2>/dev/null || echo " No specs generated yet (run: make openapi-generate)"
# Validation and CI commands
check:: | $(CARGO_NEXTEST_EXEC) $(CARGO_EXEC) ## Run all validation checks (CI-ready)
@echo "Running all validation checks..."
$(MAKE) arch-lint
$(MAKE) openapi-check
$(MAKE) clients-check
TRITON_CONFIG_DIR=/nonexistent $(CARGO) nextest run --workspace
@echo ""
@echo "All validation checks passed!"
# Client code generation (checked-in generated.rs files)
clients-generate: | $(CARGO_EXEC) ## Generate all client src/generated.rs files
$(CARGO) run -p client-generator -- generate
$(CARGO) fmt -- clients/internal/*/src/generated.rs
clients-check: | $(CARGO_EXEC) ## Check that generated client code is up-to-date (use in CI)
@echo "Checking client generated code is up-to-date..."
$(CARGO) run -p client-generator -- generate
$(CARGO) fmt -- clients/internal/*/src/generated.rs
@if git diff --quiet clients/internal/*/src/generated.rs; then \
echo "All clients are up-to-date."; \
else \
echo "ERROR: Generated client code is stale. Run 'make clients-generate' and commit."; \
git diff --stat clients/internal/*/src/generated.rs; \
exit 1; \
fi
clients-list: | $(CARGO_EXEC) ## List all managed clients
$(CARGO) run -p client-generator -- list
# Regenerate everything (OpenAPI specs + client code)
regen-clients: openapi-generate clients-generate ## Regenerate OpenAPI specs and client code
@echo "All specs and clients regenerated. Test with: make test"
# Doc-lint: check that doc comments don't leak implementation details into OpenAPI specs
DOC_LINT_PATTERNS = serde_json\|rename_all\|Dropshot\|Progenitor\|schemars\|helper method\|Service implementation\|Rust field\|Rust error\|Rust client
DOC_LINT_FILES = apis/cloudapi-api/src/types/*.rs apis/cloudapi-api/src/lib.rs \
apis/vmapi-api/src/types/*.rs apis/vmapi-api/src/lib.rs \
apis/jira-api/src/lib.rs apis/bugview-api/src/lib.rs
doc-lint: ## Check doc comments for implementation details that leak into OpenAPI specs
@echo "Checking doc comments for implementation details..."
@RESULT=""; \
for f in $(DOC_LINT_FILES); do \
if [ -f "$$f" ]; then \
MATCHES=$$(grep -n '^[[:space:]]*///' "$$f" | grep -i '$(DOC_LINT_PATTERNS)' | sed "s|^|$$f:|"); \
if [ -n "$$MATCHES" ]; then \
echo "$$MATCHES"; \
RESULT="found"; \
fi; \
fi; \
done; \
if [ -n "$$RESULT" ]; then \
echo ""; \
echo "ERROR: Found implementation details in doc comments that will leak into OpenAPI specs."; \
echo "Convert these to regular comments (//) instead of doc comments (///)."; \
exit 1; \
else \
echo "No implementation detail leaks found in doc comments."; \
fi