Repository navigation
Releases
v0.3.0: agent integration, fuzz consumers and safer fix
This release connects cargo-fallow to coding agents. A gate stops an agent commit or push that adds a new finding, and a skill tells the agent how to use each command. The release also makes fix continue past one bad edit, and lets fuzz targets count as users of workspace items.
cargo install cargo-fallow --lockedCoding agents
cargo fallow hooks install --target agentinstalls a gate for Claude Code and Codex. Before an agent runsgit commitorgit push, the gate runscargo fallow checkon the changed files. It blocks only a finding that the base commit does not have, and it lists each finding. An error of the tool does not block.cargo fallow hooks install --target gitinstalls the same check as a git pre-commit hook.hooks uninstallremoves the files, andhooks statusshows them.- The
cargo-fallowskill tells a coding agent how to run each command, read the JSON output and fix the findings after a block. The skill is inskills/cargo-fallow/SKILL.md, with a Codex interface file. The Fallow plugin also contains it. cargo fallow agent installsets up a repository in one step: a guide block inAGENTS.md, the skill for Claude Code and Codex, and the gate.agent statusshows the parts, andagent uninstallremoves them.cargo fallow init --agentsruns the same setup.
Use a release build of cargo-fallow with the gate. On a large workspace, a debug build can take more time than the hook timeout of the agent.
Configuration and checks
consumersin[workspace.metadata.fallow.visibility]lists separate workspaces that use the items of the workspace, for examplefuzz/Cargo.toml.visibilitythen does not report an item that a fuzz target calls, andfixdoes not narrow it. Without the key,fuzz/Cargo.tomlcounts when it exists.- A
boundaries.sourcesrule reports anallowentry whose file has fewer matches thanmax. The finding kind isallow-entry, so the list stays exact. An entry can also takerequire = ["pattern"], so the file must contain each pattern. cargo fallow api --public-crate <CRATE>sets the external libraries for one run.--all-publishedreads each published library.
cargo fallow fix
fixno longer stops the run for one edit that adds a compiler warning or error. It leaves out that edit, applies the others, and records the reason inskip_reasonanddiagnostic.- The guard now sees a new
dead_codewarning, so an edit that makes an item dead is left out. - The guard also builds each
consumersworkspace.
Changed behavior
- A
dead-publicfinding and a finding withtest_only: trueare no longerauto_fixable. A narrower keyword on such an item makes the compiler report dead code. Adead-publicfinding has a second action,remove-item. cargo fallow api --basereads the same libraries thatvisibilitytreats as an external API. Whenpublic-cratesis set, a narrowed item of an internal crate is no longer aremovedfinding.cargo fallow init --ci githubwritesfallow-rs/cargo-fallow@v0, the newest 0.x release, and not@main.
Fixes
- The GitHub Action and the GitLab CI template now work with a jq that ends each line with CRLF, as jq on Windows does. Before, the gate outputs, the annotation count, the job summary and the GitLab note pages kept a CR. With bash 3.2, the GitLab comment step could loop without end.
v0.2.0: API change check, new boundary rules and CRAP scores
This release adds an API change check, new boundary rules and CRAP scores. It also makes fix safer, and the GitHub Action now meets the GitHub Marketplace rules.
cargo install cargo-fallow --lockedNew checks
cargo fallow api --base <REF>reports the public API changes of each published library. It lists the added, removed and changed items, and the crates and features that were added or removed. Theapi-removalsgate fails when an item was removed and the breaking part of the version did not change. The GitHub Action runs it withcommand: apiand thebaseinput.cargo fallow boundarieshas three new rule types. Item rules keep some packages from a workspace item, also throughuse, aliases and re-exports. Glob re-export rules find apub use <path>::*that reads a denied crate or module.cfgrules report a path from code that acfgbuild compiles to an item that the same build does not compile.boundaries.sourcesrules takescope = "production"andallow = [{ path, max }]. The first skips test code. The second lets a listed file have up tomaxmatches.cargo fallow depshas the opt-infeature-unification-driftrule. It reports a shared crate that gets other features incargo build -p <member>than incargo build --workspace.--coverage <LCOV>gives each function a CRAP score incomplexityandcheck. A function at or overmax-crap(default 30) is acomplexity-crapfinding.
Configuration
cyclomatic-policy = "flat-match"counts a flatmatch, for example a lookup table, as one decision. The default staysstandard.cargo fallow dupes --productionandproduction = trueleave test code out of the clone search.cargo fallow visibility --public-crateand thepublic-crateskey name the libraries that are an external API. Each other library gets each rule.cargo fallow checkaccepts--base <REF>and--staged, so onecheckrun covers thefile-growthgate. The GitHub Action passes itsbaseinput tocheck.
cargo fallow fix
fixformats each changed file withrustfmtwhen the file was formatted before the edits.--only <CHECK>and--skip <CHECK>limit the edits todepsorvisibility.fixleaves out an edit that adds a compiler warning. Before, a workspace that builds with-D warningscould break afterfixexited 0.
Changed behavior
- The SARIF level of a finding now follows its severity:
errorgiveserror, andwarngiveswarning. A gate flag no longer changes the level. Adepswarning is now a SARIFwarning, not anote. - With
code-duplication = "off", theduplication-thresholdgate still judges the percentage. To drop the gate, removethresholdfrom[workspace.metadata.fallow.dupes].
Fixes
cargo fallow visibilitygives credit to intra-doc links in more forms, sofixno longer breakscargo doc. It also no longer reports items wherepub(crate)causes a rustc or clippy error: a type in the signature of apubitem, a#[cfg(test)] pubitem in a private module, and an item that ausewith a written visibility re-exports.cargo fallow depscounts an intra-doc link to a dependency as a use.cargo fallow mutantsgives--locked,--offlineand--frozento each cargo call in the copies.- The GitHub Action fails the step when
base: autocannot read the base commit of a gate that needs it. Before, the growth gate passed without a check. - The GitHub Action and the GitLab template post no first comment for a clean run.
- The description of the GitHub Action now fits the Marketplace limit.
Performance
cargo fallow checkparses each file one time. On a large workspace, the run uses about 14% less CPU time.- The memory of
cargo fallow visibilitynow grows about linearly with the source size. On a generated 5 MB file, the peak memory goes from 8.9 GB to 1.5 GB, and the time from 33 s to 1.5 s.
v0.1.0: the first release, with dependency, visibility, file, structure and mutation checks
The first release of cargo-fallow: codebase analysis for Rust workspaces, as a Cargo subcommand. It finds unused dependencies, public items that are too visible, files that no target compiles, copied code, complex functions, boundary violations and growing files. It also runs mutation tests. The static checks read cargo metadata and the syntax tree, so you do not have to compile the workspace first.
cargo install cargo-fallow --locked
cargo fallowChecks
cargo fallow checkruns each static check and writes one report. The report has a 0 to 100 health score and a gate table. The human output ends with the gates that fail and a next step.--hotspotsranks the files that are complex and change often,--file-scoresadds the maintainability index of each file, and--save-snapshotwith--trendcompares a run with an earlier score.cargo fallow depsfinds unused, misplaced and feature-only dependencies. Theunused-featurerule reports a feature of apublish = falsepackage that turns on nothing and that no code names.cargo fallow visibilityfindspubitems that are too visible. It reports dead public items and items that only their own crate uses. The exported API of a library that a registry can publish counts as an entry point, so a published crate gets no finding for its own API.--preciseadds a rust-analyzer pass for method calls and macro output.cargo fallow filesfinds.rsfiles that no target compiles.cargo fallow dupes,complexity,boundariesandsizereport clone groups, functions over the complexity limits, crate and module rule violations, and files that grow past their line limits.cargo fallow mutantsruns mutation tests. It selects the tests of each mutant from a coverage map. It is opt-in, because it builds the workspace and runs its tests.
Fixes and workflow
cargo fallow fixapplies the safe fixes. It removes unused dependency entries, moves misplaced entries to[dev-dependencies]and narrows visibility keywords. The edit keeps the format and the comments ofCargo.toml.fixrunscargo checkbefore and after a visibility edit, and writes the old files back when the check fails. Run--dry-runfirst to see the edits.cargo fallow initwrites a starting configuration. It sets each limit at the current maximum and saves the current findings as a baseline, so a gate starts green on an existing workspace.--ci githubprints a workflow.--changed-since <REF>and--baseline <PATH>keep a pull request focused. The first keeps the findings in the files that changed since the fork point of the ref. The second leaves out the findings of a saved baseline.- Suppression comments work for each check. Use
// fallow-ignore-next-line <kind>or// fallow-ignore-file <kind>in a.rsfile, and# fallow-ignore-next-line <rule>inCargo.toml. A comment that hides no finding gives astale-suppressionwarning. [workspace.metadata.fallow.rules]sets each rule toerror,warnoroff. A finding that counts for a gate has the severityerror. A rule atwarnreports the finding but does not fail the gate.cargo fallow explain <rule>gives the meaning, an example and the fix of a rule.--traceshows why a check keeps or reports one item, one dependency or one clone group.
Output and CI
- Formats: human, JSON, SARIF, compact, markdown,
github-annotations,github-summaryand an SVGbadgewith the health grade.cargo fallow schemaprints the JSON Schema of each JSON document. - Exit codes: 0 when no enforced gate fails, 1 when a gate fails, and 2 for an error.
- The GitHub Action installs a verified release binary, runs the checks, writes annotations and a job summary, and can post one sticky pull request comment. It accepts
changed-since,baselineandsave-baseline. - The GitLab CI template writes the code quality report of the merge request widget, and can post one merge request note.
--locked,--offlineand--frozenreach eachcargo metadatacall.
Release artifacts
Each archive has a SHA-256 checksum, an Ed25519 signature (.sig) and a build provenance attestation. The GitHub Action installer checks the signature and the checksum before it runs the binary, and fails closed. To check an archive by hand, run gh attestation verify <archive> --repo fallow-rs/cargo-fallow.
cargo-fallow is at version 0.x, so the JSON output can change in a minor release. The CHANGELOG lists each change.
Full changelog: https://github.com/fallow-rs/cargo-fallow/commits/v0.1.0