fast_ignore 0.16.1 → 0.17.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7952045a743c12fa1963ffba7aa81a8ca3cc81aec40b0bfc9c0e6bb6424e9433
4
- data.tar.gz: dcacd0bdd1873638156c9b2323263cf1ee7fc349b012f40c28caa4fe10d82f91
3
+ metadata.gz: 56582bce9b3eae6e761585c77846530bb96b287c2d6938dd7213c31b84567560
4
+ data.tar.gz: c2aabc49876831524acc8f14bc483aa8ec44ec715941a562bf4a6d5c4ac76b5c
5
5
  SHA512:
6
- metadata.gz: 35c9fedb895b3e30632b29aab2eba3369ec6512bd6c5b9cfa563156c4c0c291b5c7854877aa4c8da063b54ed97a6f132c5d903622d2a6e2fc69c57c708150c33
7
- data.tar.gz: ca894c9a8e11471d3c1f81f959862cd16a60db784898ef0d0e4da880e063257334fdf6aad061d95c23850c726ffde781076e6c248ebecfa808701d0731fbb125
6
+ metadata.gz: bc5e6b69f903bf2bb0beed6001bfa01bfa2f8b7e452eca9270884a38a1924649e336866d94085bd59ff72549d495d3857035227a7b3b0cf22859fd939c1e32ac
7
+ data.tar.gz: e286d5802e0a0857552b9c9dbe03999546817478f2960fdbd057709485a862e876e3e9328a12fafc34388ba1aad0893f10ea318e7bdff728fb3ef41facc1568a
data/CHANGELOG.md CHANGED
@@ -1,3 +1,19 @@
1
+ # v0.17.2
2
+ - Remove unnecessary backport code that was leftover when support for 2.4 was dropped
3
+ - Tiny performance improvements from rubocop-performance's suggestions
4
+
5
+ # v0.17.1
6
+ - fix handling of backward character classes `[z-a]`
7
+ previously this raised a RegexpError, but git just considered it to be identical to `[z]`, now we match the git behaviour (but why would you ever do this?, i only found it because of the fuzz spec in the `leftovers` gem)
8
+
9
+ # v0.17.0
10
+ - allow overriding `exists:` in `allowed?`
11
+ - allow setting `include_directories: true` in `allowed?`
12
+ - subsequent calls to `allowed?` with the same path but different `directory:` or `content:` arguments won't potentially mess up the cache
13
+ - slight performance improvements of the shebang rule matcher loading the first line
14
+ - drop support for ruby 2.4
15
+ - add ruby 3.1 to the test matrix
16
+
1
17
  # v0.16.1
2
18
  - respect GIT_CONFIG_SYSTEM, GIT_CONFIG_NOSYSTEM and GIT_CONFIG_GLOBAL env vars the same way git does
3
19
  - make the tests more resilient to whatever global config is going on.
data/README.md CHANGED
@@ -15,7 +15,7 @@ FastIgnore.new(relative: true).sort == `git ls-files`.split("\n").sort
15
15
  ## Features
16
16
 
17
17
  - Fast (faster than using `` `git ls-files`.split("\n") `` for small repos (because it avoids the overhead of ``` `` ```))
18
- - Supports ruby 2.4-3.0.x & jruby
18
+ - Supports ruby 2.5-3.1.x & jruby
19
19
  - supports all [gitignore rule patterns](https://git-scm.com/docs/gitignore#_pattern_format)
20
20
  - doesn't require git to be installed
21
21
  - supports a gitignore-esque "include" patterns. ([`include_rules:`](#include_rules)/[`include_files:`](#include_files))
@@ -81,20 +81,79 @@ Relative paths will be considered relative to the [`root:`](#root) directory, no
81
81
 
82
82
  This is aliased as `===` so you can use a FastIgnore instance in case statements.
83
83
  ```ruby
84
+ @path_matcher ||= FastIgnore.new
85
+
84
86
  case my_path
85
- when FastIgnore.new
87
+ when @path_matcher
86
88
  puts(my_path)
87
89
  end
88
90
  ```
89
91
 
90
92
  It's recommended to save the FastIgnore instance to a variable to avoid having to read and parse the gitignore file and gitconfig files repeatedly.
91
93
 
92
- See [Optimising allowed](#optimising_allowed) for ways to make this even faster
94
+ #### directory: true/false/nil
95
+
96
+ If your code already knows the path to test is/not a directory or wants to lie about whether it is/is not a directory, you can pass `directory: true` or `directory: false` as an argument to `allowed?` (to have FastIgnore ask the file system, you can pass `directory: nil` or nothing)
97
+
98
+ ```
99
+ FastIgnore.new.allowed?('relative/path', directory: false) # matches `path` as a file
100
+ FastIgnore.new.allowed?('relative/path', directory: true) # matches `path` as a directory
101
+ FastIgnore.new.allowed?('relative/path', directory: nil) # matches path as whatever it is on the filesystem
102
+ FastIgnore.new.allowed?('relative/path) # or as a file if it doesn't exist on the file system
103
+ ```
104
+
105
+ #### content: true/false/nil
106
+
107
+ default: `nil`
108
+
109
+ If your code already knows the path to test is has a particular text content or wants to lie about the content, you can pass `directory: true` or `directory: false` as an argument to `allowed?` (to have FastIgnore ask the file system, you can pass `directory: nil` or nothing)
110
+
111
+ ```
112
+ FastIgnore.new.allowed?('relative/path', content: "#!/usr/bin/env ruby\n\nputs 'hello'") # matches ruby shebang
113
+ FastIgnore.new.allowed?('relative/path', content: "#!/usr/bin/env bash\n\necho 'hello'") # matches bash shebang
114
+ FastIgnore.new.allowed?('relative/path', content: nil) # matches path as whatever content is on the filesystem
115
+ FastIgnore.new.allowed?('relative/path) # or as an empty file if it doesn't actually exist
116
+ ```
117
+
118
+ #### content: true/false/nil
119
+
120
+ default: `nil`
121
+
122
+ If your code already knows the path to test is has a particular text content or wants to lie about the content, you can pass `directory: true` or `directory: false` as an argument to `allowed?` (to have FastIgnore ask the file system, you can pass `directory: nil` or nothing)
123
+
124
+ ```
125
+ FastIgnore.new.allowed?('relative/path', content: "#!/usr/bin/env ruby\n\nputs 'hello'") # matches ruby shebang
126
+ FastIgnore.new.allowed?('relative/path', content: "#!/usr/bin/env bash\n\necho 'hello'") # matches bash shebang
127
+ FastIgnore.new.allowed?('relative/path', content: nil) # matches path as whatever content is on the filesystem
128
+ FastIgnore.new.allowed?('relative/path) # or as an empty file if it doesn't actually exist
129
+ ```
93
130
 
94
- **Note: A file must exist at that path and not be a directory for it to be considered allowed.**
95
- Essentially it can be thought of as `` `git ls-files`.include?(path) `` but much faster.
96
- This excludes all directories and all possible path names that don't exist.
131
+ #### exist: true/false/nil
97
132
 
133
+ default: `nil`
134
+
135
+ If your code already knows the path to test exists or wants to lie about its existence, you can pass `exists: true` or `exists: false` as an argument to `allowed?` (to have FastIgnore ask the file system, you can pass `exists: nil` or nothing)
136
+
137
+ ```
138
+ FastIgnore.new.allowed?('relative/path', exists: true) # will check the path regardless of whether it actually truly exists
139
+ FastIgnore.new.allowed?('relative/path', exists: false) # will always return false
140
+ FastIgnore.new.allowed?('relative/path', exists: nil) # asks the filesystem
141
+ FastIgnore.new.allowed?('relative/path) # asks the filesystem
142
+ ```
143
+
144
+ #### include_directories: true/false
145
+
146
+ default: `false`
147
+
148
+ By default a file must not be a directory for it to be considered allowed. This is intended to match the behaviour of `git ls-files` which only lists files.
149
+
150
+ To match directories you can pass `include_directories: true` to `allowed?`
151
+
152
+ ```
153
+ FastIgnore.new.allowed?('relative/path', include_directories: true) # will test the path even if it's a directory
154
+ FastIgnore.new.allowed?('relative/path', include_directories: false) # will always return false if the path is a directory
155
+ FastIgnore.new.allowed?('relative/path) # will always return false if the path is a directory
156
+ ```
98
157
 
99
158
  ### `relative: true`
100
159
 
@@ -293,15 +352,6 @@ FastIgnore.new(argv_rules: ["my/rule", File.read('/my/path')]).to_a
293
352
  ```
294
353
 
295
354
  This does unfortunately lose the file path as the root `/` and there is no workaround except setting the [`root:`](#root) for the whole FastIgnore instance.
296
-
297
- ### optimising #allowed?
298
-
299
- To avoid unnecessary calls to the filesystem, if your code already knows whether or not it's a directory, or if you're checking shebangs and you have already read the content of the file: use
300
- ```ruby
301
- FastIgnore.new.allowed?('relative/path', directory: false, content: "#!/usr/bin/ruby\n\nputs 'ok'\n")
302
- ```
303
- This is not required, and if FastIgnore does have to go to the filesystem for this information it's well optimised to only read what is necessary.
304
-
305
355
  ## Limitations
306
356
  - Doesn't know what to do if you change the current working directory inside the [`FastIgnore#each`](#each_map_etc) block.
307
357
  So don't do that.
@@ -2,10 +2,6 @@
2
2
 
3
3
  class FastIgnore
4
4
  class FileRoot
5
- # :nocov:
6
- using ::FastIgnore::Backports::DeletePrefixSuffix if defined?(::FastIgnore::Backports::DeletePrefixSuffix)
7
- # :nocov:
8
-
9
5
  def self.build(file_path, project_root)
10
6
  file_root = "#{::File.dirname(file_path)}/".delete_prefix(project_root)
11
7
 
@@ -100,9 +100,8 @@ class FastIgnore
100
100
 
101
101
  def on_branch?(branch_pattern)
102
102
  branch_pattern += '**' if branch_pattern.end_with?('/')
103
- current_branch = ::File.readable?("#{root}/.git/HEAD") && ::File.read("#{root}/.git/HEAD").sub!(
104
- %r{\Aref: refs/heads/}, ''
105
- )
103
+ current_branch = ::File.readable?("#{root}/.git/HEAD") &&
104
+ ::File.read("#{root}/.git/HEAD").delete_prefix('ref: refs/heads/')
106
105
  return unless current_branch
107
106
 
108
107
  # goddamit git what does 'a pattern with standard globbing wildcards' mean
@@ -2,10 +2,6 @@
2
2
 
3
3
  class FastIgnore
4
4
  class GitignoreIncludeRuleBuilder < GitignoreRuleBuilder
5
- # :nocov:
6
- using ::FastIgnore::Backports::DeletePrefixSuffix if defined?(::FastIgnore::Backports::DeletePrefixSuffix)
7
- # :nocov:
8
-
9
5
  def initialize(rule, file_path, expand_path_from = nil)
10
6
  super(rule, file_path)
11
7
 
@@ -15,7 +11,7 @@ class FastIgnore
15
11
  end
16
12
 
17
13
  def expand_rule_path
18
- anchored! unless @s.match?(/\*/)
14
+ anchored! unless @s.match?(/\*/) # rubocop:disable Performance/StringInclude # it's StringScanner#match?
19
15
  return unless @s.match?(%r{(?:[~/]|\.{1,2}/|.*/\.\./)})
20
16
 
21
17
  dir_only! if @s.match?(%r{.*/\s*\z})
@@ -108,8 +108,8 @@ class FastIgnore
108
108
  unmatchable_rule! if @s.character_class_end?
109
109
 
110
110
  until @s.character_class_end?
111
+ next if process_character_class_range
111
112
  next if process_backslash
112
- next @re.append_character_class_dash if @s.dash?
113
113
  next if @re.append_escaped(@s.character_class_literal)
114
114
 
115
115
  unmatchable_rule!
@@ -118,6 +118,22 @@ class FastIgnore
118
118
  @re.append_character_class_close
119
119
  end
120
120
 
121
+ def process_character_class_range
122
+ start = @s.character_class_range_start
123
+ return unless start
124
+
125
+ start = start.delete_prefix('\\')
126
+
127
+ @re.append_escaped(start)
128
+
129
+ finish = @s.character_class_range_end.delete_prefix('\\')
130
+
131
+ return true unless start < finish
132
+
133
+ @re.append_character_class_dash
134
+ @re.append_escaped(finish)
135
+ end
136
+
121
137
  def process_end
122
138
  blank! if nothing_emitted?
123
139
 
@@ -46,12 +46,20 @@ class FastIgnore
46
46
  skip(/\?/)
47
47
  end
48
48
 
49
- def dash?
50
- skip(/-/)
49
+ def character_class_literal
50
+ matched if scan(/[^\]\\][^\]\\-]*(?!-)/)
51
51
  end
52
52
 
53
- def character_class_literal
54
- matched if scan(/[^\]\-\\]+/)
53
+ def character_class_range_start
54
+ matched if scan(/(\\.|[^\\\]])(?=-(\\.|[^\\\]]))/)
55
+ end
56
+
57
+ def character_class_range_end
58
+ # we already confirmed this was going to match
59
+ # with the lookahead in character_class_range_start
60
+ skip(/-/)
61
+ scan(/(\\.|[^\\\]])/)
62
+ matched
55
63
  end
56
64
 
57
65
  def literal
@@ -3,10 +3,6 @@
3
3
  class FastIgnore
4
4
  module RuleBuilder
5
5
  class << self
6
- # :nocov:
7
- using ::FastIgnore::Backports::DeletePrefixSuffix if defined?(::FastIgnore::Backports::DeletePrefixSuffix)
8
- # :nocov:
9
-
10
6
  def build(rule, allow, expand_path_with, file_root)
11
7
  if rule.delete_prefix!('#!:')
12
8
  shebang_rules(rule, allow, file_root)
@@ -23,7 +19,7 @@ class FastIgnore
23
19
  rule = ::FastIgnore::ShebangRule.new(pattern, allow, file_root&.shebang_path_pattern)
24
20
  return rule unless allow
25
21
 
26
- rules = gitignore_rules('*/'.dup, allow, file_root)
22
+ rules = gitignore_rules(+'*/', allow, file_root)
27
23
  rules.pop # don't want the include all children one.
28
24
  rules << rule
29
25
  rules
@@ -11,7 +11,7 @@ class FastIgnore
11
11
  @file_rules = (squash ? squash_rules(rules.reject(&:dir_only?)) : rules.reject(&:dir_only?)).freeze
12
12
  @has_shebang_rules = rules.any?(&:shebang?)
13
13
 
14
- @allowed_recursive = { '.' => true }
14
+ @allowed_recursive = { ['.', true, nil] => true }
15
15
  @allow = allow
16
16
  @gitignore = gitignore
17
17
 
@@ -27,8 +27,8 @@ class FastIgnore
27
27
  end
28
28
 
29
29
  def allowed_recursive?(relative_path, dir, full_path, filename, content = nil)
30
- @allowed_recursive.fetch(relative_path) do
31
- @allowed_recursive[relative_path] =
30
+ @allowed_recursive.fetch([relative_path, dir, content]) do |key|
31
+ @allowed_recursive[key] =
32
32
  allowed_recursive?(::File.dirname(relative_path), true, nil, nil, nil) &&
33
33
  allowed_unrecursive?(relative_path, dir, full_path, filename, content)
34
34
  end
@@ -2,10 +2,6 @@
2
2
 
3
3
  class FastIgnore
4
4
  class RuleSets
5
- # :nocov:
6
- using ::FastIgnore::Backports::DeletePrefixSuffix if defined?(::FastIgnore::Backports::DeletePrefixSuffix)
7
- # :nocov:
8
-
9
5
  def initialize( # rubocop:disable Metrics/ParameterLists
10
6
  root:,
11
7
  ignore_rules: nil,
@@ -27,8 +23,8 @@ class FastIgnore
27
23
  @array.freeze if @gitignore_rule_set
28
24
  end
29
25
 
30
- def allowed_recursive?(relative_path, full_path, filename, content)
31
- @array.all? { |r| r.allowed_recursive?(relative_path, false, full_path, filename, content) }
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) }
32
28
  end
33
29
 
34
30
  def allowed_unrecursive?(relative_path, dir, full_path, filename)
@@ -61,12 +61,9 @@ class FastIgnore
61
61
 
62
62
  def first_line(path) # rubocop:disable Metrics/MethodLength
63
63
  file = ::File.new(path)
64
- first_line = new_fragment = file.sysread(64)
64
+ first_line = file.sysread(64)
65
65
  if first_line.start_with?('#!')
66
- until new_fragment.include?("\n")
67
- new_fragment = file.sysread(64)
68
- first_line += new_fragment
69
- end
66
+ first_line += file.readline unless first_line.include?("\n")
70
67
  else
71
68
  file.close
72
69
  return
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class FastIgnore
4
- VERSION = '0.16.1'
4
+ VERSION = '0.17.2'
5
5
  end
data/lib/fast_ignore.rb CHANGED
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative './fast_ignore/backports'
4
-
5
3
  require 'set'
6
4
  require 'strscan'
7
5
 
@@ -24,11 +22,6 @@ class FastIgnore
24
22
 
25
23
  include ::Enumerable
26
24
 
27
- # :nocov:
28
- using ::FastIgnore::Backports::DeletePrefixSuffix if defined?(::FastIgnore::Backports::DeletePrefixSuffix)
29
- using ::FastIgnore::Backports::DirEachChild if defined?(::FastIgnore::Backports::DirEachChild)
30
- # :nocov:
31
-
32
25
  def initialize(relative: false, root: nil, gitignore: :auto, follow_symlinks: false, **rule_set_builder_args)
33
26
  @relative = relative
34
27
  @follow_symlinks_method = ::File.method(follow_symlinks ? :stat : :lstat)
@@ -41,7 +34,7 @@ class FastIgnore
41
34
  end
42
35
 
43
36
  def each(&block)
44
- return enum_for(:each) unless block_given?
37
+ return enum_for(:each) unless block
45
38
 
46
39
  dir_pwd = ::Dir.pwd
47
40
  root_from_pwd = @root.start_with?(dir_pwd) ? ".#{@root.delete_prefix(dir_pwd)}" : @root
@@ -49,19 +42,30 @@ class FastIgnore
49
42
  each_recursive(root_from_pwd, '', &block)
50
43
  end
51
44
 
52
- def allowed?(path, directory: nil, content: nil)
45
+ def allowed?(path, directory: nil, content: nil, exists: nil, include_directories: false) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
53
46
  full_path = ::File.expand_path(path, @root)
54
47
  return false unless full_path.start_with?(@root)
55
- return false if directory.nil? ? @follow_symlinks_method.call(full_path).directory? : directory
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
56
61
 
57
62
  relative_path = full_path.delete_prefix(@root)
58
63
  load_gitignore_recursive(relative_path) if @gitignore_enabled
59
64
 
60
65
  filename = ::File.basename(relative_path)
66
+ content = content.slice(/.*/) if content # we only care about the first line
61
67
 
62
- @rule_sets.allowed_recursive?(relative_path, full_path, filename, content)
63
- rescue ::Errno::ENOENT, ::Errno::EACCES, ::Errno::ENOTDIR, ::Errno::ELOOP, ::Errno::ENAMETOOLONG
64
- false
68
+ @rule_sets.allowed_recursive?(relative_path, directory, full_path, filename, content)
65
69
  end
66
70
  alias_method :===, :allowed?
67
71
 
@@ -77,7 +81,7 @@ class FastIgnore
77
81
  paths << path
78
82
  end
79
83
 
80
- paths.reverse_each(&method(:load_gitignore))
84
+ paths.reverse_each { |p| load_gitignore(p) }
81
85
  end
82
86
 
83
87
  def load_gitignore(parent_path, check_exists: true)
@@ -93,21 +97,19 @@ class FastIgnore
93
97
  load_gitignore(parent_relative_path, check_exists: false) if @gitignore_enabled && children.include?('.gitignore')
94
98
 
95
99
  children.each do |filename|
96
- begin
97
- full_path = parent_full_path + filename
98
- relative_path = parent_relative_path + filename
99
- dir = @follow_symlinks_method.call(full_path).directory?
100
-
101
- next unless @rule_sets.allowed_unrecursive?(relative_path, dir, full_path, filename)
102
-
103
- if dir
104
- each_recursive(full_path + '/', relative_path + '/', &block)
105
- else
106
- yield(@relative ? relative_path : @root + relative_path)
107
- end
108
- rescue ::Errno::ENOENT, ::Errno::EACCES, ::Errno::ENOTDIR, ::Errno::ELOOP, ::Errno::ENAMETOOLONG
109
- nil
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
110
  end
111
+ rescue ::Errno::ENOENT, ::Errno::EACCES, ::Errno::ENOTDIR, ::Errno::ELOOP, ::Errno::ENAMETOOLONG
112
+ nil
111
113
  end
112
114
  end
113
115
  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.16.1
4
+ version: 0.17.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dana Sherson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-12-11 00:00:00.000000000 Z
11
+ date: 2022-03-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -100,6 +100,20 @@ dependencies:
100
100
  - - "<"
101
101
  - !ruby/object:Gem::Version
102
102
  version: '1.12'
103
+ - !ruby/object:Gem::Dependency
104
+ name: rubocop-performance
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
103
117
  - !ruby/object:Gem::Dependency
104
118
  name: rubocop-rake
105
119
  requirement: !ruby/object:Gem::Requirement
@@ -181,7 +195,6 @@ files:
181
195
  - LICENSE.txt
182
196
  - README.md
183
197
  - lib/fast_ignore.rb
184
- - lib/fast_ignore/backports.rb
185
198
  - lib/fast_ignore/file_root.rb
186
199
  - lib/fast_ignore/gitconfig_parser.rb
187
200
  - lib/fast_ignore/gitignore_include_rule_builder.rb
@@ -211,14 +224,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
211
224
  requirements:
212
225
  - - ">="
213
226
  - !ruby/object:Gem::Version
214
- version: 2.4.0
227
+ version: 2.5.0
215
228
  required_rubygems_version: !ruby/object:Gem::Requirement
216
229
  requirements:
217
230
  - - ">="
218
231
  - !ruby/object:Gem::Version
219
232
  version: '0'
220
233
  requirements: []
221
- rubygems_version: 3.2.15
234
+ rubygems_version: 3.1.6
222
235
  signing_key:
223
236
  specification_version: 4
224
237
  summary: Parse gitignore files, quickly
@@ -1,66 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class FastIgnore
4
- module Backports
5
- ruby_major, ruby_minor = ::RUBY_VERSION.split('.', 2)
6
- unless ruby_major.to_i > 2 || ruby_major.to_i == 2 && ruby_minor.to_i > 5
7
- module DirEachChild
8
- refine ::Dir.singleton_class do
9
- def children(path)
10
- ::Dir.entries(path) - ['.', '..']
11
- end
12
- end
13
- end
14
-
15
- module DeletePrefixSuffix
16
- refine ::String do
17
- # delete_prefix!(prefix) -> self or nil
18
- # Deletes leading prefix from str, returning nil if no change was made.
19
- #
20
- # "hello".delete_prefix!("hel") #=> "lo"
21
- # "hello".delete_prefix!("llo") #=> nil
22
- def delete_prefix!(str)
23
- return unless start_with?(str)
24
-
25
- slice!(0..(str.length - 1))
26
- self
27
- end
28
-
29
- # delete_suffix!(suffix) -> self or nil
30
- # Deletes trailing suffix from str, returning nil if no change was made.
31
- #
32
- # "hello".delete_suffix!("llo") #=> "he"
33
- # "hello".delete_suffix!("hel") #=> nil
34
- def delete_suffix!(str)
35
- return unless end_with?(str)
36
-
37
- slice!(-str.length..-1)
38
- self
39
- end
40
-
41
- # delete_prefix(prefix) -> new_str click to toggle source
42
- # Returns a copy of str with leading prefix deleted.
43
- #
44
- # "hello".delete_prefix("hel") #=> "lo"
45
- # "hello".delete_prefix("llo") #=> "hello"
46
- def delete_prefix(str)
47
- s = dup
48
- s.delete_prefix!(str)
49
- s
50
- end
51
-
52
- # delete_suffix(suffix) -> new_str
53
- # Returns a copy of str with trailing suffix deleted.
54
- #
55
- # "hello".delete_suffix("llo") #=> "he"
56
- # "hello".delete_suffix("hel") #=> "hello"
57
- def delete_suffix(str) # leftovers:allowed
58
- s = dup
59
- s.delete_suffix!(str)
60
- s
61
- end
62
- end
63
- end
64
- end
65
- end
66
- end