Rulebearing Playground Coverage Schemas GitHub

ADR-0052: --affected follows the configuration format: dependency-cruiser's reaches filter, or the closure

Context

The plan describes --affected as "the changed files and their dependents to depth N, then evaluate the rules over the closure". dependency-cruiser 18.2.0 does something narrower. Its normalizeOptions asks watskeburt 6.0.0 for the changed files (git diff <revision> --name-status, plus the untracked files of git status --porcelain), turns the ones with its seventeen extensions into a regular expression, and sets reaches to it. filterReaches then keeps the matching modules and every module that reaches them, and only the edges between kept modules; the summary is recomputed from what is kept.

Measured on 2026-09-27 on a scratch repository with the pinned upstream binary (one modified file that imports a forbidden module and closes a cycle, a staged new file, an untracked file, a deleted file, a staged rename, an untouched violation):

  1. The forbidden edge from the modified file to an unchanged module is not reported, because the unchanged module does not reach a changed one.
  2. The deleted file is not in the expression; renamed and copied files count by their new name.
  3. A new file inside a new, untracked folder is not seen: git status --porcelain lists the folder, which has no extension.
  4. Run from a subdirectory, the expression holds repository-relative paths while module names are relative to the subdirectory, so nothing matches and the report is empty, exit 0.
  5. affected in a configuration file is ignored ("a command line only option"), and affected is not in optionsUsed.
  6. The err reporter exits with the error count of the filtered report (4), not of the whole graph (6).

Decision

The semantics follow the configuration format, as liveness does (ADR-0032): a dependency-cruiser configuration, or none, gets dependency-cruiser's behaviour; a rulebearing.* configuration, which has no upstream to match, gets the closure the plan describes.

With a dependency-cruiser configuration

With a rulebearing.* configuration

Both

Consequences

Alternatives considered