cargo-delta
cargo-delta detects which crates in a Cargo workspace are impacted by changes in a Git feature branch. Build, test, and benchmark only the crates you need.
- Detection Methods: Code analysis, pattern matching and runtime heuristics.
- Impact Categorization: Separates crates into Modified, Affected, and Required.
- Configurable: Global and per-crate settings for parsing and detection.
- Dual-branch Git Comparison: Compares two branches or commits to find both modified and deleted files.
- File Control: Exclude files from analysis or trigger a full rebuild when critical files change.
Installation
Usage
Quick Start
-
Analyze the baseline branch:
-
Analyze the feature branch:
-
Compare to find impacted crates:
CI/CD Integration
cargo-delta is designed to speed up PR builds by building and testing only impacted crates.
Since detection is best-effort, a backstop build must run separately to catch anything delta missed or was misconfigured for.
PR pipeline — runs delta, builds and tests only impacted crates:
# 1. Analyze baseline (main branch)
- run: git checkout origin/main && cargo delta analyze > baseline.json
# 2. Analyze current (PR branch)
- run: git checkout $PR_BRANCH && cargo delta analyze > current.json
# 3. Determine impacted crates
- run: cargo delta run --baseline baseline.json --current current.json > delta.json
# 4. Build/test only impacted crates (use "Required" output)
- run: cargo test -p impacted-crate-a -p impacted-crate-b
Backstop pipeline — full build without delta, runs post-merge and/or on a nightly schedule:
# Full workspace build and test, no delta
- run: cargo build --workspace
- run: cargo test --workspace
The backstop ensures correctness. If it fails on code that passed the delta-optimized PR build, it indicates a gap in detection or a misconfigured delta — adjust the configuration accordingly.
Configuration
You can customize cargo-delta by providing a -c config.toml argument to the command.
Configuration options can be set globally and overridden per crate. For example:
[]
= true
= ["*.foo", "*.bar"]
[]
= ["*.baz"] # Override for a specific crate
Default settings are provided in config.toml.example.
Detection Methods
Module Traversal
Follows mod declarations and #[path] attributes to discover all Rust modules in the workspace.
Mod Macros
Discovers modules declared via custom macros (e.g., my_mod!), assuming first argument is the name of the module.
Config default:
[]
= []
Config example:
[]
= ["my_mod"] # my_mod!(foo)
Include Macros
Detects files included via macros such as include_str! and include_bytes!, assuming the first argument is the name of the file.
Config default:
[]
= true
= [
"include_str", # include_str!("file.txt")
"include_bytes" # include_bytes!("file.bin")
]
Pattern-based Assumptions
Assumes certain files are dependencies based on glob patterns (e.g., *.proto, *.snap).
Config default:
[]
= false
= []
Config example:
[]
= true
= [".proto"]
File Method Matching
Detects files loaded at runtime by matching method names (e.g., from_file, load, open), assuming the first argument is the name of the file.
Config default:
[]
= true
= [
"file", # ::file(path, ...)
"from_file", # ::from_file(path, ...)
"load", # ::load(path, ...)
"open", # ::open(path, ...)
"read", # ::read(path, ...)
"load_from" # ::load_from(path, ...)
]
File Control
File Exclusion
Exclude files and folders from analysis using glob patterns.
Config default:
= ["target/**", "*.tmp"]
Trip Wire
If any changed or deleted file matches a trip wire pattern, all crates are considered impacted.
Config default:
= []
Config example:
= [
"Cargo.toml", # top-level Cargo.toml
"delta.toml" # Delta config file
]
Output
Analyze
Analyze phase produces JSON file that's intended to be consumed by run phase.
- files: Nested tree of file dependencies as detected by all the heuristics.
- crates: Dependency relationships between crates within the workspace.
Run
Run phase produces JSON file that's intended to be consumed by your CI/CD.
- Modified: Crates directly modified by Git changes.
- Affected: Modified crates plus all their dependents, direct and indirect.
- Required: Affected crates plus all their dependencies, direct and indirect.
Limitations
This tool is best-effort and may not detect all dependencies:
- Dynamic file paths computed at runtime
- Conditional compilation dependencies
- Other dependencies not captured by the heuristics
Example
{
}
)
)
)
)
Contributing
Fork the repository and submit a pull request.