fast_ignore 0.17.2 → 0.17.4

Sign up to get free protection for your applications and to get access to all the features.
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