fast_ignore 0.16.1 → 0.17.0
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 +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
|
- - ">="
|