Module: Ace::Review::Molecules::ExemptPaths
- Defined in:
- lib/ace/review/molecules/exempt_paths.rb
Overview
Review-exempt paths: globs whose deltas never require a model report.
A delta round whose changed files all match the declared patterns is recorded as a no-op session without any model call; in mixed rounds the exempt paths are excluded from the subject and enumerated. Patterns are validated at config load — a pattern that matches every path is refused instead of silently exempting the world.
Constant Summary collapse
- OVER_BROAD_PROBES =
Probe set covering root-level and nested paths. A pattern matching every probe leaves nothing reviewable by definition. Dotfiles are excluded: wildcard patterns never match them under fnmatch pathname semantics (no FNM_DOTMATCH), so they cannot prove over-breadth.
["README.md", "a.txt", "dir/b.txt", "a/b/c.txt"].freeze
- CONVENTIONAL_MATCH_ALL =
Conventional spellings authors use for "everything". fnmatch pathname semantics make bare "*" / "**" single-segment, but their intent is unmistakable — refuse them instead of silently exempting the world.
["*", "**"].freeze
Class Method Summary collapse
-
.classify(paths, patterns) ⇒ Hash
Partition changed paths (destination paths, as in the diff manifest) into exempt and non-exempt.
-
.validate!(patterns) ⇒ String?
Refusal message, or nil when valid.
Class Method Details
.classify(paths, patterns) ⇒ Hash
Partition changed paths (destination paths, as in the diff manifest) into exempt and non-exempt.
51 52 53 54 55 56 57 |
# File 'lib/ace/review/molecules/exempt_paths.rb', line 51 def self.classify(paths, patterns) patterns = Array(patterns) exempt, non_exempt = Array(paths).partition do |path| patterns.any? { |pattern| SubjectFilter.glob_match?(pattern, path) } end {exempt: exempt, non_exempt: non_exempt} end |
.validate!(patterns) ⇒ String?
Returns refusal message, or nil when valid.
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/ace/review/molecules/exempt_paths.rb', line 29 def self.validate!(patterns) return nil if patterns.nil? unless patterns.is_a?(Array) && patterns.all? { |pattern| pattern.is_a?(String) && !pattern.strip.empty? } return "exempt_paths must be a list of non-empty glob strings" end patterns.each do |pattern| if CONVENTIONAL_MATCH_ALL.include?(pattern) || OVER_BROAD_PROBES.all? { |probe| SubjectFilter.glob_match?(pattern, probe) } return "exempt_paths pattern '#{pattern}' matches every path; refusing to exempt the world" end end nil end |