Ignorelint::Pattern
Inherits Struct < Value < Object
Constructors
Parse a single raw line into its semantic components.
The decomposition order matters:
- Strip trailing
\n/\r(file read artifacts) - Detect
!prefix →negated - Detect trailing
/→directory_only - Detect leading
/→rooted - Strip escape backslashes →
body
Each step peels off the detected flag from remaining so the next step
only sees what is left.
Instance methods
True for blank (empty or whitespace-only) lines. Blank lines separate groups visually but carry no pattern meaning.
The semantic core of the pattern: escape sequences removed, ! / /
flags stripped. This is what the linter inspects for glob validity,
duplicate detection, and filesystem matching.
True for comment lines (start with # after optional whitespace).
Note: in gitignore, # is only a comment marker at the start of a line;
a # mid-pattern is treated as a literal character (and flagged by
has_unescaped_hash?).
Does this pattern (as an ignore) conflict with a later negation? A pattern P and a negation !P cancel each other.
Scope flags participate: /build vs !build (rooted vs unrooted)
and build/ vs !build (directory-only vs either) match different
sets, so they are not exact cancels.
Used by Checks::Conflicts to detect redundant pairs like
"build" followed by "!build".
More than two consecutive asterisks (*** or more).
Gitignore only recognizes * (any chars except /) and ** (any
chars including /). Three or more is almost certainly a typo.
true when the line ends with / — the pattern only matches directories,
not files. In .dockerignore this distinction is meaningless because
Docker strips trailing slashes before matching.
Detect !! at the start of a line (after leading whitespace).
Double negation cancels out — "!!foo" is equivalent to "foo".
Detect an empty pattern after decomposition (no body text).
Lines like "!", "!/" or "/" carry flags but no pattern text.
Detect // in the pattern body. Double slashes usually indicate a typo
(e.g. "src//dist" instead of "src/dist"). Gitignore does treat //
as a single /, so this is informational, not an error.
Detect leading spaces or tabs before the pattern. In gitignore, leading
whitespace is not stripped — the pattern " foo" does not match "foo".
Detect trailing spaces or tabs that are invisible in most editors but
affect matching behavior. The \ (backslash-space) escape is excluded
because it is an intentional escaped space, not accidental whitespace.
Detect an unescaped # inside the pattern body.
In gitignore, # starts a comment only at the beginning of a line. A
# mid-pattern (e.g. "file#1.txt") is technically a literal, but
most users do not realize this and may intend it as a comment delimiter.
The check skips lines that are already comments.
The algorithm walks character-by-character tracking the escape state:
\\togglesin_escape#while not escaped → unescaped hash found- any other character resets
in_escape
** used incorrectly: not between / separators.
In gitignore, ** is only valid in these positions:
a/**/b— matches zero or more directories betweenaandb**/a— matchesaat any deptha/**— matches everything insidea/
Invalid: a**b, **a, a** (not at segment boundary).
The check splits the pattern on / and ensures any segment containing
** is exactly "**" — no extra characters.
1-based line number in the source file. Used to report issue locations.
True when the body contains no UNESCAPED glob metacharacters (*, ?, [) and the pattern is not negated — i.e. it names a concrete path.
Scans the raw line (skipping \-escaped chars) so an escaped \*
counts as a literal asterisk, not a glob.
Used by filesystem checks to decide whether to test File.exists?
(for literal patterns) vs. Dir.glob (for glob patterns).
Malformed bracket expression: unclosed [ or empty [].
Bracket expressions like [abc] match a single character from the set.
Common mistakes:
- Unclosed:
[abc— missing closing bracket - Empty:
[]— no characters to match - Nested:
[a[b]— brackets inside brackets
Runs on the raw line with escape awareness: an escaped \[ is a
literal bracket, not an expression opener.
true when the line starts with ! — a negation pattern that
re-includes previously excluded files. Not all ignore formats support
negation (e.g. .slugignore does not).
! followed by / — anchoring has no effect on negation.
In gitignore, a leading / anchors a pattern to the ignore file's
directory. But negation patterns (!) are already resolved relative to
that directory, so adding / to a negation is misleading.
Normalized form for duplicate/conflict comparison: escape-stripped
body, trimmed. Case-sensitive: ignore files are (e.g. "Build" and
"build" match different files on case-sensitive filesystems).
The original raw text from the file (with leading ! and trailing /
intact). Used in error messages so the user sees exactly what they wrote.
true when the pattern starts with / (after removing !) — it is
"rooted" / "anchored" to the directory containing the ignore file.
Without a leading /, the pattern matches at any depth.
Pattern contains a leading slash that anchors to root but is followed by no path separators — it only matches at the top level. Often a mistake when the user wanted to match anywhere.
Example: "/build" matches only ./build, not ./src/build.
The user likely meant "build" (matches at any depth).