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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -0
- data/README.md +0 -13
- data/lib/fast_ignore/builders/gitignore.rb +15 -0
- data/lib/fast_ignore/builders/shebang.rb +17 -0
- data/lib/fast_ignore/builders/shebang_or_gitignore.rb +15 -0
- data/lib/fast_ignore/candidate.rb +85 -0
- data/lib/fast_ignore/gitconfig_parser.rb +1 -1
- data/lib/fast_ignore/gitignore_include_rule_builder.rb +40 -63
- data/lib/fast_ignore/gitignore_rule_builder.rb +49 -26
- data/lib/fast_ignore/gitignore_rule_group.rb +31 -0
- data/lib/fast_ignore/gitignore_rule_scanner.rb +12 -0
- data/lib/fast_ignore/matchers/allow_any_dir.rb +39 -0
- data/lib/fast_ignore/matchers/allow_path_regexp.rb +45 -0
- data/lib/fast_ignore/matchers/ignore_path_regexp.rb +45 -0
- data/lib/fast_ignore/matchers/shebang_regexp.rb +46 -0
- data/lib/fast_ignore/matchers/unmatchable.rb +31 -0
- data/lib/fast_ignore/matchers/within_dir.rb +50 -0
- data/lib/fast_ignore/path_expander.rb +11 -0
- data/lib/fast_ignore/path_regexp_builder.rb +130 -0
- data/lib/fast_ignore/patterns.rb +33 -0
- data/lib/fast_ignore/relative_candidate.rb +20 -0
- data/lib/fast_ignore/rule_group.rb +42 -0
- data/lib/fast_ignore/rule_groups.rb +55 -0
- data/lib/fast_ignore/version.rb +1 -1
- data/lib/fast_ignore/walkers/base.rb +26 -0
- data/lib/fast_ignore/walkers/file_system.rb +46 -0
- data/lib/fast_ignore/walkers/gitignore_collecting_file_system.rb +48 -0
- data/lib/fast_ignore.rb +54 -84
- metadata +23 -11
- data/lib/fast_ignore/file_root.rb +0 -35
- data/lib/fast_ignore/gitignore_rule_regexp_builder.rb +0 -76
- data/lib/fast_ignore/rule.rb +0 -65
- data/lib/fast_ignore/rule_builder.rb +0 -37
- data/lib/fast_ignore/rule_set.rb +0 -76
- data/lib/fast_ignore/rule_sets.rb +0 -109
- data/lib/fast_ignore/shebang_rule.rb +0 -80
- data/lib/fast_ignore/unmatchable_rule.rb +0 -41
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c81120885ae42b4893295ecd66b501ed6962d2742adc2bd59433796ca0e41995
|
4
|
+
data.tar.gz: 0a15d4651cc7dfc7eeed32b919da373ebee92195385ff0cf22acd92751258b68
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c38a391c2a05c7439899144c2af1db29281538c855a18be47725b3e92f8fc40ecca2f69f15a26508d5f63d7f45f998cbba73ac41feaa1541356daf20067b4ce9
|
7
|
+
data.tar.gz: 0e355b08fbb00c9cca020ac06b0062f73477a59f673f6b465bf71d11c0228889dbeeb487e8e519eeccd09afa84290681f65f75300695332b0a4e44ecbec1b445
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
# v0.17.4
|
2
|
+
- Deprecated `follow_symlinks:`, it's inaccurately named and awkward.
|
3
|
+
|
4
|
+
- Plus lots of refactoring that _should_ have no effect on behaviour
|
5
|
+
- Some performance regression due to the deprecation logic. we'll improve more than we lost after the deprecations are gone entirely.
|
6
|
+
|
7
|
+
# v0.17.3
|
8
|
+
- Add fuzz tests, fix a couple more edge cases it revealed:
|
9
|
+
- `~not_a_user` will be considered literal rather than raising an error, `~a_user` will continue to be expanded to the home directory of `a_user` when used in an `argv_rules:` or `allowed?`
|
10
|
+
- an `include_rule:` with a trailing `/` was raising a FrozenError in some circumstances.
|
11
|
+
|
1
12
|
# v0.17.2
|
2
13
|
- Remove unnecessary backport code that was leftover when support for 2.4 was dropped
|
3
14
|
- Tiny performance improvements from rubocop-performance's suggestions
|
data/README.md
CHANGED
@@ -166,19 +166,6 @@ When `relative: true`: FastIgnore#each will yield paths relative to the [`root:`
|
|
166
166
|
FastIgnore.new(relative: true).to_a
|
167
167
|
```
|
168
168
|
|
169
|
-
### `follow_symlinks: true`
|
170
|
-
|
171
|
-
**Default: false**
|
172
|
-
|
173
|
-
When `follow_symlinks: false`: FastIgnore#each will match git's behaviour and not follow symbolic links.
|
174
|
-
When `follow_symlinks: true`: FastIgnore#each will check if a symlink points to a directory, and files in linked directories must also match rules using the symlink path as the directory location, not the real directory location.
|
175
|
-
|
176
|
-
**This doesn't use the real path for matching or yield or return it.**
|
177
|
-
|
178
|
-
```ruby
|
179
|
-
FastIgnore.new(follow_symlinks: true).to_a
|
180
|
-
```
|
181
|
-
|
182
169
|
### `root:`
|
183
170
|
|
184
171
|
**Default: Dir.pwd ($PWD, the current working directory)**
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class FastIgnore
|
4
|
+
module Builders
|
5
|
+
module Gitignore
|
6
|
+
def self.build(rule, allow, expand_path_with: nil)
|
7
|
+
if allow
|
8
|
+
::FastIgnore::GitignoreIncludeRuleBuilder.new(rule, expand_path_with: expand_path_with).build
|
9
|
+
else
|
10
|
+
::FastIgnore::GitignoreRuleBuilder.new(rule, expand_path_with: expand_path_with).build
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class FastIgnore
|
4
|
+
module Builders
|
5
|
+
module Shebang
|
6
|
+
def self.build(shebang, allow)
|
7
|
+
shebang.strip!
|
8
|
+
pattern = /\A#!.*\b#{::Regexp.escape(shebang)}\b/i
|
9
|
+
rule = ::FastIgnore::Matchers::ShebangRegexp.new(pattern, allow)
|
10
|
+
return rule unless allow
|
11
|
+
|
12
|
+
# also allow all directories in case they include a file with the matching shebang file
|
13
|
+
[::FastIgnore::Matchers::AllowAnyDir, rule]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class FastIgnore
|
4
|
+
module Builders
|
5
|
+
module ShebangOrGitignore
|
6
|
+
def self.build(rule, allow, expand_path_with: nil)
|
7
|
+
if rule.delete_prefix!('#!:')
|
8
|
+
::FastIgnore::Builders::Shebang.build(rule, allow)
|
9
|
+
else
|
10
|
+
::FastIgnore::Builders::Gitignore.build(rule, allow, expand_path_with: expand_path_with)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
|
3
|
+
class FastIgnore
|
4
|
+
class Candidate
|
5
|
+
class << self
|
6
|
+
def root
|
7
|
+
@root ||= new('/', nil, true, true, nil)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(full_path, filename, directory, exists, content)
|
12
|
+
@full_path = full_path
|
13
|
+
@filename = filename
|
14
|
+
(@directory = directory) unless directory.nil?
|
15
|
+
(@exists = exists) unless exists.nil?
|
16
|
+
(@first_line = content.slice(/.*/)) if content # we only care about the first line
|
17
|
+
end
|
18
|
+
|
19
|
+
def parent
|
20
|
+
@parent ||= ::FastIgnore::Candidate.new(::File.dirname(@full_path), nil, true, true, nil)
|
21
|
+
end
|
22
|
+
|
23
|
+
# use \0 because it can't be in paths
|
24
|
+
def key
|
25
|
+
@key ||= :"#{
|
26
|
+
"\0" if defined?(@directory) && @directory
|
27
|
+
}#{
|
28
|
+
@full_path
|
29
|
+
}\0#{
|
30
|
+
@first_line if defined?(@first_line)
|
31
|
+
}"
|
32
|
+
end
|
33
|
+
|
34
|
+
def relative_to(dir)
|
35
|
+
return unless @full_path.start_with?(dir)
|
36
|
+
|
37
|
+
::FastIgnore::RelativeCandidate.new(@full_path.delete_prefix(dir), self)
|
38
|
+
end
|
39
|
+
|
40
|
+
def directory?
|
41
|
+
return @directory if defined?(@directory)
|
42
|
+
|
43
|
+
@directory = ::File.lstat(@full_path).directory?
|
44
|
+
rescue ::Errno::ENOENT, ::Errno::EACCES, ::Errno::ENAMETOOLONG
|
45
|
+
@exists ||= false
|
46
|
+
@directory = false
|
47
|
+
end
|
48
|
+
|
49
|
+
def exists?
|
50
|
+
return @exists if defined?(@exists)
|
51
|
+
|
52
|
+
@exists = ::File.exist?(@full_path)
|
53
|
+
rescue ::Errno::EACCES, ::Errno::ELOOP, ::Errno::ENAMETOOLONG
|
54
|
+
# :nocov: can't quite get this set up in a test
|
55
|
+
@exists = false
|
56
|
+
# :nocov:
|
57
|
+
end
|
58
|
+
|
59
|
+
def filename
|
60
|
+
@filename ||= ::File.basename(@full_path)
|
61
|
+
end
|
62
|
+
|
63
|
+
# how long can a shebang be?
|
64
|
+
# https://www.in-ulm.de/~mascheck/various/shebang/
|
65
|
+
def first_line # rubocop:disable Metrics/MethodLength
|
66
|
+
@first_line ||= begin
|
67
|
+
file = ::File.new(@full_path)
|
68
|
+
first_line = file.sysread(64)
|
69
|
+
if first_line.start_with?('#!')
|
70
|
+
first_line += file.readline unless first_line.include?("\n")
|
71
|
+
file.close
|
72
|
+
first_line
|
73
|
+
else
|
74
|
+
file.close
|
75
|
+
''
|
76
|
+
end
|
77
|
+
rescue ::EOFError, ::SystemCallError
|
78
|
+
# :nocov:
|
79
|
+
file&.close
|
80
|
+
# :nocov:
|
81
|
+
''
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -55,7 +55,7 @@ class FastIgnore
|
|
55
55
|
include_path = scan_value(file)
|
56
56
|
|
57
57
|
value = ::FastIgnore::GitconfigParser.parse(
|
58
|
-
|
58
|
+
PathExpander.expand_path(include_path, ::File.dirname(path)),
|
59
59
|
root: root,
|
60
60
|
nesting: nesting + 1
|
61
61
|
)
|
@@ -2,22 +2,10 @@
|
|
2
2
|
|
3
3
|
class FastIgnore
|
4
4
|
class GitignoreIncludeRuleBuilder < GitignoreRuleBuilder
|
5
|
-
def initialize(rule,
|
6
|
-
super
|
5
|
+
def initialize(rule, expand_path_with: nil)
|
6
|
+
super
|
7
7
|
|
8
|
-
@parent_segments = []
|
9
8
|
@negation = true
|
10
|
-
@expand_path_from = expand_path_from
|
11
|
-
end
|
12
|
-
|
13
|
-
def expand_rule_path
|
14
|
-
anchored! unless @s.match?(/\*/) # rubocop:disable Performance/StringInclude # it's StringScanner#match?
|
15
|
-
return unless @s.match?(%r{(?:[~/]|\.{1,2}/|.*/\.\./)})
|
16
|
-
|
17
|
-
dir_only! if @s.match?(%r{.*/\s*\z})
|
18
|
-
@s.string.replace(::File.expand_path(@s.rest))
|
19
|
-
@s.string.delete_prefix!(@expand_path_from)
|
20
|
-
@s.pos = 0
|
21
9
|
end
|
22
10
|
|
23
11
|
def negated!
|
@@ -25,74 +13,63 @@ class FastIgnore
|
|
25
13
|
end
|
26
14
|
|
27
15
|
def unmatchable_rule!
|
28
|
-
throw :abort_build, ::FastIgnore::
|
29
|
-
end
|
30
|
-
|
31
|
-
def nothing_emitted?
|
32
|
-
@re.empty? && @parent_segments.empty?
|
33
|
-
end
|
34
|
-
|
35
|
-
def emit_dir
|
36
|
-
anchored!
|
37
|
-
|
38
|
-
@parent_segments << @re
|
39
|
-
@re = ::FastIgnore::GitignoreRuleRegexpBuilder.new
|
16
|
+
throw :abort_build, ::FastIgnore::Matchers::Unmatchable
|
40
17
|
end
|
41
18
|
|
42
19
|
def emit_end
|
43
|
-
@dir_only
|
20
|
+
if @dir_only
|
21
|
+
@child_re = @re.dup
|
22
|
+
@re.append_end_anchor
|
23
|
+
else
|
24
|
+
@re.append_dir_or_end_anchor
|
25
|
+
end
|
26
|
+
|
44
27
|
break!
|
45
28
|
end
|
46
29
|
|
47
|
-
def
|
48
|
-
|
49
|
-
parent_prefix = if @file_path
|
50
|
-
segment_joins_count += @file_path.escaped_segments_length
|
30
|
+
def build_parent_dir_rules
|
31
|
+
return unless @negation
|
51
32
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
33
|
+
if @anchored
|
34
|
+
parent_pattern = @s.string.dup
|
35
|
+
if parent_pattern.sub!(%r{/[^/]+/?\s*\z}, '/')
|
36
|
+
::FastIgnore::GitignoreIncludeRuleBuilder.new(parent_pattern).build_as_parent
|
56
37
|
end
|
57
38
|
else
|
58
|
-
|
39
|
+
[::FastIgnore::Matchers::AllowAnyDir]
|
59
40
|
end
|
41
|
+
end
|
60
42
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
43
|
+
def build_child_file_rule # rubocop:disable Metrics/MethodLength
|
44
|
+
if @child_re.end_with?('/')
|
45
|
+
@child_re.append_many_non_dir.append_dir if @dir_only
|
46
|
+
else
|
47
|
+
@child_re.append_dir
|
66
48
|
end
|
67
|
-
out << (')?' * segment_joins_count)
|
68
|
-
out
|
69
|
-
end
|
70
49
|
|
71
|
-
|
72
|
-
# Regexp::IGNORECASE = 1
|
73
|
-
::FastIgnore::Rule.new(::Regexp.new(parent_dir_re, 1), true, anchored_or_file_path, true)
|
74
|
-
end
|
50
|
+
@child_re.prepend(prefix)
|
75
51
|
|
76
|
-
|
77
|
-
|
78
|
-
|
52
|
+
if @negation
|
53
|
+
::FastIgnore::Matchers::AllowPathRegexp.new(@child_re.to_regexp, @anchored, false)
|
54
|
+
else
|
55
|
+
::FastIgnore::Matchers::IgnorePathRegexp.new(@child_re.to_regexp, @anchored, false)
|
56
|
+
end
|
79
57
|
end
|
80
58
|
|
81
|
-
def
|
82
|
-
|
83
|
-
|
84
|
-
joined_re.append_dir unless @parent_segments.empty?
|
85
|
-
joined_re.append(@re)
|
86
|
-
@re = joined_re
|
59
|
+
def build_as_parent
|
60
|
+
anchored!
|
61
|
+
dir_only!
|
87
62
|
|
88
|
-
|
89
|
-
|
90
|
-
|
63
|
+
catch :abort_build do
|
64
|
+
process_rule
|
65
|
+
build_rule(child_file_rule: false)
|
66
|
+
end
|
91
67
|
end
|
92
68
|
|
93
|
-
def
|
94
|
-
|
95
|
-
|
69
|
+
def build_rule(child_file_rule: true)
|
70
|
+
@child_re ||= @re.dup # in case emit_end wasn't called
|
71
|
+
|
72
|
+
[super(), *build_parent_dir_rules, (build_child_file_rule if child_file_rule)].compact
|
96
73
|
end
|
97
74
|
end
|
98
75
|
end
|
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
class FastIgnore
|
4
4
|
class GitignoreRuleBuilder # rubocop:disable Metrics/ClassLength
|
5
|
-
def initialize(rule,
|
6
|
-
@re = ::FastIgnore::
|
5
|
+
def initialize(rule, expand_path_with: nil)
|
6
|
+
@re = ::FastIgnore::PathRegexpBuilder.new
|
7
7
|
@s = ::FastIgnore::GitignoreRuleScanner.new(rule)
|
8
8
|
|
9
|
-
@
|
9
|
+
@expand_path_with = expand_path_with
|
10
10
|
@negation = false
|
11
11
|
@anchored = false
|
12
12
|
@dir_only = false
|
@@ -49,6 +49,11 @@ class FastIgnore
|
|
49
49
|
@re.append_dir
|
50
50
|
end
|
51
51
|
|
52
|
+
def emit_any_dir
|
53
|
+
anchored!
|
54
|
+
@re.append_any_dir
|
55
|
+
end
|
56
|
+
|
52
57
|
def emit_end
|
53
58
|
@re.append_end_anchor
|
54
59
|
break!
|
@@ -60,11 +65,22 @@ class FastIgnore
|
|
60
65
|
@re.append_escaped(@s.next_character) || unmatchable_rule!
|
61
66
|
end
|
62
67
|
|
63
|
-
def process_star_end_after_slash
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
+
def process_star_end_after_slash # rubocop:disable Metrics/MethodLength
|
69
|
+
if @s.star_end?
|
70
|
+
@re.append_many_non_dir
|
71
|
+
emit_end
|
72
|
+
elsif @s.two_star_end?
|
73
|
+
break!
|
74
|
+
elsif @s.star_slash_end?
|
75
|
+
@re.append_many_non_dir
|
76
|
+
dir_only!
|
77
|
+
emit_end
|
78
|
+
elsif @s.two_star_slash_end?
|
79
|
+
dir_only!
|
80
|
+
break!
|
81
|
+
else
|
82
|
+
true
|
83
|
+
end
|
68
84
|
end
|
69
85
|
|
70
86
|
def process_slash
|
@@ -76,7 +92,7 @@ class FastIgnore
|
|
76
92
|
process_star_end_after_slash
|
77
93
|
end
|
78
94
|
|
79
|
-
def process_two_stars # rubocop:disable Metrics/
|
95
|
+
def process_two_stars # rubocop:disable Metrics/MethodLength
|
80
96
|
return unless @s.two_stars?
|
81
97
|
return break! if @s.end?
|
82
98
|
|
@@ -90,8 +106,7 @@ class FastIgnore
|
|
90
106
|
if nothing_emitted?
|
91
107
|
never_anchored!
|
92
108
|
else
|
93
|
-
|
94
|
-
anchored!
|
109
|
+
emit_any_dir
|
95
110
|
end
|
96
111
|
process_star_end_after_slash
|
97
112
|
end
|
@@ -141,6 +156,7 @@ class FastIgnore
|
|
141
156
|
end
|
142
157
|
|
143
158
|
def process_rule # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
159
|
+
expand_rule_path! if @expand_path_with
|
144
160
|
anchored! if @s.slash?
|
145
161
|
|
146
162
|
catch :break do
|
@@ -159,28 +175,24 @@ class FastIgnore
|
|
159
175
|
end
|
160
176
|
end
|
161
177
|
|
162
|
-
def prefix
|
163
|
-
out = ::FastIgnore::
|
164
|
-
|
165
|
-
|
166
|
-
out.
|
178
|
+
def prefix
|
179
|
+
out = ::FastIgnore::PathRegexpBuilder.new
|
180
|
+
|
181
|
+
if @anchored
|
182
|
+
out.append_start_anchor
|
167
183
|
else
|
168
|
-
|
169
|
-
out.append_start_anchor
|
170
|
-
else
|
171
|
-
out.append_start_dir_or_anchor
|
172
|
-
end
|
184
|
+
out.append_dir_or_start_anchor
|
173
185
|
end
|
174
186
|
out
|
175
187
|
end
|
176
188
|
|
177
189
|
def build_rule
|
178
190
|
@re.prepend(prefix)
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
191
|
+
if @negation
|
192
|
+
::FastIgnore::Matchers::AllowPathRegexp.new(@re.to_regexp, @anchored, @dir_only)
|
193
|
+
else
|
194
|
+
::FastIgnore::Matchers::IgnorePathRegexp.new(@re.to_regexp, @anchored, @dir_only)
|
195
|
+
end
|
184
196
|
end
|
185
197
|
|
186
198
|
def build
|
@@ -194,5 +206,16 @@ class FastIgnore
|
|
194
206
|
build_rule
|
195
207
|
end
|
196
208
|
end
|
209
|
+
|
210
|
+
def expand_rule_path!
|
211
|
+
anchored! unless @s.match?(/\*/) # rubocop:disable Performance/StringInclude # it's StringScanner#match?
|
212
|
+
return unless @s.match?(%r{(?:[~/]|\.{1,2}/|.*/\.\./)})
|
213
|
+
|
214
|
+
dir_only! if @s.match?(%r{.*/\s*\z})
|
215
|
+
|
216
|
+
@s.string.replace(PathExpander.expand_path(@s.rest, @expand_path_with))
|
217
|
+
@s.string.delete_prefix!(@expand_path_with)
|
218
|
+
@s.pos = 0
|
219
|
+
end
|
197
220
|
end
|
198
221
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
|
3
|
+
require 'set'
|
4
|
+
|
5
|
+
class FastIgnore
|
6
|
+
class GitignoreRuleGroup < ::FastIgnore::RuleGroup
|
7
|
+
def initialize(root)
|
8
|
+
@root = root
|
9
|
+
@loaded_paths = Set[root]
|
10
|
+
|
11
|
+
super([
|
12
|
+
::FastIgnore::Patterns.new('.git', root: '/'),
|
13
|
+
::FastIgnore::Patterns.new(from_file: ::FastIgnore::GlobalGitignore.path(root: root), root: root),
|
14
|
+
::FastIgnore::Patterns.new(from_file: "#{root}.git/info/exclude", root: root),
|
15
|
+
::FastIgnore::Patterns.new(from_file: "#{root}.gitignore", root: root)
|
16
|
+
], false)
|
17
|
+
end
|
18
|
+
|
19
|
+
def add_gitignore(dir)
|
20
|
+
return if @loaded_paths.include?(dir)
|
21
|
+
|
22
|
+
@loaded_paths << dir
|
23
|
+
matcher = ::FastIgnore::Patterns.new(from_file: "#{dir}.gitignore").build_matchers(allow: false)
|
24
|
+
@matchers += matcher unless !matcher || matcher.empty?
|
25
|
+
end
|
26
|
+
|
27
|
+
def add_gitignore_to_root(path)
|
28
|
+
add_gitignore(path) until @loaded_paths.include?(path = "#{::File.dirname(path)}/")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -42,6 +42,18 @@ class FastIgnore
|
|
42
42
|
skip(/\*\s*\z/)
|
43
43
|
end
|
44
44
|
|
45
|
+
def two_star_end?
|
46
|
+
skip(/\*{2,}\s*\z/)
|
47
|
+
end
|
48
|
+
|
49
|
+
def star_slash_end?
|
50
|
+
skip(%r{\*/\s*\z})
|
51
|
+
end
|
52
|
+
|
53
|
+
def two_star_slash_end?
|
54
|
+
skip(%r{\*{2,}/\s*\z})
|
55
|
+
end
|
56
|
+
|
45
57
|
def question_mark?
|
46
58
|
skip(/\?/)
|
47
59
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class FastIgnore
|
4
|
+
module Matchers
|
5
|
+
module AllowAnyDir
|
6
|
+
class << self
|
7
|
+
def squash_id
|
8
|
+
:allow_any_dir
|
9
|
+
end
|
10
|
+
|
11
|
+
def dir_only?
|
12
|
+
true
|
13
|
+
end
|
14
|
+
|
15
|
+
def file_only?
|
16
|
+
false
|
17
|
+
end
|
18
|
+
|
19
|
+
def squash(_)
|
20
|
+
self
|
21
|
+
end
|
22
|
+
|
23
|
+
def weight
|
24
|
+
0
|
25
|
+
end
|
26
|
+
|
27
|
+
# :nocov:
|
28
|
+
def inspect
|
29
|
+
'#<AllowAnyDir>'
|
30
|
+
end
|
31
|
+
# :nocov:
|
32
|
+
|
33
|
+
def match?(_)
|
34
|
+
:allow
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class FastIgnore
|
4
|
+
module Matchers
|
5
|
+
class AllowPathRegexp
|
6
|
+
attr_reader :dir_only
|
7
|
+
alias_method :dir_only?, :dir_only
|
8
|
+
undef :dir_only
|
9
|
+
|
10
|
+
attr_reader :squash_id
|
11
|
+
attr_reader :rule
|
12
|
+
|
13
|
+
def initialize(rule, squashable, dir_only)
|
14
|
+
@rule = rule
|
15
|
+
@dir_only = dir_only
|
16
|
+
@squashable = squashable
|
17
|
+
@squash_id = squashable ? :allow : object_id
|
18
|
+
|
19
|
+
freeze
|
20
|
+
end
|
21
|
+
|
22
|
+
def squash(list)
|
23
|
+
self.class.new(::Regexp.union(list.map(&:rule)), @squashable, @dir_only)
|
24
|
+
end
|
25
|
+
|
26
|
+
def file_only?
|
27
|
+
false
|
28
|
+
end
|
29
|
+
|
30
|
+
def weight
|
31
|
+
1
|
32
|
+
end
|
33
|
+
|
34
|
+
# :nocov:
|
35
|
+
def inspect
|
36
|
+
"#<AllowPathRegexp #{'dir_only ' if @dir_only}#{@rule.inspect}>"
|
37
|
+
end
|
38
|
+
# :nocov:
|
39
|
+
|
40
|
+
def match?(candidate)
|
41
|
+
:allow if @rule.match?(candidate.relative_path)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class FastIgnore
|
4
|
+
module Matchers
|
5
|
+
class IgnorePathRegexp
|
6
|
+
attr_reader :dir_only
|
7
|
+
alias_method :dir_only?, :dir_only
|
8
|
+
undef :dir_only
|
9
|
+
|
10
|
+
attr_reader :squash_id
|
11
|
+
attr_reader :rule
|
12
|
+
|
13
|
+
def initialize(rule, anchored, dir_only)
|
14
|
+
@rule = rule
|
15
|
+
@dir_only = dir_only
|
16
|
+
@anchored = anchored
|
17
|
+
@squash_id = anchored ? :ignore : object_id
|
18
|
+
|
19
|
+
freeze
|
20
|
+
end
|
21
|
+
|
22
|
+
def squash(list)
|
23
|
+
self.class.new(::Regexp.union(list.map(&:rule)), @anchored, @dir_only)
|
24
|
+
end
|
25
|
+
|
26
|
+
def file_only?
|
27
|
+
false
|
28
|
+
end
|
29
|
+
|
30
|
+
def weight
|
31
|
+
1
|
32
|
+
end
|
33
|
+
|
34
|
+
# :nocov:
|
35
|
+
def inspect
|
36
|
+
"#<IgnorePathRegexp #{'dir_only ' if @dir_only}#{@rule.inspect}>"
|
37
|
+
end
|
38
|
+
# :nocov:
|
39
|
+
|
40
|
+
def match?(candidate)
|
41
|
+
:ignore if @rule.match?(candidate.relative_path)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|