Skip to content

for_each_file

For every matching directory / file, evaluate a nested require: block with the entry as context. Template tokens ({dir}, {stem}, {ext}, {basename}, {path}, {parent_name}) expand against each match. select: is a single glob or a list with !-prefixed excludes (e.g. ["src/*", "!src/internal"]).

when_iter: — per-iteration filter. Optional expression in the when: grammar, with one extra namespace: iter.* references the entry currently being iterated. Iterations whose verdict is false are skipped before any nested rule is built — the canonical use case for monorepos shaped like Cargo / pnpm / Bazel workspaces:

The iter namespace exposes:

ReferenceTypeNotes
iter.pathstringRelative path of the iterated entry.
iter.basenamestringBasename.
iter.parent_namestringParent dir name.
iter.stemstringBasename minus the final extension (mainly useful for files).
iter.extstringFinal extension without the dot.
iter.is_dirboolTrue for for_each_dir, false for for_each_file; always available.
iter.has_file(pattern)boolGlob match relative to the iterated dir. iter.has_file("Cargo.toml"), iter.has_file("**/*.bzl"). Always false for file iteration.

when_iter: composes with the rule’s outer when: (whole-rule gate, evaluated once) and with each nested rule’s when: (which now also sees the same iter.* context). Same field is available on for_each_file and every_matching_has.

OptionTypeRequiredDefaultDescription
requirelist of nested ruleyesNested rules evaluated against each matched file.
selectstring or list of stringyesGlob(s) selecting the files to iterate - a single glob, or a list with !-prefixed excludes.
when_iterstringPer-iteration when: filter - see rule_for_each_dir.when_iter. iter.has_file(...) always evaluates to false on file iteration; useful predicates here include iter.basename, iter.ext, iter.parent_name.

Plus the common level, id, and when fields. This rule analyses the whole repository, so it takes no paths. This table is generated from the JSON Schema; option types and defaults are authoritative.

The rule fires on this repository:

tests/
tests/snapshots/
tests/snapshots/parser.snap
tests/unit/
tests/unit/lexer.rs
tests/unit/parser.rs
tests/snapshots/parser.snap
output
tests/unit/lexer.rs
fn t2() {}
tests/unit/parser.rs
fn t1() {}

With this .alint.yml:

version: 1
rules:
- id: unit-has-snapshot
kind: for_each_file
select: "tests/unit/*.rs"
require:
- kind: file_exists
paths: "tests/snapshots/{stem}.snap"
level: warning

alint check reports:

Terminal window
--- tests/unit/lexer.rs --------------------------------------------------------
! warning unit-has-snapshot
expected a file matching [tests/snapshots/lexer.snap]
Summary (1 violation):
! 1 warning
0 passing * 1 failing

This repository is compliant:

tests/
tests/snapshots/
tests/snapshots/lexer.snap
tests/snapshots/parser.snap
tests/unit/
tests/unit/lexer.rs
tests/unit/parser.rs

With this .alint.yml:

version: 1
rules:
- id: unit-has-snapshot
kind: for_each_file
select: "tests/unit/*.rs"
require:
- kind: file_exists
paths: "tests/snapshots/{stem}.snap"
level: warning

alint check reports:

Terminal window
v All 1 rule(s) passed.