-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathjustfile
More file actions
364 lines (292 loc) · 10.7 KB
/
Copy pathjustfile
File metadata and controls
364 lines (292 loc) · 10.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
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
# Wonopcode Development Commands
# Run `just --list` to see all available commands
# Default recipe: run checks
default: check
# === Building ===
# Build in debug mode
build:
cargo build
# Build in release mode
release:
cargo build --release
# Build with all features
build-all:
cargo build --all-features
# === Testing ===
# Run all tests
test:
cargo test
# Run tests with output
test-verbose:
cargo test -- --nocapture
# Run a specific test
test-one NAME:
cargo test {{NAME}} -- --nocapture
# Run tests for a specific crate
test-crate CRATE:
cargo test -p {{CRATE}}
# === Code Coverage ===
# Generate code coverage report (requires cargo-llvm-cov)
coverage:
cargo llvm-cov --all-features --workspace \
--ignore-filename-regex '(tests/|test\.rs|mock\.rs)'
# Generate coverage report as HTML
coverage-html:
cargo llvm-cov --all-features --workspace \
--ignore-filename-regex '(tests/|test\.rs|mock\.rs)' \
--html --output-dir coverage
# Generate coverage report as LCOV for CI
coverage-lcov:
cargo llvm-cov --all-features --workspace \
--ignore-filename-regex '(tests/|test\.rs|mock\.rs)' \
--lcov --output-path lcov.info
# Open coverage report in browser
coverage-open: coverage-html
open coverage/html/index.html
# Show coverage statistics summary per crate
# Usage: just covstats [--sort crate|lines|covered|coverage|status]
covstats *ARGS:
#!/usr/bin/env bash
set -euo pipefail
# Parse arguments
SORT_BY="crate" # Default sort
for arg in {{ARGS}}; do
case "$arg" in
--sort)
shift_next=true
;;
crate|lines|covered|coverage|status)
if [[ "${shift_next:-false}" == "true" ]]; then
SORT_BY="$arg"
shift_next=false
fi
;;
--sort=*)
SORT_BY="${arg#--sort=}"
;;
-h|--help)
echo "Usage: just covstats [--sort <field>]"
echo ""
echo "Sort options:"
echo " crate - Sort by crate name (default)"
echo " lines - Sort by total lines (descending)"
echo " covered - Sort by covered lines (descending)"
echo " coverage - Sort by coverage percentage (descending)"
echo " status - Sort by status (worst first: 🔴 → 🟠 → 🟡 → ✅)"
exit 0
;;
esac
done
echo "📊 Running tests and collecting coverage..."
echo ""
# Run coverage once and save the output
COVERAGE_OUTPUT=$(cargo llvm-cov --all-features --workspace \
--ignore-filename-regex '(tests/|test\.rs|mock\.rs)' 2>&1)
# Collect all crate data into a temp file for sorting
TEMP_DATA=$(mktemp)
trap "rm -f $TEMP_DATA" EXIT
# Get unique crate names and process each
echo "$COVERAGE_OUTPUT" | grep -E "^wonop(code)?[a-z-]*/src" | \
sed 's|/src/.*||' | sort -u | \
while read -r crate; do
# Sum up lines for this crate
CRATE_DATA=$(echo "$COVERAGE_OUTPUT" | grep "^${crate}/src" | \
awk '{total+=$8; missed+=$9} END {
if(total>0) {
covered = total - missed;
pct = (covered/total)*100;
printf "%d %d %.2f", total, covered, pct;
} else {
print "0 0 0";
}
}')
TOTAL_LINES=$(echo "$CRATE_DATA" | awk '{print $1}')
COVERED=$(echo "$CRATE_DATA" | awk '{print $2}')
PCT=$(echo "$CRATE_DATA" | awk '{print $3}')
# Determine status (numeric for sorting: 1=red, 2=orange, 3=yellow, 4=green)
if (( $(echo "$PCT >= 90" | bc -l) )); then
STATUS_NUM=4
STATUS="✅"
elif (( $(echo "$PCT >= 70" | bc -l) )); then
STATUS_NUM=3
STATUS="🟡"
elif (( $(echo "$PCT >= 50" | bc -l) )); then
STATUS_NUM=2
STATUS="🟠"
else
STATUS_NUM=1
STATUS="🔴"
fi
# Output: crate|lines|covered|coverage|status_num|status_emoji
echo "${crate}|${TOTAL_LINES}|${COVERED}|${PCT}|${STATUS_NUM}|${STATUS}" >> "$TEMP_DATA"
done
# Sort the data based on the selected field
case "$SORT_BY" in
crate)
SORTED_DATA=$(sort -t'|' -k1 "$TEMP_DATA")
;;
lines)
SORTED_DATA=$(sort -t'|' -k2 -rn "$TEMP_DATA")
;;
covered)
SORTED_DATA=$(sort -t'|' -k3 -rn "$TEMP_DATA")
;;
coverage)
SORTED_DATA=$(sort -t'|' -k4 -rn "$TEMP_DATA")
;;
status)
# Sort by status (ascending = worst first), then by coverage (ascending)
SORTED_DATA=$(sort -t'|' -k5 -n -k4 -n "$TEMP_DATA")
;;
*)
echo "Unknown sort field: $SORT_BY"
echo "Valid options: crate, lines, covered, coverage, status"
exit 1
;;
esac
# Print header
echo "╔══════════════════════════════════════════════════════════════════════╗"
echo "║ WONOPCODE COVERAGE SUMMARY ║"
echo "╠══════════════════════════════════════════════════════════════════════╣"
echo "║ Crate │ Lines │ Covered │ Coverage │ Status ║"
echo "╠════════════════════════════╪══════════╪══════════╪══════════╪════════╣"
# Print sorted rows
echo "$SORTED_DATA" | while IFS='|' read -r crate lines covered pct status_num status; do
CRATE_FMT=$(printf "%-26s" "$crate")
LINES_FMT=$(printf "%8d" "$lines")
COV_FMT=$(printf "%8d" "$covered")
PCT_FMT=$(printf "%7.2f%%" "$pct")
echo "║ ${CRATE_FMT} │ ${LINES_FMT} │ ${COV_FMT} │ ${PCT_FMT} │ ${status} ║"
done
echo "╠════════════════════════════╪══════════╪══════════╪══════════╪════════╣"
# Parse total line
TOTAL_LINE=$(echo "$COVERAGE_OUTPUT" | grep "^TOTAL")
TOTAL_LINES=$(echo "$TOTAL_LINE" | awk '{print $8}')
MISSED=$(echo "$TOTAL_LINE" | awk '{print $9}')
COVERED=$((TOTAL_LINES - MISSED))
PCT=$(echo "$TOTAL_LINE" | awk '{print $10}' | tr -d '%')
if (( $(echo "$PCT >= 90" | bc -l) )); then
STATUS="✅"
elif (( $(echo "$PCT >= 70" | bc -l) )); then
STATUS="🟡"
else
STATUS="🔴"
fi
LINES_FMT=$(printf "%8d" "$TOTAL_LINES")
COV_FMT=$(printf "%8d" "$COVERED")
PCT_FMT=$(printf "%7.2f%%" "$PCT")
echo "║ TOTAL │ ${LINES_FMT} │ ${COV_FMT} │ ${PCT_FMT} │ ${STATUS} ║"
echo "╚══════════════════════════════════════════════════════════════════════╝"
echo ""
echo "Legend: ✅ ≥90% (target) │ 🟡 ≥70% │ 🟠 ≥50% │ 🔴 <50%"
echo ""
echo "Sorted by: $SORT_BY | Target: 90% coverage"
# === Linting & Formatting ===
# Run all checks (format, lint, test)
check: fmt-check lint test
@echo "All checks passed!"
# Run strict checks (for CI - warnings as errors)
check-strict: fmt-check lint-strict test
@echo "All strict checks passed!"
# Run clippy linter
lint:
cargo clippy --all-targets --all-features
# Run clippy linter (strict - warnings as errors)
lint-strict:
cargo clippy --all-targets --all-features -- -D warnings
# Run clippy and fix what it can
lint-fix:
cargo clippy --all-targets --all-features --fix --allow-dirty --allow-staged
# Check formatting without modifying files
fmt-check:
cargo fmt --all -- --check
# Format all code
fmt:
cargo fmt --all
# === Dependency Management ===
# Check for unused dependencies (requires cargo-udeps)
udeps:
@echo "Running cargo-udeps (requires nightly)..."
cargo +nightly udeps --all-targets
# Check dependencies for issues (requires cargo-deny)
deny:
cargo deny check
# Check for outdated dependencies
outdated:
cargo outdated -R
# Update dependencies
update:
cargo update
# Audit dependencies for security vulnerabilities
audit:
cargo audit
# === Cleaning ===
# Clean build artifacts
clean:
cargo clean
# Clean and rebuild
rebuild: clean build
# Clean coverage artifacts
clean-coverage:
rm -rf coverage lcov.info
# === Documentation ===
# Generate documentation
doc:
cargo doc --no-deps --all-features
# Generate and open documentation
doc-open:
cargo doc --no-deps --all-features --open
# === Development Helpers ===
# Watch for changes and run tests
watch-test:
cargo watch -x test
# Watch for changes and run clippy
watch-lint:
cargo watch -x clippy
# Run the application
run *ARGS:
cargo run -- {{ARGS}}
# Run in release mode
run-release *ARGS:
cargo run --release -- {{ARGS}}
# === CI/Pre-commit ===
# Full CI check (what CI would run)
ci: fmt-check lint-strict test deny udeps
@echo "CI checks passed!"
# Pre-commit hook check
pre-commit: fmt-check lint
@echo "Pre-commit checks passed!"
# === Installation ===
# Install development tools
install-tools:
@echo "Installing development tools..."
cargo install cargo-watch
cargo install cargo-udeps
cargo install cargo-outdated
cargo install cargo-audit
cargo install cargo-deny
cargo install cargo-llvm-cov
@echo "Tools installed!"
# Install the application locally
install:
cargo install --path crates/wonopcode --locked
# === Profiling & Analysis ===
# Show dependency tree
tree:
cargo tree
# Show duplicate dependencies
tree-dupes:
cargo tree --duplicate
# Count lines of code (requires tokei)
loc:
tokei --exclude target
# Show code complexity metrics
complexity:
cargo clippy --all-targets --all-features -- -W clippy::cognitive_complexity 2>&1 | grep -E "cognitive_complexity|warning:"
# === Release ===
# Prepare a release build with optimizations
release-build:
cargo build --release --locked
# Check that the release builds correctly
release-check:
cargo check --release --locked