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.
- 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
|