Inspired by Mark Richards's workshop on software architecture, this tool aims to provide practical ways to make architectural goals measurable and continuously verified ✅.
- Statement Count Analysis: 📝 Determine the number of statements in your Rust files or directories. Useful for gauging code volume and complexity of components.
- Code Volatility Analysis: 🔄 Identifies parts of your codebase that change most frequently, leveraging Git history. Helps pinpoint unstable areas or potential refactoring candidates.
- Module Coupling Analysis: 🔗 Measures dependencies between different Rust modules or components, helping you manage and reduce unwanted coupling.
- General Rust Code Analysis: 🔬 A flexible command for various static analyses on Rust source code.
- Command-Line Interface: 💻 Easy-to-use CLI for running analyses and configuring options.
- Multiple Output Formats: 📊 HTML, JSON, CSV and DOT (GraphViz).
- Rust toolchain (latest stable version recommended). Install from rustup.rs.
- Git (for volatility analysis).
cargo install raff-cli
brew install liamwh/raff/raff
# from source, install to ~/bin
just installOnce installed, the raff binary will be available on your PATH.
To see the list of available commands and their options:
raff --helpThe general command structure is:
raff <COMMAND> [OPTIONS]-
StatementCount: Analyzes statement counts.- Example:
raff statement-count --path ./src --output-format table - (You might need to add specific options based on how
StatementCountArgsis defined. Common options could include--path <directory/file>,--exclude <patterns>, etc.)
- Example:
-
Volatility: Analyzes code churn from Git history.- Example:
raff volatility --path . --output-format json - (Typically requires the target to be a Git repository. Options might include date ranges, file patterns.)
- Example:
-
Coupling: Analyzes dependencies between modules.- Example:
raff coupling --path ./src - (Might require specifying module boundaries or analysis depth.)
- Example:
-
RustCodeAnalysis: Performs general Rust code analysis.- Example:
raff rust-code-analysis --path ./src --rule <specific_rule_name> - (The exact options will depend on the implemented analysis rules.)
- Example:
For detailed options for each command, run:
raff <COMMAND> --helpraff includes a built-in pre-commit profile optimized for use as a pre-commit hook. This profile:
- Analyzes only git-staged changes
- Uses fast, read-only coupling checks suitable for commit hooks
- Prints a single-line summary on success and a CLI table on failure
- Fails the hook when it finds warnings or errors
Add raff to your .pre-commit-config.yaml:
repos:
- repo: local
hooks:
- id: raff-architecture-check
name: Architecture fitness functions
entry: raff --profile pre-commit all
language: system
pass_filenames: false
files: '(^|/)Cargo\.toml$|(^|/)Cargo\.lock$|(^|/)rust-toolchain(\.toml)?$|^\.cargo/|\.rs$'The built-in defaults work without any extra configuration. If you want to override them,
the pre-commit profile can be customized in .raff/raff.toml:
[profile.pre_commit]
fast = true
staged = true
quiet = true
sc_threshold = 25Test the pre-commit profile manually:
# Stage some files
git add src/
# Run with pre-commit profile
raff --profile pre-commit allThe following enhancements are planned or could be valuable additions:
- 🔶 FF: Do any domain objects use primitive types? (e.g.
Stringinstead ofName). - 🏛️ FF: Is codebase flat? (Analyze and visualize component hierarchy).
- 🚫 FF: No source code should reside in the root namespace (or other configurable namespace rules).
- ⚖️ Configurable thresholds for fitness functions to produce pass/fail results.
- 🚀 Integration with CI/CD pipelines / github actions.