Skip to content

Commit 507058a

Browse files
committed
cargo-rail: improved the demo/example setup; fixed the feature pruning deleting 'optional' features.
1 parent 43e90b5 commit 507058a

File tree

141 files changed

+4434
-942
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

141 files changed

+4434
-942
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# cargo-rail
22

3-
**Monorepo orchestration for Rust workspaces. 12 dependencies. Zero workspace-hack crates.**
3+
**Graph-aware monorepo orchestration for Rust workspaces.**
44

55
[![Crates.io](https://img.shields.io/crates/v/cargo-rail.svg)](https://crates.io/crates/cargo-rail)
66
[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
# Change Detection
2+
3+
Demonstrates `cargo rail affected` and `cargo rail test` for graph-aware change detection.
4+
5+
## What This Shows
6+
7+
1. **Graph-aware analysis** - Changes propagate through the dependency graph
8+
2. **Smart categorization** - Infrastructure vs. docs-only vs. crate changes
9+
3. **Customizable patterns** - Configure what triggers rebuilds
10+
4. **CI integration** - Multiple output formats for GitHub Actions
11+
12+
## Demo
13+
14+
[change-detection demo](./demo.mp4)
15+
16+
## How It Works
17+
18+
```
19+
┌─────────────────────────────────────────────────────────────────┐
20+
│ Git Changes │
21+
│ ─────────── │
22+
│ .github/workflows/ci.yml → infrastructure (all crates) │
23+
│ README.md → docs-only (no tests) │
24+
│ crates/core/src/lib.rs → crate change → walks dep graph │
25+
└─────────────────────────────────────────────────────────────────┘
26+
27+
28+
┌─────────────────────────────────────────────────────────────────┐
29+
│ Dependency Graph Walk │
30+
│ ──────────────────── │
31+
│ core (changed) │
32+
│ ├── api (depends on core) → affected │
33+
│ │ └── server (depends on api) → affected │
34+
│ └── cli (depends on core) → affected │
35+
│ utils (no changes) → skipped │
36+
└─────────────────────────────────────────────────────────────────┘
37+
```
38+
39+
## Commands
40+
41+
```bash
42+
# Show affected crates (auto-detects origin/main)
43+
cargo rail affected
44+
45+
# Changes in last 5 commits
46+
cargo rail affected --since HEAD~5
47+
48+
# Changes between two SHAs (CI mode)
49+
cargo rail affected --from abc123 --to def456
50+
51+
# Output formats for CI
52+
cargo rail affected -f github-matrix # {"include":[{"crate":"core"},...]}
53+
cargo rail affected -f names-only # Just names, one per line
54+
cargo rail affected -f json # Full JSON output
55+
56+
# Run tests for only affected crates
57+
cargo rail test
58+
59+
# Explain why each crate is being tested
60+
cargo rail test --explain
61+
62+
# Pass arguments to test runner
63+
cargo rail test -- --nocapture
64+
```
65+
66+
## Configuration
67+
68+
```toml
69+
# rail.toml
70+
71+
# Infrastructure files that trigger all-crates rebuild
72+
[change-detection]
73+
infrastructure = [
74+
".github/**",
75+
"scripts/**",
76+
"justfile",
77+
"Makefile",
78+
"rust-toolchain.toml",
79+
"Cargo.lock",
80+
]
81+
82+
# Custom categories for specialized workflows
83+
[change-detection.custom]
84+
# Verification models - separate from regular tests
85+
verify = ["**/verify/**/*.rs"]
86+
# Benchmark files - may want separate CI job
87+
bench = ["**/benches/**"]
88+
```
89+
90+
## Output Formats
91+
92+
| Format | Use Case | Example |
93+
|--------|----------|---------|
94+
| `text` (default) | Human-readable | Pretty-printed with colors |
95+
| `json` | Programmatic access | Full structured output |
96+
| `names-only` | Shell scripting | `core\napi\nserver` |
97+
| `github-matrix` | GitHub Actions matrix | `{"include":[...]}` |
98+
| `jsonl` | Streaming/logs | One JSON object per line |
99+
100+
## GitHub Actions Integration
101+
102+
```yaml
103+
jobs:
104+
detect:
105+
runs-on: ubuntu-latest
106+
outputs:
107+
matrix: ${{ steps.affected.outputs.matrix }}
108+
steps:
109+
- uses: actions/checkout@v4
110+
with: { fetch-depth: 0 }
111+
- run: cargo install cargo-rail
112+
- id: affected
113+
run: |
114+
cargo rail affected \
115+
--from ${{ github.event.pull_request.base.sha }} \
116+
--to ${{ github.event.pull_request.head.sha }} \
117+
-f github-matrix \
118+
-o $GITHUB_OUTPUT
119+
120+
test:
121+
needs: detect
122+
strategy:
123+
matrix: ${{ fromJson(needs.detect.outputs.matrix) }}
124+
steps:
125+
- run: cargo test -p ${{ matrix.crate }}
126+
```
127+
128+
## Use Cases
129+
130+
- **CI optimization** - Only test what changed, not the entire workspace
131+
- **Pre-commit hooks** - Quick validation of affected crates
132+
- **PR reviews** - See exactly which crates a PR touches
133+
- **Monorepo scale** - Essential for large workspaces (100+ crates)
134+
135+
Details in [`summary.toml`](./summary.toml).

examples/change-detection/build.sh

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#!/bin/bash
2+
set -e
3+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
4+
cd "$SCRIPT_DIR"
5+
6+
TEST_REPO="$HOME/loadingalias/testing/tokio"
7+
if [ -d "$TEST_REPO" ]; then
8+
echo "=== Resetting test repo ==="
9+
(cd "$TEST_REPO" && git checkout -- . && git clean -fd) 2>/dev/null || true
10+
fi
11+
12+
mkdir -p segments
13+
14+
echo "=== Recording segments ==="
15+
for tape in tapes/*.tape; do
16+
echo "Recording: $(basename "$tape" .tape)"
17+
vhs "$tape"
18+
done
19+
20+
echo "=== Speeding up test segment (2x) ==="
21+
if [ -f segments/3_test.mp4 ]; then
22+
ffmpeg -y -i segments/3_test.mp4 -vf "setpts=0.5*PTS" -an segments/3_test_fast.mp4
23+
fi
24+
25+
echo "=== Concatenating segments ==="
26+
cat > segments/concat.txt << 'EOF'
27+
file '1_intro.mp4'
28+
file '2_affected.mp4'
29+
file '3_test_fast.mp4'
30+
EOF
31+
32+
ffmpeg -y -f concat -safe 0 -i segments/concat.txt -c copy demo.mp4
33+
34+
echo "=== Done ==="
35+
ls -lh demo.mp4
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# Change Detection Example
2+
#
3+
# Demonstrates graph-aware change detection for monorepo CI optimization.
4+
# The `affected` command identifies which crates need testing based on git changes.
5+
# The `test` command runs tests only for affected crates.
6+
7+
[example]
8+
type = "workflow"
9+
feature = "change-detection"
10+
commands = ["cargo rail affected", "cargo rail test"]
11+
12+
[notes]
13+
description = """
14+
Change detection uses a 3-stage pipeline:
15+
16+
1. Git diff → list of changed files
17+
2. File classification:
18+
- infrastructure → triggers all crates (Cargo.lock, CI, Makefile)
19+
- docs-only → no tests needed (*.md, docs/**)
20+
- crate files → identifies owning crate
21+
3. Graph walk → find all dependents (reverse deps)
22+
23+
The result is a minimal set of crates that need testing.
24+
"""
25+
26+
# ============================================================================
27+
# Example rail.toml configuration for change detection
28+
# ============================================================================
29+
30+
# Minimal config (uses smart defaults)
31+
[config.minimal]
32+
note = "Just works - uses default infrastructure patterns"
33+
toml = """
34+
# No config needed - defaults are sensible
35+
"""
36+
37+
# Custom infrastructure patterns
38+
[config.infrastructure]
39+
note = "Override which files trigger all-crates rebuild"
40+
toml = """
41+
[change-detection]
42+
infrastructure = [
43+
".github/**",
44+
"scripts/**",
45+
"justfile",
46+
"Makefile",
47+
"rust-toolchain.toml",
48+
"Cargo.lock",
49+
"deny.toml",
50+
]
51+
"""
52+
53+
# Custom categories for specialized CI
54+
[config.custom_categories]
55+
note = "Add custom categories for filtering in CI"
56+
toml = """
57+
[change-detection]
58+
infrastructure = [".github/**", "Cargo.lock"]
59+
60+
# Custom categories appear in JSON output
61+
[change-detection.custom]
62+
verify = ["**/verify/**/*.rs", "**/model/**/*.rs"]
63+
bench = ["**/benches/**"]
64+
fuzz = ["**/fuzz/**"]
65+
"""
66+
67+
# ============================================================================
68+
# Command examples with explanations
69+
# ============================================================================
70+
71+
[[commands]]
72+
cmd = "cargo rail affected"
73+
desc = "Auto-detect base branch (origin/main or origin/master)"
74+
75+
[[commands]]
76+
cmd = "cargo rail affected --since HEAD~10"
77+
desc = "Last 10 commits - useful for local dev"
78+
79+
[[commands]]
80+
cmd = "cargo rail affected --from $BASE_SHA --to $HEAD_SHA"
81+
desc = "CI mode - exact SHA range from PR"
82+
83+
[[commands]]
84+
cmd = "cargo rail affected -f github-matrix -o $GITHUB_OUTPUT"
85+
desc = "GitHub Actions dynamic matrix"
86+
87+
[[commands]]
88+
cmd = "cargo rail affected -f names-only | xargs cargo test -p"
89+
desc = "Shell scripting integration"
90+
91+
[[commands]]
92+
cmd = "cargo rail test --explain"
93+
desc = "See why each crate is being tested"
94+
95+
[[commands]]
96+
cmd = "cargo rail test --since main"
97+
desc = "Test all changes since branching from main"
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Change Detection - Segment 1: Introduction
2+
3+
Output segments/1_intro.mp4
4+
5+
Set Shell "bash"
6+
Set FontSize 14
7+
Set Width 1920
8+
Set Height 1080
9+
Set Theme "Catppuccin Mocha"
10+
Set Padding 40
11+
Set Framerate 30
12+
Set TypingSpeed 40ms
13+
Set WaitTimeout 30s
14+
15+
Hide
16+
Type "export PS1='~/testing/tokio> '"
17+
Enter
18+
Type "cd ~/loadingalias/testing/tokio"
19+
Enter
20+
Sleep 500ms
21+
Show
22+
23+
Sleep 500ms
24+
Type "# Large workspace with many crates"
25+
Enter
26+
Sleep 1s
27+
28+
Type "cargo metadata --format-version 1 | jq '.workspace_members | length'"
29+
Enter
30+
Wait+Screen /\d+/
31+
Sleep 2s
32+
33+
Type "# See recent changes"
34+
Enter
35+
Sleep 500ms
36+
Type "git log --oneline -5"
37+
Enter
38+
Wait+Screen /[0-9a-f]{7}/
39+
Sleep 3s
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Change Detection - Segment 2: cargo rail affected
2+
3+
Output segments/2_affected.mp4
4+
5+
Set Shell "bash"
6+
Set FontSize 14
7+
Set Width 1920
8+
Set Height 1080
9+
Set Theme "Catppuccin Mocha"
10+
Set Padding 40
11+
Set Framerate 30
12+
Set TypingSpeed 40ms
13+
Set WaitTimeout 2m
14+
15+
Hide
16+
Type "export PS1='~/testing/tokio> '"
17+
Enter
18+
Type "cd ~/loadingalias/testing/tokio"
19+
Enter
20+
Sleep 500ms
21+
Show
22+
23+
Sleep 500ms
24+
Type "# Which crates are affected by recent changes?"
25+
Enter
26+
Sleep 1s
27+
28+
Type "cargo rail affected --since HEAD~5"
29+
Enter
30+
Wait+Screen /changed files:|docs-only|test targets:|affected/
31+
Sleep 4s
32+
33+
Type "# Different output formats for CI"
34+
Enter
35+
Sleep 1s
36+
37+
Type "cargo rail affected --since HEAD~5 -f names-only"
38+
Enter
39+
Wait+Screen /tokio|stream/
40+
Sleep 3s
41+
42+
Type "# GitHub Actions matrix format"
43+
Enter
44+
Sleep 500ms
45+
Type "cargo rail affected --since HEAD~5 -f github-matrix"
46+
Enter
47+
Wait+Screen /include|crate/
48+
Sleep 4s
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Change Detection - Segment 3: cargo rail test (will be sped up)
2+
3+
Output segments/3_test.mp4
4+
5+
Set Shell "bash"
6+
Set FontSize 14
7+
Set Width 1920
8+
Set Height 1080
9+
Set Theme "Catppuccin Mocha"
10+
Set Padding 40
11+
Set Framerate 30
12+
Set TypingSpeed 40ms
13+
Set WaitTimeout 10m
14+
15+
Hide
16+
Type "export PS1='~/testing/tokio> '"
17+
Enter
18+
Type "cd ~/loadingalias/testing/tokio"
19+
Enter
20+
Sleep 500ms
21+
Show
22+
23+
Sleep 500ms
24+
Type "# Test only affected crates with --explain"
25+
Enter
26+
Sleep 1s
27+
28+
Type "cargo rail test --since HEAD~5 --explain"
29+
Enter
30+
Wait+Screen /test result:|Finished|PASSED|FAILED|error\[|running/
31+
Sleep 4s

0 commit comments

Comments
 (0)