Noir::ExcludePath
Compiled --exclude-path patterns, and the single implementation of
what they mean.
The option used to be spelled out inline in the detector's walk
(src/detector/detector.cr), which is the only place that sees every
file — so it protected exactly the analyzers that take their file set
from CodeLocator. The six adapters that enumerate the filesystem
themselves (Spring/Quarkus static resources, Dropwizard config, the Go
static-dir resolver, the Android/iOS resource walks) never went through
it and happily reported files the user had excluded. Analyzer#excluded_path?
applies this to them, which is only correct as long as both sides agree
on what a pattern means — hence one type, used by both.
Pattern semantics (as in .gitignore, a pattern that matches a
directory excludes everything under it):
- a pattern containing
/is a glob over the path relative to the scan base of the file or any directory above it:tests/*andsrc/legacyboth droptests/unit/a.js/src/legacy/x/y.go; - a pattern without
/is a glob over the name of the file or of any directory above it:*.test.jsdrops test files,testsdrops everytests/directory at any depth; - a leading
./on a path pattern is dropped, since the path it is compared against never carries one:./tests/**meanstests/**. It is dropped after the classification above, so./app.jsstays a path pattern for the file at the base rather than becoming a basename pattern for everyapp.js; - on macOS/Windows the comparison folds case, because their default filesystems do. Folding on Linux would wrongly drop case-distinct files that legitimately coexist.
Constants
Mirrors the detector's original exclude_case_insensitive.
Constructors
Class methods
./tests → tests, ././tests → tests, and the gitignore-style
anchored /tests → tests (the candidate path loses its leading /
too, so an anchored pattern otherwise matched nothing). A pattern that
is nothing but ./ is left alone: stripping it would leave an empty
pattern.
Instance methods
True when the user supplied at least one usable pattern. Callers
should check this before computing a relative path per file — with no
--exclude-path there is nothing to compute it for.
relative_path is the file's location relative to the scan base that
owns it. A leading / is accepted (that is the shape
Analyzer#base_relative_path returns) and ignored, so both callers
can hand over their own spelling.
Raises File::BadPatternError on a malformed glob, which the
detector converts into Noir::InvalidExcludePathError — a bad
pattern must stop the scan rather than silently exclude nothing.