fast_ignore 0.17.2 → 0.17.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +11 -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 +1 -1
  9. data/lib/fast_ignore/gitignore_include_rule_builder.rb +40 -63
  10. data/lib/fast_ignore/gitignore_rule_builder.rb +49 -26
  11. data/lib/fast_ignore/gitignore_rule_group.rb +31 -0
  12. data/lib/fast_ignore/gitignore_rule_scanner.rb +12 -0
  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 -84
  30. metadata +23 -11
  31. data/lib/fast_ignore/file_root.rb +0 -35
  32. data/lib/fast_ignore/gitignore_rule_regexp_builder.rb +0 -76
  33. data/lib/fast_ignore/rule.rb +0 -65
  34. data/lib/fast_ignore/rule_builder.rb +0 -37
  35. data/lib/fast_ignore/rule_set.rb +0 -76
  36. data/lib/fast_ignore/rule_sets.rb +0 -109
  37. data/lib/fast_ignore/shebang_rule.rb +0 -80
  38. data/lib/fast_ignore/unmatchable_rule.rb +0 -41
data/lib/fast_ignore.rb CHANGED
@@ -6,66 +6,51 @@ require 'strscan'
6
6
  class FastIgnore
7
7
  class Error < StandardError; end
8
8
 
9
- require_relative './fast_ignore/rule_sets'
10
- require_relative './fast_ignore/rule_set'
11
- require_relative './fast_ignore/global_gitignore'
12
- require_relative './fast_ignore/rule_builder'
13
- require_relative './fast_ignore/gitignore_rule_builder'
14
- require_relative './fast_ignore/gitignore_include_rule_builder'
15
- require_relative './fast_ignore/gitignore_rule_regexp_builder'
16
- require_relative './fast_ignore/gitignore_rule_scanner'
17
- require_relative './fast_ignore/file_root'
18
- require_relative './fast_ignore/rule'
19
- require_relative './fast_ignore/unmatchable_rule'
20
- require_relative './fast_ignore/shebang_rule'
21
- 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'
22
34
 
23
35
  include ::Enumerable
24
36
 
25
- def initialize(relative: false, root: nil, gitignore: :auto, follow_symlinks: false, **rule_set_builder_args)
26
- @relative = relative
27
- @follow_symlinks_method = ::File.method(follow_symlinks ? :stat : :lstat)
28
- @gitignore_enabled = gitignore
29
- @loaded_gitignore_files = ::Set[''] if gitignore
37
+ def initialize(relative: false, root: nil, gitignore: :auto, follow_symlinks: false, **rule_group_builder_args)
30
38
  @root = "#{::File.expand_path(root.to_s, Dir.pwd)}/"
31
- @rule_sets = ::FastIgnore::RuleSets.new(root: @root, gitignore: gitignore, **rule_set_builder_args)
32
-
33
- freeze
34
- end
35
-
36
- def each(&block)
37
- return enum_for(:each) unless block
38
-
39
- dir_pwd = ::Dir.pwd
40
- root_from_pwd = @root.start_with?(dir_pwd) ? ".#{@root.delete_prefix(dir_pwd)}" : @root
41
-
42
- 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
43
43
  end
44
44
 
45
- def allowed?(path, directory: nil, content: nil, exists: nil, include_directories: false) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
46
- full_path = ::File.expand_path(path, @root)
47
- return false unless full_path.start_with?(@root)
48
-
49
- begin
50
- directory = directory.nil? ? @follow_symlinks_method.call(full_path).directory? : directory
51
- rescue ::Errno::ENOENT, ::Errno::EACCES, ::Errno::ENOTDIR, ::Errno::ELOOP, ::Errno::ENAMETOOLONG
52
- exists = false if exists.nil?
53
- directory = false
54
- end
55
-
56
- return false if !include_directories && directory
57
-
58
- exists = exists.nil? ? ::File.exist?(full_path) : exists
59
-
60
- return false unless exists
61
-
62
- relative_path = full_path.delete_prefix(@root)
63
- load_gitignore_recursive(relative_path) if @gitignore_enabled
64
-
65
- filename = ::File.basename(relative_path)
66
- content = content.slice(/.*/) if content # we only care about the first line
67
-
68
- @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
+ )
69
54
  end
70
55
  alias_method :===, :allowed?
71
56
 
@@ -73,43 +58,28 @@ class FastIgnore
73
58
  method(:allowed?).to_proc
74
59
  end
75
60
 
76
- private
61
+ def each(&block)
62
+ return enum_for(:each) unless block
77
63
 
78
- def load_gitignore_recursive(path)
79
- paths = []
80
- while (path = ::File.dirname(path)) != '.'
81
- paths << path
82
- end
64
+ prefix = @relative ? '' : @root
83
65
 
84
- paths.reverse_each { |p| load_gitignore(p) }
66
+ walker.each(@root, prefix, &block)
85
67
  end
86
68
 
87
- def load_gitignore(parent_path, check_exists: true)
88
- 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)
89
71
 
90
- @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)
91
74
 
92
- @loaded_gitignore_files << parent_path
75
+ freeze
93
76
  end
94
77
 
95
- def each_recursive(parent_full_path, parent_relative_path, &block) # rubocop:disable Metrics/MethodLength
96
- children = ::Dir.children(parent_full_path)
97
- load_gitignore(parent_relative_path, check_exists: false) if @gitignore_enabled && children.include?('.gitignore')
98
-
99
- children.each do |filename|
100
- full_path = parent_full_path + filename
101
- relative_path = parent_relative_path + filename
102
- dir = @follow_symlinks_method.call(full_path).directory?
103
-
104
- next unless @rule_sets.allowed_unrecursive?(relative_path, dir, full_path, filename)
105
-
106
- if dir
107
- each_recursive(full_path + '/', relative_path + '/', &block)
108
- else
109
- yield(@relative ? relative_path : @root + relative_path)
110
- end
111
- rescue ::Errno::ENOENT, ::Errno::EACCES, ::Errno::ENOTDIR, ::Errno::ELOOP, ::Errno::ENAMETOOLONG
112
- nil
113
- end
78
+ private
79
+
80
+ def walker
81
+ build unless defined?(@walker)
82
+
83
+ @walker
114
84
  end
115
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.2
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-19 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
@@ -195,20 +195,32 @@ files:
195
195
  - LICENSE.txt
196
196
  - README.md
197
197
  - lib/fast_ignore.rb
198
- - 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
199
202
  - lib/fast_ignore/gitconfig_parser.rb
200
203
  - lib/fast_ignore/gitignore_include_rule_builder.rb
201
204
  - lib/fast_ignore/gitignore_rule_builder.rb
202
- - lib/fast_ignore/gitignore_rule_regexp_builder.rb
205
+ - lib/fast_ignore/gitignore_rule_group.rb
203
206
  - lib/fast_ignore/gitignore_rule_scanner.rb
204
207
  - lib/fast_ignore/global_gitignore.rb
205
- - lib/fast_ignore/rule.rb
206
- - lib/fast_ignore/rule_builder.rb
207
- - lib/fast_ignore/rule_set.rb
208
- - lib/fast_ignore/rule_sets.rb
209
- - lib/fast_ignore/shebang_rule.rb
210
- - 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
211
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
212
224
  homepage: https://github.com/robotdana/fast_ignore
213
225
  licenses:
214
226
  - MIT
@@ -231,7 +243,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
231
243
  - !ruby/object:Gem::Version
232
244
  version: '0'
233
245
  requirements: []
234
- rubygems_version: 3.1.6
246
+ rubygems_version: 3.2.15
235
247
  signing_key:
236
248
  specification_version: 4
237
249
  summary: Parse gitignore files, quickly
@@ -1,35 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class FastIgnore
4
- class FileRoot
5
- def self.build(file_path, project_root)
6
- file_root = "#{::File.dirname(file_path)}/".delete_prefix(project_root)
7
-
8
- new(file_root) unless file_root.empty?
9
- end
10
-
11
- def initialize(file_root)
12
- @file_root = file_root
13
- end
14
-
15
- def shebang_path_pattern
16
- @shebang_path_pattern ||= /\A#{escaped}./
17
- end
18
-
19
- def escaped
20
- @escaped ||= ::Regexp.escape(@file_root)
21
- end
22
-
23
- def escaped_segments
24
- @escaped_segments ||= escaped.split('/')
25
- end
26
-
27
- def escaped_segments_length
28
- @escaped_segments_length ||= escaped_segments.length
29
- end
30
-
31
- def escaped_segments_joined
32
- @escaped_segments_joined ||= escaped_segments.join('(?:/') + '(?:/'
33
- end
34
- end
35
- 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,37 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class FastIgnore
4
- module RuleBuilder
5
- class << self
6
- def build(rule, allow, expand_path_with, file_root)
7
- if rule.delete_prefix!('#!:')
8
- shebang_rules(rule, allow, file_root)
9
- else
10
- gitignore_rules(rule, allow, file_root, expand_path_with)
11
- end
12
- end
13
-
14
- private
15
-
16
- def shebang_rules(shebang, allow, file_root)
17
- shebang.strip!
18
- pattern = /\A#!.*\b#{::Regexp.escape(shebang)}\b/i
19
- rule = ::FastIgnore::ShebangRule.new(pattern, allow, file_root&.shebang_path_pattern)
20
- return rule unless allow
21
-
22
- rules = gitignore_rules(+'*/', allow, file_root)
23
- rules.pop # don't want the include all children one.
24
- rules << rule
25
- rules
26
- end
27
-
28
- def gitignore_rules(rule, allow, file_root, expand_path_with = nil)
29
- if allow
30
- ::FastIgnore::GitignoreIncludeRuleBuilder.new(rule, file_root, expand_path_with).build
31
- else
32
- ::FastIgnore::GitignoreRuleBuilder.new(rule, file_root).build
33
- end
34
- end
35
- end
36
- end
37
- 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
@@ -1,109 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class FastIgnore
4
- class RuleSets
5
- def initialize( # rubocop:disable Metrics/ParameterLists
6
- root:,
7
- ignore_rules: nil,
8
- ignore_files: nil,
9
- gitignore: true,
10
- include_rules: nil,
11
- include_files: nil,
12
- argv_rules: nil
13
- )
14
- @array = []
15
- @project_root = root
16
- append_root_gitignore(gitignore)
17
- append_set_from_array(ignore_rules)
18
- append_set_from_array(include_rules, allow: true)
19
- append_set_from_array(argv_rules, allow: true, expand_path_with: @project_root)
20
- append_sets_from_files(ignore_files)
21
- append_sets_from_files(include_files, allow: true)
22
- @array.sort_by!(&:weight)
23
- @array.freeze if @gitignore_rule_set
24
- end
25
-
26
- def allowed_recursive?(relative_path, dir, full_path, filename, content)
27
- @array.all? { |r| r.allowed_recursive?(relative_path, dir, full_path, filename, content) }
28
- end
29
-
30
- def allowed_unrecursive?(relative_path, dir, full_path, filename)
31
- @array.all? { |r| r.allowed_unrecursive?(relative_path, dir, full_path, filename, nil) }
32
- end
33
-
34
- def append_subdir_gitignore(relative_path:, check_exists: true) # rubocop:disable Metrics/MethodLength
35
- if @gitignore_rule_set
36
- new_gitignore = build_set_from_file(relative_path, gitignore: true, check_exists: check_exists, squash: false)
37
- return if !new_gitignore || new_gitignore.empty?
38
-
39
- @gitignore_rule_set << new_gitignore
40
- else
41
- new_gitignore = build_set_from_file(relative_path, gitignore: true, check_exists: check_exists)
42
- return if !new_gitignore || new_gitignore.empty?
43
-
44
- @array << new_gitignore
45
- @gitignore_rule_set = new_gitignore
46
- @array.sort_by!(&:weight) && @array.freeze
47
- end
48
- new_gitignore
49
- end
50
-
51
- private
52
-
53
- def append_and_return_if_present(value)
54
- return unless value && !value.empty?
55
-
56
- @array << value
57
- value
58
- end
59
-
60
- def append_root_gitignore(gitignore)
61
- return @gitignore_rule_set = nil unless gitignore
62
-
63
- append_set_from_array('.git')
64
- gi = ::FastIgnore::RuleSet.new([], false, true)
65
- gi << build_from_root_gitignore_file(::FastIgnore::GlobalGitignore.path(root: @project_root))
66
- gi << build_from_root_gitignore_file("#{@project_root}.git/info/exclude")
67
- gi << build_from_root_gitignore_file("#{@project_root}.gitignore")
68
- @gitignore_rule_set = append_and_return_if_present(gi)
69
- end
70
-
71
- def build_from_root_gitignore_file(path)
72
- return unless path && ::File.exist?(path)
73
-
74
- build_rule_set(::File.readlines(path), false, gitignore: true)
75
- end
76
-
77
- def build_rule_set(rules, allow, expand_path_with: nil, file_root: nil, gitignore: false, squash: true) # rubocop:disable Metrics/ParameterLists
78
- rules = rules.flat_map do |rule|
79
- ::FastIgnore::RuleBuilder.build(rule, allow, expand_path_with, file_root)
80
- end
81
-
82
- ::FastIgnore::RuleSet.new(rules, allow, gitignore, squash)
83
- end
84
-
85
- def build_set_from_file(filename, allow: false, gitignore: false, check_exists: false, squash: true)
86
- filename = ::File.expand_path(filename, @project_root)
87
- return if check_exists && !::File.exist?(filename)
88
- raise ::FastIgnore::Error, "#{filename} is not within #{@project_root}" unless filename.start_with?(@project_root)
89
-
90
- file_root = ::FastIgnore::FileRoot.build(filename, @project_root)
91
- build_rule_set(::File.readlines(filename), allow, file_root: file_root, gitignore: gitignore, squash: squash)
92
- end
93
-
94
- def append_sets_from_files(files, allow: false)
95
- Array(files).each do |file|
96
- append_and_return_if_present(build_set_from_file(file, allow: allow))
97
- end
98
- end
99
-
100
- def append_set_from_array(rules, allow: false, expand_path_with: nil)
101
- return unless rules
102
-
103
- rules = Array(rules).flat_map { |string| string.to_s.lines }
104
- return if rules.empty?
105
-
106
- append_and_return_if_present(build_rule_set(rules, allow, expand_path_with: expand_path_with))
107
- end
108
- end
109
- end