Class: Everywhere::Ignore
- Inherits:
-
Object
- Object
- Everywhere::Ignore
- Defined in:
- lib/everywhere/ignore.rb
Overview
Shared source-exclusion rules, read from .everywhereignore (dockerignore
style) when present, else a sensible default. ONE source of truth so the
build receipt's source checksum (Receipt) and the Platform snapshot
(every platform build, later) describe exactly the same set of files — a
checksum that didn't match what actually ships would be worse than none.
Pattern semantics are a pragmatic subset of .dockerignore/.gitignore:
dist → a path segment named "dist", anywhere
vendor/bundle → that exact path (and everything under it)
*.log → glob against the full path and the basename
!keep/this.log → NEGATION: re-include a file an earlier pattern excluded
Rules are evaluated top to bottom and the LAST one that matches a path wins
(dockerignore semantics), so ordering matters: put ! re-includes after the
broad exclude they carve out of.
Constant Summary collapse
- FILE =
".everywhereignore"- FLAGS =
File::FNM_PATHNAME | File::FNM_DOTMATCH
- DEFAULTS =
Build products, caches, VCS, local state, and secrets. Excluding
.env*and the key/cert family keeps signing material out of both the checksum and any future snapshot. %w[ dist tmp log node_modules .git storage .bundle vendor/bundle coverage public/assets public/packs .DS_Store .env* *.log *.key *.pem *.crt *.p12 *.mobileprovision ].freeze
Instance Attribute Summary collapse
-
#rules ⇒ Object
readonly
Returns the value of attribute rules.
Class Method Summary collapse
- .for(root) ⇒ Object
-
.parse(text) ⇒ Object
→ [{ negated:, pattern: }, ...] in file order.
Instance Method Summary collapse
-
#files(root) ⇒ Object
Every non-ignored regular file under root, as sorted root-relative paths.
-
#ignored?(rel) ⇒ Boolean
Last matching rule wins; a negated match re-includes.
-
#initialize(rules) ⇒ Ignore
constructor
A new instance of Ignore.
Constructor Details
#initialize(rules) ⇒ Ignore
Returns a new instance of Ignore.
53 54 55 |
# File 'lib/everywhere/ignore.rb', line 53 def initialize(rules) @rules = rules end |
Instance Attribute Details
#rules ⇒ Object (readonly)
Returns the value of attribute rules.
51 52 53 |
# File 'lib/everywhere/ignore.rb', line 51 def rules @rules end |
Class Method Details
.for(root) ⇒ Object
32 33 34 35 36 |
# File 'lib/everywhere/ignore.rb', line 32 def self.for(root) path = File.join(root, FILE) source = File.exist?(path) ? File.read(path) : DEFAULTS.join("\n") new(parse(source)) end |
.parse(text) ⇒ Object
→ [{ negated:, pattern: }, ...] in file order. Blank lines and whole-line
# comments are dropped; a leading ! marks a re-include.
40 41 42 43 44 45 46 47 48 49 |
# File 'lib/everywhere/ignore.rb', line 40 def self.parse(text) text.lines.filter_map do |raw| line = raw.chomp next if line.strip.empty? || line.lstrip.start_with?("#") negated = line.start_with?("!") pattern = (negated ? line[1..] : line).strip.sub(%r{\A/}, "").chomp("/") { negated: negated, pattern: pattern } unless pattern.empty? end end |
Instance Method Details
#files(root) ⇒ Object
Every non-ignored regular file under root, as sorted root-relative paths.
58 59 60 61 62 63 |
# File 'lib/everywhere/ignore.rb', line 58 def files(root) Dir.glob("**/*", File::FNM_DOTMATCH, base: root) .reject { |rel| ignored?(rel) } .select { |rel| File.file?(File.join(root, rel)) } .sort end |
#ignored?(rel) ⇒ Boolean
Last matching rule wins; a negated match re-includes. Default: kept.
66 67 68 69 70 71 72 73 |
# File 'lib/everywhere/ignore.rb', line 66 def ignored?(rel) base = rel.split("/").last return true if [".", ".."].include?(base) @rules.reduce(false) do |ignored, rule| match?(rule[:pattern], rel, base) ? !rule[:negated] : ignored end end |