fast_ignore 0.17.0 → 0.17.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +19 -0
  3. data/README.md +0 -13
  4. data/lib/fast_ignore/builders/gitignore.rb +15 -0
  5. data/lib/fast_ignore/builders/shebang.rb +17 -0
  6. data/lib/fast_ignore/builders/shebang_or_gitignore.rb +15 -0
  7. data/lib/fast_ignore/candidate.rb +85 -0
  8. data/lib/fast_ignore/gitconfig_parser.rb +3 -4
  9. data/lib/fast_ignore/gitignore_include_rule_builder.rb +40 -67
  10. data/lib/fast_ignore/gitignore_rule_builder.rb +66 -27
  11. data/lib/fast_ignore/gitignore_rule_group.rb +31 -0
  12. data/lib/fast_ignore/gitignore_rule_scanner.rb +24 -4
  13. data/lib/fast_ignore/matchers/allow_any_dir.rb +39 -0
  14. data/lib/fast_ignore/matchers/allow_path_regexp.rb +45 -0
  15. data/lib/fast_ignore/matchers/ignore_path_regexp.rb +45 -0
  16. data/lib/fast_ignore/matchers/shebang_regexp.rb +46 -0
  17. data/lib/fast_ignore/matchers/unmatchable.rb +31 -0
  18. data/lib/fast_ignore/matchers/within_dir.rb +50 -0
  19. data/lib/fast_ignore/path_expander.rb +11 -0
  20. data/lib/fast_ignore/path_regexp_builder.rb +130 -0
  21. data/lib/fast_ignore/patterns.rb +33 -0
  22. data/lib/fast_ignore/relative_candidate.rb +20 -0
  23. data/lib/fast_ignore/rule_group.rb +42 -0
  24. data/lib/fast_ignore/rule_groups.rb +55 -0
  25. data/lib/fast_ignore/version.rb +1 -1
  26. data/lib/fast_ignore/walkers/base.rb +26 -0
  27. data/lib/fast_ignore/walkers/file_system.rb +46 -0
  28. data/lib/fast_ignore/walkers/gitignore_collecting_file_system.rb +48 -0
  29. data/lib/fast_ignore.rb +54 -91
  30. metadata +36 -11
  31. data/lib/fast_ignore/backports.rb +0 -66
  32. data/lib/fast_ignore/file_root.rb +0 -39
  33. data/lib/fast_ignore/gitignore_rule_regexp_builder.rb +0 -76
  34. data/lib/fast_ignore/rule.rb +0 -65
  35. data/lib/fast_ignore/rule_builder.rb +0 -41
  36. data/lib/fast_ignore/rule_set.rb +0 -76
  37. data/lib/fast_ignore/rule_sets.rb +0 -113
  38. data/lib/fast_ignore/shebang_rule.rb +0 -80
  39. data/lib/fast_ignore/unmatchable_rule.rb +0 -41
data/lib/fast_ignore.rb CHANGED
@@ -1,78 +1,56 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative './fast_ignore/backports'
4
-
5
3
  require 'set'
6
4
  require 'strscan'
7
5
 
8
6
  class FastIgnore
9
7
  class Error < StandardError; end
10
8
 
11
- require_relative './fast_ignore/rule_sets'
12
- require_relative './fast_ignore/rule_set'
13
- require_relative './fast_ignore/global_gitignore'
14
- require_relative './fast_ignore/rule_builder'
15
- require_relative './fast_ignore/gitignore_rule_builder'
16
- require_relative './fast_ignore/gitignore_include_rule_builder'
17
- require_relative './fast_ignore/gitignore_rule_regexp_builder'
18
- require_relative './fast_ignore/gitignore_rule_scanner'
19
- require_relative './fast_ignore/file_root'
20
- require_relative './fast_ignore/rule'
21
- require_relative './fast_ignore/unmatchable_rule'
22
- require_relative './fast_ignore/shebang_rule'
23
- require_relative './fast_ignore/gitconfig_parser'
9
+ require_relative 'fast_ignore/rule_groups'
10
+ require_relative 'fast_ignore/global_gitignore'
11
+ require_relative 'fast_ignore/gitignore_rule_builder'
12
+ require_relative 'fast_ignore/gitignore_include_rule_builder'
13
+ require_relative 'fast_ignore/path_regexp_builder'
14
+ require_relative 'fast_ignore/gitignore_rule_scanner'
15
+ require_relative 'fast_ignore/rule_group'
16
+ require_relative 'fast_ignore/matchers/unmatchable'
17
+ require_relative 'fast_ignore/matchers/shebang_regexp'
18
+ require_relative 'fast_ignore/gitconfig_parser'
19
+ require_relative 'fast_ignore/path_expander'
20
+ require_relative 'fast_ignore/candidate'
21
+ require_relative 'fast_ignore/relative_candidate'
22
+ require_relative 'fast_ignore/matchers/within_dir'
23
+ require_relative 'fast_ignore/matchers/allow_any_dir'
24
+ require_relative 'fast_ignore/matchers/allow_path_regexp'
25
+ require_relative 'fast_ignore/matchers/ignore_path_regexp'
26
+ require_relative 'fast_ignore/patterns'
27
+ require_relative 'fast_ignore/walkers/base'
28
+ require_relative 'fast_ignore/walkers/file_system'
29
+ require_relative 'fast_ignore/walkers/gitignore_collecting_file_system'
30
+ require_relative 'fast_ignore/gitignore_rule_group'
31
+ require_relative 'fast_ignore/builders/shebang'
32
+ require_relative 'fast_ignore/builders/gitignore'
33
+ require_relative 'fast_ignore/builders/shebang_or_gitignore'
24
34
 
25
35
  include ::Enumerable
26
36
 
27
- # :nocov:
28
- using ::FastIgnore::Backports::DeletePrefixSuffix if defined?(::FastIgnore::Backports::DeletePrefixSuffix)
29
- using ::FastIgnore::Backports::DirEachChild if defined?(::FastIgnore::Backports::DirEachChild)
30
- # :nocov:
31
-
32
- def initialize(relative: false, root: nil, gitignore: :auto, follow_symlinks: false, **rule_set_builder_args)
33
- @relative = relative
34
- @follow_symlinks_method = ::File.method(follow_symlinks ? :stat : :lstat)
35
- @gitignore_enabled = gitignore
36
- @loaded_gitignore_files = ::Set[''] if gitignore
37
+ def initialize(relative: false, root: nil, gitignore: :auto, follow_symlinks: false, **rule_group_builder_args)
37
38
  @root = "#{::File.expand_path(root.to_s, Dir.pwd)}/"
38
- @rule_sets = ::FastIgnore::RuleSets.new(root: @root, gitignore: gitignore, **rule_set_builder_args)
39
-
40
- freeze
41
- end
42
-
43
- def each(&block)
44
- return enum_for(:each) unless block_given?
45
-
46
- dir_pwd = ::Dir.pwd
47
- root_from_pwd = @root.start_with?(dir_pwd) ? ".#{@root.delete_prefix(dir_pwd)}" : @root
48
-
49
- each_recursive(root_from_pwd, '', &block)
39
+ @gitignore = gitignore
40
+ @rule_group_builder_args = rule_group_builder_args
41
+ @follow_symlinks = follow_symlinks
42
+ @relative = relative
50
43
  end
51
44
 
52
- def allowed?(path, directory: nil, content: nil, exists: nil, include_directories: false) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
53
- full_path = ::File.expand_path(path, @root)
54
- return false unless full_path.start_with?(@root)
55
-
56
- begin
57
- directory = directory.nil? ? @follow_symlinks_method.call(full_path).directory? : directory
58
- rescue ::Errno::ENOENT, ::Errno::EACCES, ::Errno::ENOTDIR, ::Errno::ELOOP, ::Errno::ENAMETOOLONG
59
- exists = false if exists.nil?
60
- directory = false
61
- end
62
-
63
- return false if !include_directories && directory
64
-
65
- exists = exists.nil? ? ::File.exist?(full_path) : exists
66
-
67
- return false unless exists
68
-
69
- relative_path = full_path.delete_prefix(@root)
70
- load_gitignore_recursive(relative_path) if @gitignore_enabled
71
-
72
- filename = ::File.basename(relative_path)
73
- content = content.slice(/.*/) if content # we only care about the first line
74
-
75
- @rule_sets.allowed_recursive?(relative_path, directory, full_path, filename, content)
45
+ def allowed?(path, directory: nil, content: nil, exists: nil, include_directories: false)
46
+ walker.allowed?(
47
+ path,
48
+ root: @root,
49
+ directory: directory,
50
+ content: content,
51
+ exists: exists,
52
+ include_directories: include_directories
53
+ )
76
54
  end
77
55
  alias_method :===, :allowed?
78
56
 
@@ -80,43 +58,28 @@ class FastIgnore
80
58
  method(:allowed?).to_proc
81
59
  end
82
60
 
83
- private
61
+ def each(&block)
62
+ return enum_for(:each) unless block
84
63
 
85
- def load_gitignore_recursive(path)
86
- paths = []
87
- while (path = ::File.dirname(path)) != '.'
88
- paths << path
89
- end
64
+ prefix = @relative ? '' : @root
90
65
 
91
- paths.reverse_each { |p| load_gitignore(p) }
66
+ walker.each(@root, prefix, &block)
92
67
  end
93
68
 
94
- def load_gitignore(parent_path, check_exists: true)
95
- return if @loaded_gitignore_files.include?(parent_path)
69
+ def build
70
+ rule_groups = ::FastIgnore::RuleGroups.new(root: @root, gitignore: @gitignore, **@rule_group_builder_args)
96
71
 
97
- @rule_sets.append_subdir_gitignore(relative_path: parent_path + '.gitignore', check_exists: check_exists)
72
+ walker_class = @gitignore ? ::FastIgnore::Walkers::GitignoreCollectingFileSystem : ::FastIgnore::Walkers::FileSystem
73
+ @walker = walker_class.new(rule_groups, follow_symlinks: @follow_symlinks)
98
74
 
99
- @loaded_gitignore_files << parent_path
75
+ freeze
100
76
  end
101
77
 
102
- def each_recursive(parent_full_path, parent_relative_path, &block) # rubocop:disable Metrics/MethodLength
103
- children = ::Dir.children(parent_full_path)
104
- load_gitignore(parent_relative_path, check_exists: false) if @gitignore_enabled && children.include?('.gitignore')
105
-
106
- children.each do |filename|
107
- full_path = parent_full_path + filename
108
- relative_path = parent_relative_path + filename
109
- dir = @follow_symlinks_method.call(full_path).directory?
110
-
111
- next unless @rule_sets.allowed_unrecursive?(relative_path, dir, full_path, filename)
112
-
113
- if dir
114
- each_recursive(full_path + '/', relative_path + '/', &block)
115
- else
116
- yield(@relative ? relative_path : @root + relative_path)
117
- end
118
- rescue ::Errno::ENOENT, ::Errno::EACCES, ::Errno::ENOTDIR, ::Errno::ELOOP, ::Errno::ENAMETOOLONG
119
- nil
120
- end
78
+ private
79
+
80
+ def walker
81
+ build unless defined?(@walker)
82
+
83
+ @walker
121
84
  end
122
85
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fast_ignore
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.17.0
4
+ version: 0.17.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dana Sherson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-03-03 00:00:00.000000000 Z
11
+ date: 2022-04-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -100,6 +100,20 @@ dependencies:
100
100
  - - "<"
101
101
  - !ruby/object:Gem::Version
102
102
  version: '1.12'
103
+ - !ruby/object:Gem::Dependency
104
+ name: rubocop-performance
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
103
117
  - !ruby/object:Gem::Dependency
104
118
  name: rubocop-rake
105
119
  requirement: !ruby/object:Gem::Requirement
@@ -181,21 +195,32 @@ files:
181
195
  - LICENSE.txt
182
196
  - README.md
183
197
  - lib/fast_ignore.rb
184
- - lib/fast_ignore/backports.rb
185
- - lib/fast_ignore/file_root.rb
198
+ - lib/fast_ignore/builders/gitignore.rb
199
+ - lib/fast_ignore/builders/shebang.rb
200
+ - lib/fast_ignore/builders/shebang_or_gitignore.rb
201
+ - lib/fast_ignore/candidate.rb
186
202
  - lib/fast_ignore/gitconfig_parser.rb
187
203
  - lib/fast_ignore/gitignore_include_rule_builder.rb
188
204
  - lib/fast_ignore/gitignore_rule_builder.rb
189
- - lib/fast_ignore/gitignore_rule_regexp_builder.rb
205
+ - lib/fast_ignore/gitignore_rule_group.rb
190
206
  - lib/fast_ignore/gitignore_rule_scanner.rb
191
207
  - lib/fast_ignore/global_gitignore.rb
192
- - lib/fast_ignore/rule.rb
193
- - lib/fast_ignore/rule_builder.rb
194
- - lib/fast_ignore/rule_set.rb
195
- - lib/fast_ignore/rule_sets.rb
196
- - lib/fast_ignore/shebang_rule.rb
197
- - lib/fast_ignore/unmatchable_rule.rb
208
+ - lib/fast_ignore/matchers/allow_any_dir.rb
209
+ - lib/fast_ignore/matchers/allow_path_regexp.rb
210
+ - lib/fast_ignore/matchers/ignore_path_regexp.rb
211
+ - lib/fast_ignore/matchers/shebang_regexp.rb
212
+ - lib/fast_ignore/matchers/unmatchable.rb
213
+ - lib/fast_ignore/matchers/within_dir.rb
214
+ - lib/fast_ignore/path_expander.rb
215
+ - lib/fast_ignore/path_regexp_builder.rb
216
+ - lib/fast_ignore/patterns.rb
217
+ - lib/fast_ignore/relative_candidate.rb
218
+ - lib/fast_ignore/rule_group.rb
219
+ - lib/fast_ignore/rule_groups.rb
198
220
  - lib/fast_ignore/version.rb
221
+ - lib/fast_ignore/walkers/base.rb
222
+ - lib/fast_ignore/walkers/file_system.rb
223
+ - lib/fast_ignore/walkers/gitignore_collecting_file_system.rb
199
224
  homepage: https://github.com/robotdana/fast_ignore
200
225
  licenses:
201
226
  - MIT
@@ -1,66 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class FastIgnore
4
- module Backports
5
- ruby_major, ruby_minor = ::RUBY_VERSION.split('.', 2)
6
- unless ruby_major.to_i > 2 || ruby_major.to_i == 2 && ruby_minor.to_i > 5
7
- module DirEachChild
8
- refine ::Dir.singleton_class do
9
- def children(path)
10
- ::Dir.entries(path) - ['.', '..']
11
- end
12
- end
13
- end
14
-
15
- module DeletePrefixSuffix
16
- refine ::String do
17
- # delete_prefix!(prefix) -> self or nil
18
- # Deletes leading prefix from str, returning nil if no change was made.
19
- #
20
- # "hello".delete_prefix!("hel") #=> "lo"
21
- # "hello".delete_prefix!("llo") #=> nil
22
- def delete_prefix!(str)
23
- return unless start_with?(str)
24
-
25
- slice!(0..(str.length - 1))
26
- self
27
- end
28
-
29
- # delete_suffix!(suffix) -> self or nil
30
- # Deletes trailing suffix from str, returning nil if no change was made.
31
- #
32
- # "hello".delete_suffix!("llo") #=> "he"
33
- # "hello".delete_suffix!("hel") #=> nil
34
- def delete_suffix!(str)
35
- return unless end_with?(str)
36
-
37
- slice!(-str.length..-1)
38
- self
39
- end
40
-
41
- # delete_prefix(prefix) -> new_str click to toggle source
42
- # Returns a copy of str with leading prefix deleted.
43
- #
44
- # "hello".delete_prefix("hel") #=> "lo"
45
- # "hello".delete_prefix("llo") #=> "hello"
46
- def delete_prefix(str)
47
- s = dup
48
- s.delete_prefix!(str)
49
- s
50
- end
51
-
52
- # delete_suffix(suffix) -> new_str
53
- # Returns a copy of str with trailing suffix deleted.
54
- #
55
- # "hello".delete_suffix("llo") #=> "he"
56
- # "hello".delete_suffix("hel") #=> "hello"
57
- def delete_suffix(str) # leftovers:allowed
58
- s = dup
59
- s.delete_suffix!(str)
60
- s
61
- end
62
- end
63
- end
64
- end
65
- end
66
- end
@@ -1,39 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class FastIgnore
4
- class FileRoot
5
- # :nocov:
6
- using ::FastIgnore::Backports::DeletePrefixSuffix if defined?(::FastIgnore::Backports::DeletePrefixSuffix)
7
- # :nocov:
8
-
9
- def self.build(file_path, project_root)
10
- file_root = "#{::File.dirname(file_path)}/".delete_prefix(project_root)
11
-
12
- new(file_root) unless file_root.empty?
13
- end
14
-
15
- def initialize(file_root)
16
- @file_root = file_root
17
- end
18
-
19
- def shebang_path_pattern
20
- @shebang_path_pattern ||= /\A#{escaped}./
21
- end
22
-
23
- def escaped
24
- @escaped ||= ::Regexp.escape(@file_root)
25
- end
26
-
27
- def escaped_segments
28
- @escaped_segments ||= escaped.split('/')
29
- end
30
-
31
- def escaped_segments_length
32
- @escaped_segments_length ||= escaped_segments.length
33
- end
34
-
35
- def escaped_segments_joined
36
- @escaped_segments_joined ||= escaped_segments.join('(?:/') + '(?:/'
37
- end
38
- end
39
- end
@@ -1,76 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class FastIgnore
4
- class GitignoreRuleRegexpBuilder < String
5
- def to_regexp
6
- # Regexp::IGNORECASE = 1
7
- ::Regexp.new(self, 1)
8
- end
9
-
10
- def append(value)
11
- self.<<(value)
12
-
13
- self
14
- end
15
-
16
- def append_escaped(value)
17
- return unless value
18
-
19
- append(::Regexp.escape(value))
20
- end
21
-
22
- def append_dir
23
- append('/')
24
- end
25
-
26
- def append_any_dir
27
- append('(?:.*/)?')
28
- end
29
-
30
- def append_one_non_dir
31
- append('[^/]')
32
- end
33
-
34
- def append_any_non_dir
35
- append_one_non_dir
36
- append('*')
37
- end
38
-
39
- def append_many_non_dir
40
- append_one_non_dir
41
- append('+')
42
- end
43
-
44
- def append_end_anchor
45
- append('\\z')
46
- end
47
-
48
- def append_start_anchor
49
- append('\\A')
50
- end
51
-
52
- def append_start_dir_or_anchor
53
- append('(?:\\A|/)')
54
- end
55
-
56
- def append_end_dir_or_anchor
57
- append('(?:/|\\z)')
58
- end
59
-
60
- def append_character_class_open
61
- append('(?!/)[')
62
- end
63
-
64
- def append_character_class_negation
65
- append('^')
66
- end
67
-
68
- def append_character_class_dash
69
- append('-')
70
- end
71
-
72
- def append_character_class_close
73
- append(']')
74
- end
75
- end
76
- end
@@ -1,65 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class FastIgnore
4
- class Rule
5
- attr_reader :negation
6
- alias_method :negation?, :negation
7
- undef :negation
8
-
9
- attr_reader :component_rules
10
- attr_reader :component_rules_count
11
-
12
- attr_reader :dir_only
13
- alias_method :dir_only?, :dir_only
14
- undef :dir_only
15
-
16
- attr_reader :squashable_type
17
- attr_reader :rule
18
-
19
- def squash(rules)
20
- # component rules is to improve the performance of repos with many .gitignore files. e.g. linux.
21
- component_rules = rules.flat_map(&:component_rules)
22
- ::FastIgnore::Rule.new(
23
- ::Regexp.union(component_rules.map(&:rule)).freeze,
24
- @negation, @anchored, @dir_only, component_rules
25
- )
26
- end
27
-
28
- def initialize(rule, negation, anchored, dir_only, component_rules = self) # rubocop:disable Metrics/MethodLength
29
- @rule = rule
30
- @anchored = anchored
31
- @dir_only = dir_only
32
- @negation = negation
33
- @component_rules = component_rules
34
- @component_rules_count = component_rules == self ? 1 : component_rules.length
35
-
36
- @squashable_type = if anchored && negation
37
- 1
38
- elsif anchored
39
- 0
40
- else
41
- ::Float::NAN # because it doesn't equal itself
42
- end
43
-
44
- freeze
45
- end
46
-
47
- def file_only?
48
- false
49
- end
50
-
51
- def shebang?
52
- false
53
- end
54
-
55
- # :nocov:
56
- def inspect
57
- "#<Rule #{'!' if @negation}#{'/' if @anchored}#{@rule}#{'/' if @dir_only}>"
58
- end
59
- # :nocov:
60
-
61
- def match?(relative_path, _full_path, _filename, _content)
62
- @rule.match?(relative_path)
63
- end
64
- end
65
- end
@@ -1,41 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class FastIgnore
4
- module RuleBuilder
5
- class << self
6
- # :nocov:
7
- using ::FastIgnore::Backports::DeletePrefixSuffix if defined?(::FastIgnore::Backports::DeletePrefixSuffix)
8
- # :nocov:
9
-
10
- def build(rule, allow, expand_path_with, file_root)
11
- if rule.delete_prefix!('#!:')
12
- shebang_rules(rule, allow, file_root)
13
- else
14
- gitignore_rules(rule, allow, file_root, expand_path_with)
15
- end
16
- end
17
-
18
- private
19
-
20
- def shebang_rules(shebang, allow, file_root)
21
- shebang.strip!
22
- pattern = /\A#!.*\b#{::Regexp.escape(shebang)}\b/i
23
- rule = ::FastIgnore::ShebangRule.new(pattern, allow, file_root&.shebang_path_pattern)
24
- return rule unless allow
25
-
26
- rules = gitignore_rules('*/'.dup, allow, file_root)
27
- rules.pop # don't want the include all children one.
28
- rules << rule
29
- rules
30
- end
31
-
32
- def gitignore_rules(rule, allow, file_root, expand_path_with = nil)
33
- if allow
34
- ::FastIgnore::GitignoreIncludeRuleBuilder.new(rule, file_root, expand_path_with).build
35
- else
36
- ::FastIgnore::GitignoreRuleBuilder.new(rule, file_root).build
37
- end
38
- end
39
- end
40
- end
41
- end
@@ -1,76 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class FastIgnore
4
- class RuleSet
5
- attr_reader :gitignore
6
- alias_method :gitignore?, :gitignore
7
- undef :gitignore
8
-
9
- def initialize(rules, allow, gitignore, squash = true)
10
- @dir_rules = (squash ? squash_rules(rules.reject(&:file_only?)) : rules.reject(&:file_only?)).freeze
11
- @file_rules = (squash ? squash_rules(rules.reject(&:dir_only?)) : rules.reject(&:dir_only?)).freeze
12
- @has_shebang_rules = rules.any?(&:shebang?)
13
-
14
- @allowed_recursive = { ['.', true, nil] => true }
15
- @allow = allow
16
- @gitignore = gitignore
17
-
18
- freeze unless gitignore?
19
- end
20
-
21
- def <<(other)
22
- return unless other
23
-
24
- @has_shebang_rules ||= other.has_shebang_rules
25
- @dir_rules = squash_rules(@dir_rules + other.dir_rules)
26
- @file_rules = squash_rules(@file_rules + other.file_rules)
27
- end
28
-
29
- def allowed_recursive?(relative_path, dir, full_path, filename, content = nil)
30
- @allowed_recursive.fetch([relative_path, dir, content]) do |key|
31
- @allowed_recursive[key] =
32
- allowed_recursive?(::File.dirname(relative_path), true, nil, nil, nil) &&
33
- allowed_unrecursive?(relative_path, dir, full_path, filename, content)
34
- end
35
- end
36
-
37
- def allowed_unrecursive?(relative_path, dir, full_path, filename, content)
38
- (dir ? @dir_rules : @file_rules).reverse_each do |rule|
39
- return rule.negation? if rule.match?(relative_path, full_path, filename, content)
40
- end
41
-
42
- not @allow
43
- end
44
-
45
- def squash_rules(rules) # rubocop:disable Metrics/MethodLength
46
- running_component_rule_size = rules.first&.component_rules_count || 0
47
- rules.chunk_while do |a, b|
48
- # a.squashable_type == b.squashable_type
49
- next true if a.squashable_type == b.squashable_type &&
50
- (running_component_rule_size + b.component_rules_count <= 40)
51
-
52
- running_component_rule_size = b.component_rules_count
53
- false
54
- end.map do |chunk| # rubocop:disable Style/MultilineBlockChain
55
- first = chunk.first
56
- next first if chunk.length == 1
57
-
58
- first.squash(chunk)
59
- end
60
- end
61
-
62
- def weight
63
- @dir_rules.length + (@has_shebang_rules ? 10 : 0)
64
- end
65
-
66
- def empty?
67
- @dir_rules.empty? && @file_rules.empty?
68
- end
69
-
70
- protected
71
-
72
- attr_reader :dir_rules
73
- attr_reader :file_rules
74
- attr_reader :has_shebang_rules
75
- end
76
- end