fast_ignore 0.14.0 → 0.16.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +17 -0
- data/README.md +5 -3
- data/lib/fast_ignore/file_root.rb +39 -0
- data/lib/fast_ignore/gitconfig_parser.rb +207 -0
- data/lib/fast_ignore/gitignore_include_rule_builder.rb +102 -0
- data/lib/fast_ignore/gitignore_rule_builder.rb +125 -155
- data/lib/fast_ignore/gitignore_rule_regexp_builder.rb +76 -0
- data/lib/fast_ignore/gitignore_rule_scanner.rb +73 -0
- data/lib/fast_ignore/global_gitignore.rb +16 -8
- data/lib/fast_ignore/rule.rb +8 -3
- data/lib/fast_ignore/rule_builder.rb +19 -50
- data/lib/fast_ignore/rule_set.rb +16 -6
- data/lib/fast_ignore/rule_sets.rb +13 -12
- data/lib/fast_ignore/shebang_rule.rb +15 -5
- data/lib/fast_ignore/unmatchable_rule.rb +5 -1
- data/lib/fast_ignore/version.rb +1 -1
- data/lib/fast_ignore.rb +15 -9
- metadata +43 -18
@@ -2,210 +2,180 @@
|
|
2
2
|
|
3
3
|
class FastIgnore
|
4
4
|
class GitignoreRuleBuilder # rubocop:disable Metrics/ClassLength
|
5
|
-
def initialize(rule,
|
6
|
-
@re = ::
|
7
|
-
@
|
8
|
-
@allow = allow
|
9
|
-
if @allow
|
10
|
-
@segments = 0
|
11
|
-
@parent_re = ::String.new
|
12
|
-
end
|
13
|
-
|
14
|
-
@s = ::StringScanner.new(rule)
|
5
|
+
def initialize(rule, file_path)
|
6
|
+
@re = ::FastIgnore::GitignoreRuleRegexpBuilder.new
|
7
|
+
@s = ::FastIgnore::GitignoreRuleScanner.new(rule)
|
15
8
|
|
16
|
-
@
|
17
|
-
@
|
18
|
-
@negation = negation
|
9
|
+
@file_path = file_path
|
10
|
+
@negation = false
|
19
11
|
@anchored = false
|
20
|
-
@
|
12
|
+
@dir_only = false
|
21
13
|
end
|
22
14
|
|
23
|
-
def
|
24
|
-
|
15
|
+
def break!
|
16
|
+
throw :break
|
25
17
|
end
|
26
18
|
|
27
|
-
def
|
28
|
-
|
19
|
+
def blank!
|
20
|
+
throw :abort_build, []
|
21
|
+
end
|
29
22
|
|
30
|
-
|
31
|
-
|
23
|
+
def unmatchable_rule!
|
24
|
+
throw :abort_build, []
|
32
25
|
end
|
33
26
|
|
34
|
-
def
|
35
|
-
|
27
|
+
def negated!
|
28
|
+
@negation = true
|
29
|
+
end
|
36
30
|
|
37
|
-
|
38
|
-
|
31
|
+
def anchored!
|
32
|
+
@anchored ||= true
|
39
33
|
end
|
40
34
|
|
41
|
-
def
|
42
|
-
|
43
|
-
@allow ? ::FastIgnore::UnmatchableRule : []
|
44
|
-
)
|
35
|
+
def never_anchored!
|
36
|
+
@anchored = :never
|
45
37
|
end
|
46
38
|
|
47
|
-
def
|
48
|
-
|
39
|
+
def dir_only!
|
40
|
+
@dir_only = true
|
41
|
+
end
|
49
42
|
|
50
|
-
|
43
|
+
def nothing_emitted?
|
44
|
+
@re.empty?
|
45
|
+
end
|
51
46
|
|
52
|
-
|
47
|
+
def emit_dir
|
48
|
+
anchored!
|
49
|
+
@re.append_dir
|
53
50
|
end
|
54
51
|
|
55
|
-
def
|
56
|
-
@
|
57
|
-
|
58
|
-
if @s.eos?
|
59
|
-
unmatchable_rule!
|
60
|
-
elsif process_escaped_char
|
61
|
-
@has_characters_in_group = true
|
62
|
-
elsif @s.skip(%r{/})
|
63
|
-
next unless negated_class
|
64
|
-
|
65
|
-
@has_characters_in_group = true
|
66
|
-
@segment_re << '/'
|
67
|
-
elsif @s.skip(/-/)
|
68
|
-
@has_characters_in_group = true
|
69
|
-
@segment_re << '-'
|
70
|
-
else @s.scan(%r{[^/\]\-]+})
|
71
|
-
@has_characters_in_group = true
|
72
|
-
@segment_re << ::Regexp.escape(@s.matched)
|
73
|
-
end
|
74
|
-
end
|
52
|
+
def emit_end
|
53
|
+
@re.append_end_anchor
|
54
|
+
break!
|
75
55
|
end
|
76
56
|
|
77
|
-
def
|
78
|
-
return unless @s.
|
57
|
+
def process_backslash
|
58
|
+
return unless @s.backslash?
|
79
59
|
|
80
|
-
|
81
|
-
if @segment_re.empty?
|
82
|
-
@parent_re << '.*'
|
83
|
-
else
|
84
|
-
process_slash_allow('.*')
|
85
|
-
end
|
86
|
-
end
|
87
|
-
process_slash('(?:.*/)?')
|
60
|
+
@re.append_escaped(@s.next_character) || unmatchable_rule!
|
88
61
|
end
|
89
62
|
|
90
|
-
def
|
91
|
-
return unless @s.
|
63
|
+
def process_star_end_after_slash
|
64
|
+
return true unless @s.star_end?
|
92
65
|
|
93
|
-
|
94
|
-
|
66
|
+
@re.append_many_non_dir
|
67
|
+
emit_end
|
95
68
|
end
|
96
69
|
|
97
|
-
def
|
98
|
-
return unless @s.
|
70
|
+
def process_slash
|
71
|
+
return unless @s.slash?
|
72
|
+
return dir_only! if @s.end?
|
73
|
+
return unmatchable_rule! if @s.slash?
|
99
74
|
|
100
|
-
|
101
|
-
|
75
|
+
emit_dir
|
76
|
+
process_star_end_after_slash
|
102
77
|
end
|
103
78
|
|
104
|
-
def
|
105
|
-
|
106
|
-
|
107
|
-
@segment_re.clear
|
108
|
-
@anchored = true
|
109
|
-
end
|
79
|
+
def process_two_stars # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
80
|
+
return unless @s.two_stars?
|
81
|
+
return break! if @s.end?
|
110
82
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
83
|
+
if @s.slash?
|
84
|
+
if @s.end?
|
85
|
+
@re.append_any_non_dir
|
86
|
+
dir_only!
|
87
|
+
elsif @s.slash?
|
88
|
+
unmatchable_rule!
|
89
|
+
else
|
90
|
+
if nothing_emitted?
|
91
|
+
never_anchored!
|
92
|
+
else
|
93
|
+
@re.append_any_dir
|
94
|
+
anchored!
|
95
|
+
end
|
96
|
+
process_star_end_after_slash
|
97
|
+
end
|
98
|
+
else
|
99
|
+
@re.append_any_non_dir
|
100
|
+
end
|
116
101
|
end
|
117
102
|
|
118
|
-
def
|
119
|
-
|
120
|
-
end
|
103
|
+
def process_character_class # rubocop:disable Metrics/MethodLength
|
104
|
+
return unless @s.character_class_start?
|
121
105
|
|
122
|
-
|
123
|
-
|
124
|
-
|
106
|
+
@re.append_character_class_open
|
107
|
+
@re.append_character_class_negation if @s.character_class_negation?
|
108
|
+
unmatchable_rule! if @s.character_class_end?
|
109
|
+
|
110
|
+
until @s.character_class_end?
|
111
|
+
next if process_backslash
|
112
|
+
next @re.append_character_class_dash if @s.dash?
|
113
|
+
next if @re.append_escaped(@s.character_class_literal)
|
125
114
|
|
126
|
-
|
127
|
-
|
115
|
+
unmatchable_rule!
|
116
|
+
end
|
117
|
+
|
118
|
+
@re.append_character_class_close
|
128
119
|
end
|
129
120
|
|
130
121
|
def process_end
|
131
|
-
|
122
|
+
blank! if nothing_emitted?
|
132
123
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
124
|
+
emit_end
|
125
|
+
end
|
126
|
+
|
127
|
+
def process_rule # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
128
|
+
anchored! if @s.slash?
|
129
|
+
|
130
|
+
catch :break do
|
131
|
+
loop do
|
132
|
+
next if process_backslash
|
133
|
+
next if process_slash
|
134
|
+
next if process_two_stars
|
135
|
+
next @re.append_any_non_dir if @s.star?
|
136
|
+
next @re.append_one_non_dir if @s.question_mark?
|
137
|
+
next if process_character_class
|
138
|
+
next if @re.append_escaped(@s.literal)
|
139
|
+
next if @re.append_escaped(@s.significant_whitespace)
|
140
|
+
|
141
|
+
process_end
|
138
142
|
end
|
139
143
|
end
|
140
|
-
@trailing_stars = true
|
141
144
|
end
|
142
145
|
|
143
|
-
def
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
146
|
+
def prefix # rubocop:disable Metrics/MethodLength
|
147
|
+
out = ::FastIgnore::GitignoreRuleRegexpBuilder.new
|
148
|
+
if @file_path
|
149
|
+
out.append_start_anchor.append(@file_path.escaped)
|
150
|
+
out.append_any_dir unless @anchored
|
151
|
+
else
|
152
|
+
if @anchored
|
153
|
+
out.append_start_anchor
|
154
|
+
else
|
155
|
+
out.append_start_dir_or_anchor
|
156
|
+
end
|
150
157
|
end
|
158
|
+
out
|
151
159
|
end
|
152
160
|
|
153
|
-
def
|
154
|
-
@
|
155
|
-
|
156
|
-
|
157
|
-
process_rule
|
161
|
+
def build_rule
|
162
|
+
@re.prepend(prefix)
|
163
|
+
::FastIgnore::Rule.new(@re.to_regexp, @negation, anchored_or_file_path, @dir_only)
|
164
|
+
end
|
158
165
|
|
159
|
-
|
166
|
+
def anchored_or_file_path
|
167
|
+
@anchored || @file_path
|
168
|
+
end
|
160
169
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
"\\A#{escaped_file_path}(?:.*/)?"
|
167
|
-
end
|
168
|
-
else
|
169
|
-
if @anchored
|
170
|
-
'\\A'
|
171
|
-
else
|
172
|
-
'(?:\\A|/)'
|
173
|
-
end
|
174
|
-
end
|
170
|
+
def build
|
171
|
+
catch :abort_build do
|
172
|
+
blank! if @s.hash?
|
173
|
+
negated! if @s.exclamation_mark?
|
174
|
+
process_rule
|
175
175
|
|
176
|
-
@
|
177
|
-
anchored_or_file_path = @anchored || @file_path
|
178
|
-
if @allow
|
179
|
-
if @file_path
|
180
|
-
allow_escaped_file_path = escaped_file_path.gsub(%r{(?<!\\)(?:\\\\)*/}) do |e|
|
181
|
-
@segments += 1
|
182
|
-
"#{e[0..-2]}(?:/"
|
183
|
-
end
|
184
|
-
|
185
|
-
prefix = if @anchored
|
186
|
-
"\\A#{allow_escaped_file_path}"
|
187
|
-
else
|
188
|
-
"\\A#{allow_escaped_file_path}(?:.*/)?"
|
189
|
-
end
|
190
|
-
end
|
191
|
-
@parent_re.prepend(prefix)
|
192
|
-
@parent_re << (')?' * @segments)
|
193
|
-
(@re << '(/|\\z)') unless @dir_only || @trailing_stars
|
194
|
-
rules = [
|
195
|
-
# Regexp::IGNORECASE = 1
|
196
|
-
::FastIgnore::Rule.new(::Regexp.new(@re, 1), @negation, anchored_or_file_path, @dir_only),
|
197
|
-
::FastIgnore::Rule.new(::Regexp.new(@parent_re, 1), true, anchored_or_file_path, true)
|
198
|
-
]
|
199
|
-
if @dir_only
|
200
|
-
(rules << ::FastIgnore::Rule.new(::Regexp.new((@re << '/.*'), 1), @negation, anchored_or_file_path, false))
|
201
|
-
end
|
202
|
-
rules
|
203
|
-
else
|
204
|
-
(@re << '\\z') unless @trailing_stars
|
176
|
+
@anchored = false if @anchored == :never
|
205
177
|
|
206
|
-
|
207
|
-
::FastIgnore::Rule.new(::Regexp.new(@re, 1), @negation, anchored_or_file_path, @dir_only)
|
208
|
-
end
|
178
|
+
build_rule
|
209
179
|
end
|
210
180
|
end
|
211
181
|
end
|
@@ -0,0 +1,76 @@
|
|
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
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class FastIgnore
|
4
|
+
class GitignoreRuleScanner < StringScanner
|
5
|
+
def character_class_end?
|
6
|
+
skip(/\]/)
|
7
|
+
end
|
8
|
+
|
9
|
+
def character_class_start?
|
10
|
+
skip(/\[/)
|
11
|
+
end
|
12
|
+
|
13
|
+
def character_class_negation?
|
14
|
+
skip(/\^|!/)
|
15
|
+
end
|
16
|
+
|
17
|
+
def end?
|
18
|
+
skip(/\s*\z/)
|
19
|
+
end
|
20
|
+
|
21
|
+
def slash?
|
22
|
+
skip(%r{/})
|
23
|
+
end
|
24
|
+
|
25
|
+
def backslash?
|
26
|
+
skip(/\\/)
|
27
|
+
end
|
28
|
+
|
29
|
+
def two_stars?
|
30
|
+
skip(/\*{2,}/)
|
31
|
+
end
|
32
|
+
|
33
|
+
def star?
|
34
|
+
skip(/\*/)
|
35
|
+
end
|
36
|
+
|
37
|
+
def next_character
|
38
|
+
matched if scan(/./)
|
39
|
+
end
|
40
|
+
|
41
|
+
def star_end?
|
42
|
+
skip(/\*\s*\z/)
|
43
|
+
end
|
44
|
+
|
45
|
+
def question_mark?
|
46
|
+
skip(/\?/)
|
47
|
+
end
|
48
|
+
|
49
|
+
def dash?
|
50
|
+
skip(/-/)
|
51
|
+
end
|
52
|
+
|
53
|
+
def character_class_literal
|
54
|
+
matched if scan(/[^\]\-\\]+/)
|
55
|
+
end
|
56
|
+
|
57
|
+
def literal
|
58
|
+
matched if scan(%r{[^*/?\[\\\s]+})
|
59
|
+
end
|
60
|
+
|
61
|
+
def significant_whitespace
|
62
|
+
matched if scan(/\s+(?!\s|\z)/)
|
63
|
+
end
|
64
|
+
|
65
|
+
def exclamation_mark?
|
66
|
+
skip(/!/)
|
67
|
+
end
|
68
|
+
|
69
|
+
def hash?
|
70
|
+
skip(/#/)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -11,32 +11,40 @@ class FastIgnore
|
|
11
11
|
default_global_gitignore_path
|
12
12
|
end
|
13
13
|
|
14
|
+
private
|
15
|
+
|
14
16
|
def gitconfig_gitignore_path(config_path)
|
15
17
|
return unless config_path
|
16
|
-
return unless ::File.
|
18
|
+
return unless ::File.readable?(config_path)
|
17
19
|
|
18
|
-
ignore_path = ::
|
20
|
+
ignore_path = ::FastIgnore::GitconfigParser.parse(config_path)
|
19
21
|
return unless ignore_path
|
20
22
|
|
21
23
|
ignore_path.strip!
|
22
|
-
return
|
24
|
+
return '' if ignore_path.empty? # don't expand path in this case
|
23
25
|
|
24
26
|
::File.expand_path(ignore_path)
|
25
27
|
end
|
26
28
|
|
27
29
|
def xdg_config_path
|
28
|
-
|
29
|
-
|
30
|
-
::File.expand_path('git/config', ::ENV['XDG_CONFIG_HOME'])
|
30
|
+
xdg_config_home? && ::File.expand_path('git/config', xdg_config_home)
|
31
31
|
end
|
32
32
|
|
33
33
|
def default_global_gitignore_path
|
34
|
-
if
|
35
|
-
::File.expand_path('git/ignore',
|
34
|
+
if xdg_config_home?
|
35
|
+
::File.expand_path('git/ignore', xdg_config_home)
|
36
36
|
else
|
37
37
|
::File.expand_path('~/.config/git/ignore')
|
38
38
|
end
|
39
39
|
end
|
40
|
+
|
41
|
+
def xdg_config_home
|
42
|
+
::ENV['XDG_CONFIG_HOME']
|
43
|
+
end
|
44
|
+
|
45
|
+
def xdg_config_home?
|
46
|
+
xdg_config_home && (not xdg_config_home.empty?)
|
47
|
+
end
|
40
48
|
end
|
41
49
|
end
|
42
50
|
end
|
data/lib/fast_ignore/rule.rb
CHANGED
@@ -7,6 +7,7 @@ class FastIgnore
|
|
7
7
|
undef :negation
|
8
8
|
|
9
9
|
attr_reader :component_rules
|
10
|
+
attr_reader :component_rules_count
|
10
11
|
|
11
12
|
attr_reader :dir_only
|
12
13
|
alias_method :dir_only?, :dir_only
|
@@ -17,8 +18,11 @@ class FastIgnore
|
|
17
18
|
|
18
19
|
def squash(rules)
|
19
20
|
# component rules is to improve the performance of repos with many .gitignore files. e.g. linux.
|
20
|
-
|
21
|
-
::FastIgnore::Rule.new(
|
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
|
+
)
|
22
26
|
end
|
23
27
|
|
24
28
|
def initialize(rule, negation, anchored, dir_only, component_rules = self) # rubocop:disable Metrics/MethodLength
|
@@ -27,6 +31,7 @@ class FastIgnore
|
|
27
31
|
@dir_only = dir_only
|
28
32
|
@negation = negation
|
29
33
|
@component_rules = component_rules
|
34
|
+
@component_rules_count = component_rules == self ? 1 : component_rules.length
|
30
35
|
|
31
36
|
@squashable_type = if anchored && negation
|
32
37
|
1
|
@@ -53,7 +58,7 @@ class FastIgnore
|
|
53
58
|
end
|
54
59
|
# :nocov:
|
55
60
|
|
56
|
-
def match?(relative_path,
|
61
|
+
def match?(relative_path, _full_path, _filename, _content)
|
57
62
|
@rule.match?(relative_path)
|
58
63
|
end
|
59
64
|
end
|
@@ -8,64 +8,33 @@ class FastIgnore
|
|
8
8
|
# :nocov:
|
9
9
|
|
10
10
|
def build(rule, allow, expand_path_with, file_root)
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
gitignore_rules(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
|
17
16
|
end
|
18
17
|
|
19
18
|
private
|
20
19
|
|
21
|
-
def
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
def remove_shebang(rule)
|
27
|
-
return unless rule.delete_prefix!('#!:')
|
28
|
-
|
29
|
-
rule.strip!
|
30
|
-
|
31
|
-
true
|
32
|
-
end
|
33
|
-
|
34
|
-
def shebang_rules(rule, allow)
|
35
|
-
rule = ::FastIgnore::ShebangRule.new(/\A#!.*\b#{::Regexp.escape(rule)}\b/i, allow)
|
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)
|
36
24
|
return rule unless allow
|
37
25
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
rule.empty? || rule.start_with?('#')
|
43
|
-
end
|
44
|
-
|
45
|
-
def gitignore_rules(rule, allow, expand_path_with, file_root)
|
46
|
-
dir_only = extract_dir_only(rule)
|
47
|
-
negation = extract_negation(rule, allow)
|
48
|
-
|
49
|
-
expand_rule_path(rule, expand_path_with) if expand_path_with
|
50
|
-
|
51
|
-
::FastIgnore::GitignoreRuleBuilder.new(rule, negation, dir_only, file_root, allow).build
|
52
|
-
end
|
53
|
-
|
54
|
-
def extract_dir_only(rule)
|
55
|
-
rule.delete_suffix!('/')
|
56
|
-
end
|
57
|
-
|
58
|
-
def extract_negation(rule, allow)
|
59
|
-
return allow unless rule.delete_prefix!('!')
|
60
|
-
|
61
|
-
not allow
|
26
|
+
rules = gitignore_rules('*/'.dup, allow, file_root)
|
27
|
+
rules.pop # don't want the include all children one.
|
28
|
+
rules << rule
|
29
|
+
rules
|
62
30
|
end
|
63
31
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
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
|
69
38
|
end
|
70
39
|
end
|
71
40
|
end
|