Skip to content

ordered_block

The lines between a start / end marker pair must stay sorted (and, with unique: true, free of duplicates) under comparator (lexical / lexical-ci / numeric). Both markers are optional: omit end to sort from start to EOF, omit both to sort the whole file (the markerless "this file is one sorted list" form — dictionaries, allow-lists, a fully-sorted CODEOWNERS). The generic form of per-project keep-sorted scripts (protobuf failure_lists, sorted .gitignore / CODEOWNERS / dependency lists). Per-file: with markers, a file with no start marker is silently fine; markers match the trimmed line; blank lines inside a block are ignored; one violation per out-of-order block; a fully-delimited block that never sees its end is reported unclosed (a block with an absent end runs to EOF by design). An optional select: regex restricts the sortable entries to lines matching it — other lines inside the block (comments, group headers) pass through untouched (the sectioned / keep-sorted-subset shape).

Optional require: — a list of exact lines the block must CONTAIN (in addition to being sorted), for the "a managed sorted list must have these entries" shape (a CODEOWNERS, an allow-list). Currently markerless-only (omit start/end; a marker makes the insert target ambiguous). A missing one is a separate, independently-fixable finding. Presence is exact-string (trimmed), independent of comparator — under lexical-ci, requiring bravo is not satisfied by an existing Bravo (the case-variant is inserted). A required line that could never round-trip to an entry is refused at load: one that carries an embedded line break, or (with select: set) one that does not itself match select:.

Fix: sort — reorder each block's entries under the rule's comparator (dropping duplicates when unique), reusing the rule's own start / end / comparator / unique / select so the fix reorders exactly what the check flags; markers, blank lines, and select-excluded lines stay in place, and every line keeps its terminator (LF vs CRLF) and the file its trailing-newline state. Safe by default (a keep-sorted block is order-independent). The unclosed finding is not sort-fixable — sort cannot invent a missing end marker — so it is reported but not advertised as auto-fixable.

Fix: insert_line — splice a missing require: line at its SORTED position (using the comparator), preserving every other line's terminator and the file's trailing-newline state. The differentiator over file_append (which only appends at EOF), for order-sensitive lists. Unsafe by default: it adds ruleset-authored content at a COMPUTED position, and position is load-bearing in exactly the order-sensitive formats it targets (a .gitignore negation only works AFTER the pattern it re-includes), so a mis-placed insert can silently change file meaning. A bare fix therefore SUGGESTS it; --unsafe-fixes, or a per-rule applicability: safe for an order-tolerant list such as CODEOWNERS, applies it. Also demoted to a suggestion from an untrusted remote extends: (the require: lines are ruleset-authored). It fixes only the missing-required-line findings — an out-of-order entry is sort's job, so pair two rules (sort + insert_line) for a fully-managed list. With no fix declared, violations are unfixable.

OptionTypeRequiredDefaultDescription
comparatorone of lexical | lexical-ci | numericlexicalComparator used to order entries: lexical (default), lexical-ci, or numeric.
endstringnullMarker line closing a block. Optional - omit to run the block to EOF.
requirelist of stringnullExact lines that must be PRESENT in the block (in addition to it being sorted). A missing one is repaired by the insert_line fix, which splices it at its sorted position. Currently supported only for a MARKERLESS rule (the whole file is one sorted list -- the CODEOWNERS / allow-list shape). Presence is EXACT-string (trimmed), independent of comparator: under lexical-ci, requiring bravo is NOT satisfied by an existing Bravo (the distinct case-variant is inserted) -- a required line is inserted verbatim, so it must match itself exactly. For the same reason, with select: set every required line must itself match select: (else the inserted line could never be recognized as an entry); a non-matching line is rejected at load.
selectstringnullRegex; when set, only lines inside a block matching it are sortable entries (others, such as comments or group headers, pass through). The sectioned / keep-sorted-subset shape.
startstringnullMarker line opening a block (matched on the trimmed line). Optional - omit to anchor the block at the start of the file.
uniquebooleanfalseWhen true, also forbid duplicate (equal) entries within a block.

Plus the common paths, level, id, when, scope_filter, fix, and expect_matches fields. This table is generated from the JSON Schema; option types and defaults are authoritative.

A keep-sorted block left out of order

Section titled "A keep-sorted block left out of order"

The rule fires on this repository:

  • .gitignore

    ⚠ warning keep-sorted

    5:1 ordered_block (start at line 2): "*.tmp" is out of order (it comes after "node_modules/")

.gitignore
/target
# keep-sorted start
*.log
node_modules/
*.tmp
# keep-sorted end

With this .alint.yml:

version: 1
rules:
- id: keep-sorted
kind: ordered_block
paths: "**/.gitignore"
start: "# keep-sorted start"
end: "# keep-sorted end"
comparator: lexical
level: warning

alint check reports:

Terminal window
--- .gitignore -----------------------------------------------------------------
! warning keep-sorted
5:1 ordered_block (start at line 2): "*.tmp" is out of order (it comes
after "node_modules/")
Summary (1 violation):
! 1 warning
0 passing * 1 failing

A keep-sorted block in lexical order

Section titled "A keep-sorted block in lexical order"

This repository is compliant:

  • .gitignore✓
.gitignore
/target
# keep-sorted start
*.log
*.tmp
node_modules/
# keep-sorted end

With this .alint.yml:

version: 1
rules:
- id: keep-sorted
kind: ordered_block
paths: "**/.gitignore"
start: "# keep-sorted start"
end: "# keep-sorted end"
comparator: lexical
level: warning

alint check reports:

Terminal window
v All 1 rule(s) passed.