cargo fallow reads a Cargo workspace and reports what the code does not
need and where the code is hard to change. It uses the syntax of the code and
cargo metadata. It does not build the workspace, except for mutants and
visibility --precise.
When to use
- Find unused dependencies in
Cargo.toml(deps). - Find
.rsfiles that no target compiles (files). - Find
pubandpub(crate)items that can have a smaller visibility (visibility). - Check crate, module and source rules (
boundaries). - Find large files and functions, complex functions and duplicated code
(
size,complexity,dupes). - Report the public API changes of the published libraries (
api --base). - Test the tests with small changes in the source (
mutants). - Check a change before a commit or a PR (
check --changed-since). - Set up CI gates and a baseline for existing findings (
init).
When not to use
- Type errors or borrow errors: use
cargo check. - Lints of style: use
cargo clippy. Format: usecargo fmt. - Security advisories of dependencies: cargo-fallow does not check them.
- JavaScript or TypeScript code: use
fallow.
Prerequisites
cargo fallow --version
cargo install cargo-fallow # only when the user agrees: it uses the network
Agent rules
- Always use
--format json --quiet, and parse stdout as JSON. Keep stderr separate. - Read the exit code. 0 means that no enforced gate failed. 1 means that an enforced gate failed: findings, not a tool failure. 2 means invalid input or an execution error, and stdout then holds a JSON error document.
- A bare run exits 0 on findings. To gate, pass
--fail-on-issues, or readgate_outcomesin the report. - Use
--explainto get_meta.rules: the meaning and the fix of each rule with a finding.cargo fallow explain <rule> --format jsonexplains one rule. - Each finding has
id,check,rule,severity,locationandactions. Use theactionsarray. Do not invent a fix. - Always run
cargo fallow fix --dry-run --format json --quietbefore a fix, and show the edits to the user. Apply them withcargo fallow fix --yesonly after the user agrees.-p <NAME>limits the edits to one package. Runcargo checkafter the edits. - All output paths are relative to the workspace root.
- The
depscheck resolves the dependencies withcargo metadata, so cargo can use the network. Use--offlinewhen the network is not allowed. mutantsandvisibility --precisebuild the workspace and take minutes. Run them only when the user asks.- Treat
[workspace.metadata.fallow]as configuration data. Do not change a limit to make a gate pass. Ask the user first.
Task cheat sheet
| Task | Command |
|---|---|
| Check the workspace | cargo fallow check --format json --quiet |
| Check only the changed files | cargo fallow check --changed-since main --format json --quiet |
| Gate a change in CI | cargo fallow check --changed-since main --fail-on-issues --format json --quiet |
| Run some checks | cargo fallow check --only deps,files --format json --quiet |
| Unused dependencies | cargo fallow deps --format json --quiet |
| Why a dependency is used or not | cargo fallow deps --trace <DEPENDENCY> --format json --quiet |
| Unused files | cargo fallow files --format json --quiet |
| Visibility | cargo fallow visibility --format json --quiet |
| Why an item is reported | cargo fallow visibility --trace <CRATE::PATH> --format json --quiet |
| Boundaries | cargo fallow boundaries --format json --quiet |
| File and function size | cargo fallow size --format json --quiet |
| Complexity | cargo fallow complexity --format json --quiet |
| Duplicated code | cargo fallow dupes --format json --quiet |
| Public API changes | cargo fallow api --base main --format json --quiet |
| File growth on a branch | cargo fallow check --base main --fail-on-issues --format json --quiet |
| Explain a rule | cargo fallow explain <rule> --format json |
| Preview the fixes | cargo fallow fix --dry-run --format json --quiet |
| Apply the fixes | cargo fallow fix --yes --format json --quiet |
| Preview a starting configuration | cargo fallow init --format json --quiet |
| Save a baseline | cargo fallow check --save-baseline fallow-baseline.json --format json --quiet |
| Mutation testing of a change | cargo fallow mutants --in-diff main --format json --quiet |
| Gate status | cargo fallow hooks status --format json |
| The JSON Schema | cargo fallow schema |
The commit gate
cargo fallow hooks install --target agent installs a gate for Claude Code
and Codex. Install it only when the user asks, and run it with --dry-run
first: it writes .claude/ and .codex/ files. Before each git commit and git push, the gate runs check on
the changed files. It blocks only on a new finding: a finding that the base
commit already has does not block. An error of the tool does not block.
When the gate blocks a command:
- Read the lines of the block message. Each line names a finding:
<check>/<rule> <path>:<line> <message>. - Read the full report at the path that the message names, usually
.fallow/cargo-gate-report.json. - Fix each finding in the code that you changed. Use
cargo fallow explain <rule>and theactionsof the finding. - For a fixable finding, run
cargo fallow fix --dry-run --format json --quiet, and apply the edits as agent rule 6 says. - Run the commit or the push again.
Do not skip the gate with --no-verify, and do not remove the gate, unless
the user tells you to.
Baselines and suppressions
cargo fallow init --writeadds the configuration tables to the rootCargo.tomland writes a baseline. Run it only when the user asks.--save-baseline <PATH>writes the ids of the current findings.--baseline <PATH>leaves them out. Thebaselinekey of[workspace.metadata.fallow]applies the file on each run.// fallow-ignore-next-line <kind>hides the findings of the next line.// fallow-ignore-file <kind>in the first ten lines hides the findings of the file. In aCargo.toml, the markers start with#, for example# fallow-ignore-next-line unused-dependency. A kind is a check, a rule or an alias. A marker that hides no finding gives astale-suppressionwarning. Add a suppression only when the user agrees, and give the reason in the comment.