|
11 | 11 |
|
12 | 12 | ## [Unreleased] |
13 | 13 |
|
| 14 | +## [0.2.0] - 2026-11-05 |
| 15 | + |
| 16 | +### Added |
| 17 | + |
| 18 | +- `cargo fallow fix` formats each changed file with `rustfmt` when `rustfmt` |
| 19 | + formatted it before the edits, so `cargo fmt --check` still passes. |
| 20 | + |
| 21 | +- `cargo fallow fix --only <CHECK>` and `--skip <CHECK>` limit the edits to |
| 22 | + some checks. The values are `deps` and `visibility`. Each flag takes a list |
| 23 | + with commas and can repeat. A `--skip` of both checks exits 2. |
| 24 | + |
| 25 | +- `[workspace.metadata.fallow.complexity] cyclomatic-policy = "flat-match"` |
| 26 | + counts a flat `match` as one decision for the `max-cyclomatic` limit. A |
| 27 | + flat `match` has no guard and no decision in an arm, for example a lookup |
| 28 | + table. A finding then has `standard_cyclomatic` with the standard count. |
| 29 | + The default stays `standard`, and the health score does not change. |
| 30 | + |
| 31 | +- `cargo fallow visibility` has the `--public-crate` flag and the |
| 32 | + `public-crates` key of `[workspace.metadata.fallow.visibility]`. When they |
| 33 | + name libraries, only those libraries are an external API. Each other |
| 34 | + library gets each rule, also when a registry can publish it. A name can |
| 35 | + have `*` as a glob. fallow for TypeScript names the same option |
| 36 | + `publicPackages`. |
| 37 | + |
| 38 | +- `cargo fallow complexity --coverage <LCOV>` and `cargo fallow check |
| 39 | + --coverage <LCOV>` give each function a CRAP score from its cyclomatic |
| 40 | + complexity and its line coverage. A function at or over |
| 41 | + `[workspace.metadata.fallow.complexity] max-crap` (default 30) is a |
| 42 | + `complexity-crap` finding. `--coverage-root <PATH>` maps the `SF` paths of |
| 43 | + an LCOV file from another machine. |
| 44 | + |
| 45 | +- `[workspace.metadata.fallow.dupes] production = true` and |
| 46 | + `cargo fallow dupes --production` leave test code out of the clone search. |
| 47 | + Test code is a test target, a test module and an item with a test |
| 48 | + attribute, for example `#[cfg(test)]` or `#[test]`. The line counts and the |
| 49 | + `threshold` then count only production code. The default stays `false`. |
| 50 | + `--no-production` keeps test code. |
| 51 | + |
| 52 | +- `cargo fallow check` accepts `--base <REF>` and `--staged`, and gives them to |
| 53 | + the size check. The `file-growth` gate then runs, and `--fail-on-issues` |
| 54 | + enforces it, so one `check` run covers each gate. |
| 55 | + |
| 56 | +- A `boundaries.sources` rule takes `scope = "production"`. The rule then |
| 57 | + skips test targets, test modules and items with a test attribute, for |
| 58 | + example `#[cfg(test)]` or `#[test]`. |
| 59 | +- A `boundaries.sources` rule takes `allow = [{ path, max }]`. A listed file |
| 60 | + passes up to `max` matches of the rule. Each match over `max` is a finding. |
| 61 | + |
| 62 | +- The GitHub Action passes the `base` input to `check` as `--base`, so the |
| 63 | + `file-growth` gate runs in a `check` step. |
| 64 | + |
| 65 | +- `cargo fallow boundaries` has item rules |
| 66 | + (`[[workspace.metadata.fallow.boundaries.items]]`) and glob re-export rules |
| 67 | + (`[[workspace.metadata.fallow.boundaries.reexports]]`). An item rule keeps |
| 68 | + the code of some packages from a workspace item, with the path resolved |
| 69 | + through `use`, aliases and re-exports. `allow-via` keeps a use through a |
| 70 | + named module allowed. A glob re-export rule finds a `pub use <path>::*` |
| 71 | + that reads a denied crate or module. The findings have the kinds |
| 72 | + `item-path` and `glob-reexport`, and the summary counts the uses that do |
| 73 | + not resolve in `unresolved`. |
| 74 | + |
| 75 | +- `cargo fallow api --base <REF>` reports the public API changes of each |
| 76 | + published library between the merge base of the ref and HEAD: `added`, |
| 77 | + `removed` and `changed` items, and `crate-added`, `crate-removed` and |
| 78 | + `feature-removed`. The `api-removals` gate counts a removal when the |
| 79 | + breaking part of the version did not change. The GitHub Action runs it with |
| 80 | + `command: api` and the `base` input. |
| 81 | + |
| 82 | +- `[[workspace.metadata.fallow.boundaries.cfg]]` rules list `cfg` builds, |
| 83 | + for example `builds = [["test"], ["test", "miri"]]`. For each build, the |
| 84 | + rule reports a path from code that the build compiles to an item that the |
| 85 | + build does not compile. The kind is `cfg-path`. An option that no build |
| 86 | + names is unknown, and then the rule gives credit. |
| 87 | + |
| 88 | +- `cargo fallow deps` has the opt-in `feature-unification-drift` rule. For each |
| 89 | + member that `unify-features` in `[workspace.metadata.fallow.deps]` names, it |
| 90 | + compares the features that `cargo build -p <member>` and |
| 91 | + `cargo build --workspace` turn on for each shared crate. Each finding names |
| 92 | + the crate, the version and the features that only one build turns on. |
| 93 | + |
| 94 | +### Changed |
| 95 | + |
| 96 | +- The SARIF level of a finding now follows its severity: `error` gives |
| 97 | + `error`, and `warn` gives `warning`. Before, an `error` finding was a |
| 98 | + SARIF `warning` when its gate was not enforced. A gate flag no longer |
| 99 | + changes the level. This is the same rule that fallow uses. |
| 100 | +- A `deps` warning, for example `unused-optional-dependency`, is now a SARIF |
| 101 | + `warning`. Before, it was a SARIF `note`. |
| 102 | +- The `github-annotations` and `github-summary` formats and the GitHub Action |
| 103 | + use the same level. A surviving mutant is now always an `error`. |
| 104 | + |
| 105 | +- With `code-duplication = "off"`, the `duplication-threshold` gate still |
| 106 | + judges the percentage, and the output has no clone group. A workspace can |
| 107 | + now gate the percentage without a warning for each clone group. Before, the |
| 108 | + rule at `off` removed the gate too. A workspace that used `off` to drop the |
| 109 | + gate must now remove `threshold` from `[workspace.metadata.fallow.dupes]`. |
| 110 | + |
| 111 | +### Fixed |
| 112 | + |
| 113 | +- `cargo fallow mutants` now gives `--locked`, `--offline` and `--frozen` to |
| 114 | + each cargo call in the copies: the builds, the test lists, the doctests and |
| 115 | + the `cargo metadata` calls. Before, only the first `cargo metadata` call got |
| 116 | + the flag, so a build in a copy could use the network. With `--offline` or |
| 117 | + `--frozen`, these calls and the test runs also get `CARGO_NET_OFFLINE=true`. |
| 118 | + |
| 119 | +- `cargo fallow visibility` no longer reports a type that the signature of an |
| 120 | + item that stays `pub` names, for example the return type of a `#[napi] pub |
| 121 | + fn`. Before, the `pub(crate)` change made rustc warn with |
| 122 | + `private_interfaces`. |
| 123 | +- `cargo fallow visibility` gives credit to an intra-doc link in a doc |
| 124 | + comment, a `#[doc]` attribute or an included documentation file. The link |
| 125 | + is a use from the module of the documentation, so `fix` no longer breaks |
| 126 | + `cargo doc`. The trace shows the use as `doc-link`. |
| 127 | +- `cargo fallow deps` counts an intra-doc link to a dependency as a use. |
| 128 | + |
| 129 | +- `cargo fallow visibility` no longer reports `unnecessary-public` for a |
| 130 | + `#[cfg(test)] pub` item in a private module. There, `pub` already gives |
| 131 | + crate visibility, and `clippy::redundant_pub_crate` rejects `pub(crate)`. |
| 132 | + When only its own module uses the item, the check reports |
| 133 | + `unnecessary-restricted-visibility`, so `fix` makes it private. |
| 134 | +- `cargo fallow visibility` no longer reports an item that a `use` with a |
| 135 | + written visibility re-exports, for example `pub(crate) use self::item as |
| 136 | + alias;`. rustc rejects the re-export of a private item. |
| 137 | + |
| 138 | +- `cargo fallow visibility` reads more forms of intra-doc links: a `Self::` |
| 139 | + path (also in the documentation of a field or a variant), a turbofish such |
| 140 | + as `Gen::<u8>::new`, an indented paragraph, and an included file with a |
| 141 | + path from `env!("CARGO_MANIFEST_DIR")` or from more than one `concat!` |
| 142 | + literal. |
| 143 | +- `cargo fallow visibility` no longer reports a type that macro tokens name |
| 144 | + when the macro can write a `pub` item: the tokens hold `pub` or a `vis` |
| 145 | + fragment. |
| 146 | + |
| 147 | +- `cargo fallow fix` leaves out an edit that adds a compiler warning, the same |
| 148 | + as an edit that adds an error. Before, a workspace that builds with |
| 149 | + `-D warnings` could break after `fix` exited 0. A new `dead_code` warning |
| 150 | + does not count, because a `dead-public` edit shows the dead code on |
| 151 | + purpose. |
| 152 | + |
| 153 | +- The GitHub Action fails the step when `base: auto` cannot read the base |
| 154 | + commit and the command needs the base for a gate (`check`, `size` and |
| 155 | + `mutants`). Before, the action wrote a notice and ran with no base, so the |
| 156 | + growth gate passed without a check. A run with no pull request base and no |
| 157 | + push stays a notice. |
| 158 | + |
| 159 | +- The description of the GitHub Action now has fewer than 125 characters, so |
| 160 | + the GitHub Marketplace accepts the action. |
| 161 | + |
| 162 | +- The GitHub Action and the GitLab template no longer post a first pull |
| 163 | + request comment or merge request note for a clean run. A clean run still |
| 164 | + updates an old comment, and an unchanged comment gets no update. |
| 165 | + |
| 166 | +### Performance |
| 167 | + |
| 168 | +- `cargo fallow check` parses each file one time for the module graph and the |
| 169 | + `files` check. Before, the `files` check read and parsed each file a second |
| 170 | + time. On a large workspace, the run uses about 14% less CPU time. The output |
| 171 | + does not change. |
| 172 | + |
| 173 | +- The bracket scan of intra-doc links is linear in the length of the text. A |
| 174 | + text with many open brackets no longer takes seconds. |
| 175 | + |
| 176 | +- The memory of `cargo fallow visibility` now grows about linearly with the |
| 177 | + source size. A field access, a method call or a name in macro tokens gave |
| 178 | + one credit to each item with the name, so a generated file with many fields |
| 179 | + of one name needed memory for each pair. Each name now keeps its items once. |
| 180 | + On a generated 5 MB file, the peak memory goes from 8.9 GB to 1.5 GB, and |
| 181 | + the time from 33 s to 1.5 s. |
| 182 | + |
14 | 183 | ## [0.1.0] - 2026-11-04 |
15 | 184 |
|
16 | 185 | ### Added |
|
0 commit comments