fast_ignore 0.16.1 → 0.17.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/README.md +65 -15
- data/lib/fast_ignore/rule_set.rb +3 -3
- data/lib/fast_ignore/rule_sets.rb +2 -2
- data/lib/fast_ignore/shebang_rule.rb +2 -5
- data/lib/fast_ignore/version.rb +1 -1
- data/lib/fast_ignore.rb +29 -20
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 78cb85cea0888d67c91de09bd54ad644510167c993dc355d187593003d341393
|
4
|
+
data.tar.gz: fb1fda9c1675ee28f4a6ff23191f95c2dd6e497ca2a70c4791dc5dfb85baecd1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 10531a1d819b74fcc442ce7591be124430d3c55c55afbccb79ba295dd89c0e85e4a1a0a75b11996557057fa2f5dbad71e9284789143395d229e3abbbbd42ba3c
|
7
|
+
data.tar.gz: d0b07a2757c3b962a59973581234ec9e346717d24cdbd5443073c0fd14f840fb287419d63eeb31d4aa52d3fff2e1c0842cc119ed52e836cd55ed73bcd29a3fc7
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
# v0.17.0
|
2
|
+
- allow overriding `exists:` in `allowed?`
|
3
|
+
- allow setting `include_directories: true` in `allowed?`
|
4
|
+
- subsequent calls to `allowed?` with the same path but different `directory:` or `content:` arguments won't potentially mess up the cache
|
5
|
+
- slight performance improvements of the shebang rule matcher loading the first line
|
6
|
+
- drop support for ruby 2.4
|
7
|
+
- add ruby 3.1 to the test matrix
|
8
|
+
|
1
9
|
# v0.16.1
|
2
10
|
- respect GIT_CONFIG_SYSTEM, GIT_CONFIG_NOSYSTEM and GIT_CONFIG_GLOBAL env vars the same way git does
|
3
11
|
- 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.
|
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
|
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
|
-
|
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
|
-
|
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.
|
data/lib/fast_ignore/rule_set.rb
CHANGED
@@ -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[
|
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
|
@@ -27,8 +27,8 @@ class FastIgnore
|
|
27
27
|
@array.freeze if @gitignore_rule_set
|
28
28
|
end
|
29
29
|
|
30
|
-
def allowed_recursive?(relative_path, full_path, filename, content)
|
31
|
-
@array.all? { |r| r.allowed_recursive?(relative_path,
|
30
|
+
def allowed_recursive?(relative_path, dir, full_path, filename, content)
|
31
|
+
@array.all? { |r| r.allowed_recursive?(relative_path, dir, full_path, filename, content) }
|
32
32
|
end
|
33
33
|
|
34
34
|
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 =
|
64
|
+
first_line = file.sysread(64)
|
65
65
|
if first_line.start_with?('#!')
|
66
|
-
|
67
|
-
new_fragment = file.sysread(64)
|
68
|
-
first_line += new_fragment
|
69
|
-
end
|
66
|
+
first_line += file.readline unless first_line.match?(/\n/)
|
70
67
|
else
|
71
68
|
file.close
|
72
69
|
return
|
data/lib/fast_ignore/version.rb
CHANGED
data/lib/fast_ignore.rb
CHANGED
@@ -49,19 +49,30 @@ class FastIgnore
|
|
49
49
|
each_recursive(root_from_pwd, '', &block)
|
50
50
|
end
|
51
51
|
|
52
|
-
def allowed?(path, directory: nil, content: nil)
|
52
|
+
def allowed?(path, directory: nil, content: nil, exists: nil, include_directories: false) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
53
53
|
full_path = ::File.expand_path(path, @root)
|
54
54
|
return false unless full_path.start_with?(@root)
|
55
|
-
|
55
|
+
|
56
|
+
begin
|
57
|
+
directory = directory.nil? ? @follow_symlinks_method.call(full_path).directory? : directory
|
58
|
+
rescue ::Errno::ENOENT, ::Errno::EACCES, ::Errno::ENOTDIR, ::Errno::ELOOP, ::Errno::ENAMETOOLONG
|
59
|
+
exists = false if exists.nil?
|
60
|
+
directory = false
|
61
|
+
end
|
62
|
+
|
63
|
+
return false if !include_directories && directory
|
64
|
+
|
65
|
+
exists = exists.nil? ? ::File.exist?(full_path) : exists
|
66
|
+
|
67
|
+
return false unless exists
|
56
68
|
|
57
69
|
relative_path = full_path.delete_prefix(@root)
|
58
70
|
load_gitignore_recursive(relative_path) if @gitignore_enabled
|
59
71
|
|
60
72
|
filename = ::File.basename(relative_path)
|
73
|
+
content = content.slice(/.*/) if content # we only care about the first line
|
61
74
|
|
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
|
75
|
+
@rule_sets.allowed_recursive?(relative_path, directory, full_path, filename, content)
|
65
76
|
end
|
66
77
|
alias_method :===, :allowed?
|
67
78
|
|
@@ -77,7 +88,7 @@ class FastIgnore
|
|
77
88
|
paths << path
|
78
89
|
end
|
79
90
|
|
80
|
-
paths.reverse_each(
|
91
|
+
paths.reverse_each { |p| load_gitignore(p) }
|
81
92
|
end
|
82
93
|
|
83
94
|
def load_gitignore(parent_path, check_exists: true)
|
@@ -93,21 +104,19 @@ class FastIgnore
|
|
93
104
|
load_gitignore(parent_relative_path, check_exists: false) if @gitignore_enabled && children.include?('.gitignore')
|
94
105
|
|
95
106
|
children.each do |filename|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
yield(@relative ? relative_path : @root + relative_path)
|
107
|
-
end
|
108
|
-
rescue ::Errno::ENOENT, ::Errno::EACCES, ::Errno::ENOTDIR, ::Errno::ELOOP, ::Errno::ENAMETOOLONG
|
109
|
-
nil
|
107
|
+
full_path = parent_full_path + filename
|
108
|
+
relative_path = parent_relative_path + filename
|
109
|
+
dir = @follow_symlinks_method.call(full_path).directory?
|
110
|
+
|
111
|
+
next unless @rule_sets.allowed_unrecursive?(relative_path, dir, full_path, filename)
|
112
|
+
|
113
|
+
if dir
|
114
|
+
each_recursive(full_path + '/', relative_path + '/', &block)
|
115
|
+
else
|
116
|
+
yield(@relative ? relative_path : @root + relative_path)
|
110
117
|
end
|
118
|
+
rescue ::Errno::ENOENT, ::Errno::EACCES, ::Errno::ENOTDIR, ::Errno::ELOOP, ::Errno::ENAMETOOLONG
|
119
|
+
nil
|
111
120
|
end
|
112
121
|
end
|
113
122
|
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.
|
4
|
+
version: 0.17.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dana Sherson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-03-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -211,7 +211,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
211
211
|
requirements:
|
212
212
|
- - ">="
|
213
213
|
- !ruby/object:Gem::Version
|
214
|
-
version: 2.
|
214
|
+
version: 2.5.0
|
215
215
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
216
216
|
requirements:
|
217
217
|
- - ">="
|