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
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class FastIgnore
|
4
|
+
module Matchers
|
5
|
+
class ShebangRegexp
|
6
|
+
attr_reader :squash_id
|
7
|
+
attr_reader :rule
|
8
|
+
|
9
|
+
def initialize(rule, negation)
|
10
|
+
@rule = rule
|
11
|
+
@return_value = negation ? :allow : :ignore
|
12
|
+
@squash_id = negation ? :allow_shebang : :ignore_shebang
|
13
|
+
|
14
|
+
freeze
|
15
|
+
end
|
16
|
+
|
17
|
+
def squash(list)
|
18
|
+
self.class.new(::Regexp.union(list.map(&:rule)), @return_value == :allow)
|
19
|
+
end
|
20
|
+
|
21
|
+
def file_only?
|
22
|
+
true
|
23
|
+
end
|
24
|
+
|
25
|
+
def dir_only?
|
26
|
+
false
|
27
|
+
end
|
28
|
+
|
29
|
+
# :nocov:
|
30
|
+
def inspect
|
31
|
+
"#<ShebangRegexp #{@return_value} /#{@rule.to_s[26..-4]}/>"
|
32
|
+
end
|
33
|
+
# :nocov:
|
34
|
+
|
35
|
+
def match?(candidate)
|
36
|
+
return false if candidate.filename.include?('.')
|
37
|
+
|
38
|
+
@return_value if candidate.first_line.match?(@rule)
|
39
|
+
end
|
40
|
+
|
41
|
+
def weight
|
42
|
+
2
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class FastIgnore
|
4
|
+
module Matchers
|
5
|
+
module Unmatchable
|
6
|
+
class << self
|
7
|
+
def dir_only?
|
8
|
+
false
|
9
|
+
end
|
10
|
+
|
11
|
+
def file_only?
|
12
|
+
false
|
13
|
+
end
|
14
|
+
|
15
|
+
def weight
|
16
|
+
0
|
17
|
+
end
|
18
|
+
|
19
|
+
# :nocov:
|
20
|
+
def inspect
|
21
|
+
'#<Unmatchable>'
|
22
|
+
end
|
23
|
+
# :nocov:
|
24
|
+
|
25
|
+
def match?(_)
|
26
|
+
false
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class FastIgnore
|
4
|
+
module Matchers
|
5
|
+
class WithinDir
|
6
|
+
attr_reader :weight
|
7
|
+
|
8
|
+
def initialize(matchers, root)
|
9
|
+
@dir_matchers = squash_matchers(matchers.reject(&:file_only?))
|
10
|
+
@file_matchers = squash_matchers(matchers.reject(&:dir_only?))
|
11
|
+
|
12
|
+
@weight = @dir_matchers.sum(&:weight) + @file_matchers.sum(&:weight)
|
13
|
+
@root = root
|
14
|
+
|
15
|
+
freeze
|
16
|
+
end
|
17
|
+
|
18
|
+
def match?(candidate)
|
19
|
+
relative_candidate = candidate.relative_to(@root)
|
20
|
+
return false unless relative_candidate
|
21
|
+
|
22
|
+
(candidate.directory? ? @dir_matchers : @file_matchers).reverse_each do |rule|
|
23
|
+
val = rule.match?(relative_candidate)
|
24
|
+
return val if val
|
25
|
+
end
|
26
|
+
|
27
|
+
false
|
28
|
+
end
|
29
|
+
|
30
|
+
def empty?
|
31
|
+
@dir_matchers.empty? && @file_matchers.empty?
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def squash_matchers(matchers)
|
37
|
+
return matchers if matchers.empty?
|
38
|
+
|
39
|
+
matchers -= [::FastIgnore::Matchers::Unmatchable]
|
40
|
+
return [::FastIgnore::Matchers::Unmatchable] if matchers.empty?
|
41
|
+
|
42
|
+
matchers.chunk_while { |a, b| a.squash_id == b.squash_id }.map do |chunk|
|
43
|
+
next chunk.first if chunk.length == 1
|
44
|
+
|
45
|
+
chunk.first.squash(chunk)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class FastIgnore
|
4
|
+
class PathRegexpBuilder
|
5
|
+
def initialize
|
6
|
+
@string = +''
|
7
|
+
end
|
8
|
+
|
9
|
+
def to_regexp
|
10
|
+
# Regexp::IGNORECASE = 1
|
11
|
+
::Regexp.new(@string, 1)
|
12
|
+
end
|
13
|
+
|
14
|
+
# String methods
|
15
|
+
|
16
|
+
def dup
|
17
|
+
out = super
|
18
|
+
|
19
|
+
@string = @string.dup
|
20
|
+
|
21
|
+
out
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_str
|
25
|
+
@string
|
26
|
+
end
|
27
|
+
alias_method :to_s, :to_str
|
28
|
+
|
29
|
+
def empty?
|
30
|
+
@string.empty?
|
31
|
+
end
|
32
|
+
|
33
|
+
def end_with?(str)
|
34
|
+
@string.end_with?(str)
|
35
|
+
end
|
36
|
+
|
37
|
+
def append(value)
|
38
|
+
@string.<<(value)
|
39
|
+
|
40
|
+
self
|
41
|
+
rescue FrozenError
|
42
|
+
# :nocov:
|
43
|
+
# the string seems to become inadvertently frozen in 2.5 and 2.6 with specific inputs
|
44
|
+
# and i don't understand why
|
45
|
+
# it seems like it's happening during the Regexp.new
|
46
|
+
# for some reason that i don't understand
|
47
|
+
@string = @string.dup
|
48
|
+
append(value)
|
49
|
+
# :nocov:
|
50
|
+
end
|
51
|
+
alias_method :<<, :append
|
52
|
+
|
53
|
+
def prepend(value)
|
54
|
+
@string.prepend(value)
|
55
|
+
|
56
|
+
self
|
57
|
+
rescue FrozenError
|
58
|
+
# :nocov:
|
59
|
+
# the string seems to become inadvertently frozen in 2.5 and 2.6 with specific inputs
|
60
|
+
# and i don't understand why
|
61
|
+
# it seems like it's happening during the Regexp.new
|
62
|
+
# for some reason that i don't understand
|
63
|
+
@string = @string.dup
|
64
|
+
prepend(value)
|
65
|
+
# :nocov:
|
66
|
+
end
|
67
|
+
|
68
|
+
# builder methods
|
69
|
+
|
70
|
+
def append_escaped(value)
|
71
|
+
return unless value
|
72
|
+
|
73
|
+
append(::Regexp.escape(value))
|
74
|
+
end
|
75
|
+
|
76
|
+
def append_dir
|
77
|
+
append('/')
|
78
|
+
end
|
79
|
+
|
80
|
+
def append_any_dir
|
81
|
+
append('(?:.*/)?')
|
82
|
+
end
|
83
|
+
|
84
|
+
def append_one_non_dir
|
85
|
+
append('[^/]')
|
86
|
+
end
|
87
|
+
|
88
|
+
def append_any_non_dir
|
89
|
+
append_one_non_dir
|
90
|
+
append('*')
|
91
|
+
end
|
92
|
+
|
93
|
+
def append_many_non_dir
|
94
|
+
append_one_non_dir
|
95
|
+
append('+')
|
96
|
+
end
|
97
|
+
|
98
|
+
def append_end_anchor
|
99
|
+
append('\\z')
|
100
|
+
end
|
101
|
+
|
102
|
+
def append_start_anchor
|
103
|
+
append('\\A')
|
104
|
+
end
|
105
|
+
|
106
|
+
def append_dir_or_start_anchor
|
107
|
+
append('(?:\\A|/)')
|
108
|
+
end
|
109
|
+
|
110
|
+
def append_dir_or_end_anchor
|
111
|
+
append('(?:/|\\z)')
|
112
|
+
end
|
113
|
+
|
114
|
+
def append_character_class_open
|
115
|
+
append('(?!/)[')
|
116
|
+
end
|
117
|
+
|
118
|
+
def append_character_class_negation
|
119
|
+
append('^')
|
120
|
+
end
|
121
|
+
|
122
|
+
def append_character_class_dash
|
123
|
+
append('-')
|
124
|
+
end
|
125
|
+
|
126
|
+
def append_character_class_close
|
127
|
+
append(']')
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
|
3
|
+
class FastIgnore
|
4
|
+
class Patterns
|
5
|
+
def initialize(*patterns, from_file: nil, format: :gitignore, root: nil)
|
6
|
+
if from_file
|
7
|
+
@root = root || ::File.dirname(from_file)
|
8
|
+
@patterns = ::File.exist?(from_file) ? ::File.readlines(from_file) : []
|
9
|
+
else
|
10
|
+
@root = root || ::Dir.pwd
|
11
|
+
@patterns = patterns.flatten.flat_map { |string| string.to_s.lines }
|
12
|
+
end
|
13
|
+
@root += '/' unless @root.end_with?('/')
|
14
|
+
@expand_path_with = (@root if format == :expand_path)
|
15
|
+
end
|
16
|
+
|
17
|
+
def build_matchers(allow: false) # rubocop:disable Metrics/MethodLength
|
18
|
+
matchers = @patterns.flat_map do |p|
|
19
|
+
::FastIgnore::Builders::ShebangOrGitignore.build(p, allow, expand_path_with: @expand_path_with)
|
20
|
+
end
|
21
|
+
|
22
|
+
return if matchers.empty?
|
23
|
+
return [::FastIgnore::Matchers::WithinDir.new(matchers, @root)] unless allow
|
24
|
+
|
25
|
+
[
|
26
|
+
::FastIgnore::Matchers::WithinDir.new(matchers, @root),
|
27
|
+
::FastIgnore::Matchers::WithinDir.new(
|
28
|
+
::FastIgnore::GitignoreIncludeRuleBuilder.new(@root).build_as_parent, '/'
|
29
|
+
)
|
30
|
+
]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
|
3
|
+
class FastIgnore
|
4
|
+
class RelativeCandidate
|
5
|
+
attr_reader :relative_path
|
6
|
+
|
7
|
+
def initialize(relative_path, root_candidate)
|
8
|
+
@relative_path = relative_path
|
9
|
+
@root_candidate = root_candidate
|
10
|
+
end
|
11
|
+
|
12
|
+
def filename
|
13
|
+
@root_candidate.filename
|
14
|
+
end
|
15
|
+
|
16
|
+
def first_line
|
17
|
+
@root_candidate.first_line
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class FastIgnore
|
4
|
+
class RuleGroup
|
5
|
+
def initialize(patterns, allow)
|
6
|
+
@matchers = Array(patterns).flat_map { |x| x.build_matchers(allow: allow) }.compact
|
7
|
+
@allow = allow
|
8
|
+
@allowed_recursive = { ::FastIgnore::Candidate.root.key => true }.compare_by_identity
|
9
|
+
end
|
10
|
+
|
11
|
+
def empty?
|
12
|
+
@matchers.empty? || @matchers.all?(&:empty?)
|
13
|
+
end
|
14
|
+
|
15
|
+
def weight
|
16
|
+
@matchers.sum(&:weight)
|
17
|
+
end
|
18
|
+
|
19
|
+
def freeze
|
20
|
+
@matchers.freeze
|
21
|
+
|
22
|
+
super
|
23
|
+
end
|
24
|
+
|
25
|
+
def allowed_recursive?(candidate)
|
26
|
+
@allowed_recursive.fetch(candidate.key) do
|
27
|
+
@allowed_recursive[candidate.key] =
|
28
|
+
allowed_recursive?(candidate.parent) &&
|
29
|
+
allowed_unrecursive?(candidate)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def allowed_unrecursive?(candidate)
|
34
|
+
@matchers.reverse_each do |matcher|
|
35
|
+
val = matcher.match?(candidate)
|
36
|
+
return val == :allow if val
|
37
|
+
end
|
38
|
+
|
39
|
+
not @allow
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class FastIgnore
|
4
|
+
class RuleGroups
|
5
|
+
def initialize( # rubocop:disable Metrics/ParameterLists, Metrics/AbcSize, Metrics/MethodLength
|
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
|
+
if gitignore
|
16
|
+
@gitignore_rule_group = ::FastIgnore::GitignoreRuleGroup.new(root)
|
17
|
+
@array << @gitignore_rule_group
|
18
|
+
end
|
19
|
+
@array << ::FastIgnore::RuleGroup.new(::FastIgnore::Patterns.new(ignore_rules, root: root), false).freeze
|
20
|
+
@array << ::FastIgnore::RuleGroup.new(::FastIgnore::Patterns.new(include_rules, root: root), true).freeze
|
21
|
+
@array << ::FastIgnore::RuleGroup.new(
|
22
|
+
::FastIgnore::Patterns.new(argv_rules, root: root, format: :expand_path),
|
23
|
+
true
|
24
|
+
).freeze
|
25
|
+
|
26
|
+
Array(ignore_files).each do |f|
|
27
|
+
path = PathExpander.expand_path(f, root)
|
28
|
+
@array << ::FastIgnore::RuleGroup.new(::FastIgnore::Patterns.new(from_file: path), false).freeze
|
29
|
+
end
|
30
|
+
Array(include_files).each do |f|
|
31
|
+
path = PathExpander.expand_path(f, root)
|
32
|
+
@array << ::FastIgnore::RuleGroup.new(::FastIgnore::Patterns.new(from_file: path), true).freeze
|
33
|
+
end
|
34
|
+
@array.reject!(&:empty?)
|
35
|
+
@array.sort_by!(&:weight)
|
36
|
+
@array.freeze
|
37
|
+
end
|
38
|
+
|
39
|
+
def allowed_recursive?(candidate)
|
40
|
+
@array.all? { |r| r.allowed_recursive?(candidate) }
|
41
|
+
end
|
42
|
+
|
43
|
+
def allowed_unrecursive?(candidate)
|
44
|
+
@array.all? { |r| r.allowed_unrecursive?(candidate) }
|
45
|
+
end
|
46
|
+
|
47
|
+
def add_gitignore(dir)
|
48
|
+
@gitignore_rule_group.add_gitignore(dir)
|
49
|
+
end
|
50
|
+
|
51
|
+
def add_gitignore_to_root(path)
|
52
|
+
@gitignore_rule_group.add_gitignore_to_root(path)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
data/lib/fast_ignore/version.rb
CHANGED
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
|
3
|
+
class FastIgnore
|
4
|
+
module Walkers
|
5
|
+
class Base
|
6
|
+
def initialize(rule_groups, follow_symlinks:)
|
7
|
+
warn 'FastIgnore deprecation: follow_symlinks argument is deprecated' if follow_symlinks
|
8
|
+
|
9
|
+
@follow_symlinks = follow_symlinks
|
10
|
+
@rule_groups = rule_groups
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def directory?(full_path, directory)
|
16
|
+
if !directory.nil?
|
17
|
+
directory
|
18
|
+
elsif @follow_symlinks
|
19
|
+
::File.stat(full_path).directory?
|
20
|
+
else
|
21
|
+
::File.lstat(full_path).directory?
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
|
3
|
+
class FastIgnore
|
4
|
+
module Walkers
|
5
|
+
class FileSystem < Base
|
6
|
+
def allowed?(path, root: Dir.pwd, directory: nil, content: nil, exists: nil, include_directories: false) # rubocop:disable Metrics/MethodLength, Metrics/ParameterLists
|
7
|
+
full_path = PathExpander.expand_path(path, root)
|
8
|
+
return false unless full_path.start_with?(root)
|
9
|
+
|
10
|
+
begin
|
11
|
+
dir = directory?(full_path, directory)
|
12
|
+
rescue ::Errno::ENOENT, ::Errno::EACCES, ::Errno::ELOOP, ::Errno::ENAMETOOLONG
|
13
|
+
nil
|
14
|
+
end
|
15
|
+
|
16
|
+
return false if !include_directories && dir
|
17
|
+
|
18
|
+
candidate = ::FastIgnore::Candidate.new(full_path, nil, dir, exists, content)
|
19
|
+
|
20
|
+
return false unless candidate.exists?
|
21
|
+
|
22
|
+
@rule_groups.allowed_recursive?(candidate)
|
23
|
+
end
|
24
|
+
|
25
|
+
def each(parent_full_path, parent_relative_path, &block) # rubocop:disable Metrics/MethodLength
|
26
|
+
::Dir.children(parent_full_path).each do |filename|
|
27
|
+
full_path = parent_full_path + filename
|
28
|
+
dir = directory?(full_path, nil)
|
29
|
+
candidate = ::FastIgnore::Candidate.new(full_path, filename, dir, true, nil)
|
30
|
+
|
31
|
+
next unless @rule_groups.allowed_unrecursive?(candidate)
|
32
|
+
|
33
|
+
relative_path = parent_relative_path + filename
|
34
|
+
|
35
|
+
if dir
|
36
|
+
each(full_path + '/', relative_path + '/', &block)
|
37
|
+
else
|
38
|
+
yield(relative_path)
|
39
|
+
end
|
40
|
+
rescue ::Errno::ENOENT, ::Errno::EACCES, ::Errno::ENOTDIR, ::Errno::ELOOP, ::Errno::ENAMETOOLONG
|
41
|
+
nil
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
|
3
|
+
class FastIgnore
|
4
|
+
module Walkers
|
5
|
+
class GitignoreCollectingFileSystem < Base
|
6
|
+
def allowed?(path, root: Dir.pwd, directory: nil, content: nil, exists: nil, include_directories: false) # rubocop:disable Metrics/ParameterLists
|
7
|
+
full_path = PathExpander.expand_path(path, root)
|
8
|
+
return false unless full_path.start_with?(root)
|
9
|
+
|
10
|
+
candidate = ::FastIgnore::Candidate.new(full_path, nil, directory, exists, content)
|
11
|
+
|
12
|
+
begin
|
13
|
+
return false if !include_directories && directory?(full_path, directory)
|
14
|
+
rescue ::Errno::ENOENT, ::Errno::EACCES, ::Errno::ELOOP, ::Errno::ENAMETOOLONG
|
15
|
+
# nil
|
16
|
+
end
|
17
|
+
|
18
|
+
return false unless candidate.exists?
|
19
|
+
|
20
|
+
@rule_groups.add_gitignore_to_root(full_path)
|
21
|
+
@rule_groups.allowed_recursive?(candidate)
|
22
|
+
end
|
23
|
+
|
24
|
+
def each(parent_full_path, parent_relative_path, &block) # rubocop:disable Metrics/MethodLength
|
25
|
+
children = ::Dir.children(parent_full_path)
|
26
|
+
@rule_groups.add_gitignore(parent_full_path) if children.include?('.gitignore')
|
27
|
+
|
28
|
+
children.each do |filename|
|
29
|
+
full_path = parent_full_path + filename
|
30
|
+
dir = directory?(full_path, nil)
|
31
|
+
candidate = ::FastIgnore::Candidate.new(full_path, filename, dir, true, nil)
|
32
|
+
|
33
|
+
next unless @rule_groups.allowed_unrecursive?(candidate)
|
34
|
+
|
35
|
+
relative_path = parent_relative_path + filename
|
36
|
+
|
37
|
+
if dir
|
38
|
+
each(full_path + '/', relative_path + '/', &block)
|
39
|
+
else
|
40
|
+
yield(relative_path)
|
41
|
+
end
|
42
|
+
rescue ::Errno::ENOENT, ::Errno::EACCES, ::Errno::ENOTDIR, ::Errno::ELOOP, ::Errno::ENAMETOOLONG
|
43
|
+
nil
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|