fast_ignore 0.7.0 → 0.8.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/.simplecov +6 -0
- data/CHANGELOG.md +4 -1
- data/README.md +6 -1
- data/bin/ls-shebangs +6 -0
- data/fast_ignore.gemspec +1 -1
- data/lib/fast_ignore/rule_parser.rb +0 -3
- data/lib/fast_ignore/rule_set.rb +19 -13
- data/lib/fast_ignore/rule_set_builder.rb +14 -13
- data/lib/fast_ignore/version.rb +1 -1
- data/lib/fast_ignore.rb +42 -6
- metadata +8 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 58d10e2bb7f504f6ff41d4ad3fbea902df56aa785d45a78e160a40ea5795a1a0
|
4
|
+
data.tar.gz: 16a77bf6dbdbb76f8e8f08793dd5a81d21147dcf9d77e72c4403de377025d4f3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1de15ac6a8ce01bd18077bc402026cddbfeae82e33bbbd1e0e587d1ff3d898ac0fa43abc211bcf007cf2cec7c1fe00c2b60375760a767818330efc4164b2bf67
|
7
|
+
data.tar.gz: 7daed034a210e0f56be064400e7264c182f3abaeda13cd857b9d81f5fc6dc8c397195d087dc539a03f21787f65f24e39e87c4a5d182c419c80b00e5848148756
|
data/.simplecov
ADDED
data/CHANGELOG.md
CHANGED
@@ -1,8 +1,11 @@
|
|
1
|
-
# v0.
|
1
|
+
# v0.8.0
|
2
2
|
- drop support for ruby 2.3. My plan is to only support supported ruby versions
|
3
3
|
- add coverage to the pipeline. removed some methods, added some tests, and now we have 100% test coverage
|
4
4
|
- deprecate using `gitignore: '/path/to/gitignore'`. please use `gitignore: false, ignore_files: '/path/to/gitignore'` instead.
|
5
5
|
|
6
|
+
# v0.7.0
|
7
|
+
- add `include_shebang:` which filters by shebangs
|
8
|
+
|
6
9
|
# v0.6.0
|
7
10
|
- nicer argv handling
|
8
11
|
- add `argv_rules:` option, which resolves paths and considers everything that doesn't start with a `*` to start with a `/`
|
data/README.md
CHANGED
@@ -71,7 +71,12 @@ Note that the location of the .gitignore file will affect rules beginning with `
|
|
71
71
|
|
72
72
|
To raise an `Errno::ENOENT` error if the .gitignore file is not found use:
|
73
73
|
```ruby
|
74
|
-
FastIgnore.new(gitignore: true)
|
74
|
+
FastIgnore.new(gitignore: true).to_a
|
75
|
+
```
|
76
|
+
|
77
|
+
To filter by extensionless files shebang/hashbang/etc:
|
78
|
+
```ruby
|
79
|
+
FastIgnore.new(include_rules: '*.rb', include_shebangs: 'ruby').to_a
|
75
80
|
```
|
76
81
|
|
77
82
|
To check if a single file is allowed, use
|
data/bin/ls-shebangs
ADDED
data/fast_ignore.gemspec
CHANGED
@@ -31,7 +31,7 @@ Gem::Specification.new do |spec|
|
|
31
31
|
|
32
32
|
spec.add_development_dependency 'bundler', '>= 1.17'
|
33
33
|
spec.add_development_dependency 'pry', '> 0'
|
34
|
-
spec.add_development_dependency 'rake', '
|
34
|
+
spec.add_development_dependency 'rake', '>= 12.3.3'
|
35
35
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
36
36
|
spec.add_development_dependency 'rubocop', '>= 0.74.0'
|
37
37
|
spec.add_development_dependency 'rubocop-rspec', '~> 1'
|
data/lib/fast_ignore/rule_set.rb
CHANGED
@@ -1,31 +1,37 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative 'rule_parser'
|
4
|
-
|
5
3
|
class FastIgnore
|
6
4
|
class RuleSet
|
7
5
|
attr_reader :rules
|
6
|
+
attr_reader :allow
|
7
|
+
alias_method :allow?, :allow
|
8
8
|
|
9
|
-
def initialize(project_root: Dir.pwd, allow: false)
|
10
|
-
@
|
11
|
-
@
|
9
|
+
def initialize(project_root: Dir.pwd, allow: false, and_no_ext: false)
|
10
|
+
@dir_rules = []
|
11
|
+
@file_rules = []
|
12
12
|
@project_root = project_root
|
13
|
+
@and_no_ext = and_no_ext
|
13
14
|
|
14
15
|
@any_not_anchored = false
|
15
16
|
@allow = allow
|
16
17
|
@default = true unless allow
|
17
18
|
end
|
18
19
|
|
19
|
-
def allowed_recursive?(path, dir)
|
20
|
+
def allowed_recursive?(path, dir, basename)
|
20
21
|
@allowed_recursive ||= { @project_root => true }
|
21
22
|
@allowed_recursive.fetch(path) do
|
22
23
|
@allowed_recursive[path] =
|
23
|
-
allowed_recursive?(::File.dirname(path), true) && allowed_unrecursive?(path, dir)
|
24
|
+
allowed_recursive?(::File.dirname(path), true, nil) && allowed_unrecursive?(path, dir, basename)
|
24
25
|
end
|
25
26
|
end
|
26
27
|
|
27
|
-
def allowed_unrecursive?(path, dir)
|
28
|
-
|
28
|
+
def allowed_unrecursive?(path, dir, basename)
|
29
|
+
if @and_no_ext
|
30
|
+
return true if dir
|
31
|
+
return true unless basename&.include?('.')
|
32
|
+
end
|
33
|
+
|
34
|
+
(dir ? @dir_rules : @file_rules).reverse_each do |rule|
|
29
35
|
# 14 = Rule::FNMATCH_OPTIONS
|
30
36
|
return rule.negation? if ::File.fnmatch?(rule.rule, path, 14)
|
31
37
|
end
|
@@ -35,18 +41,18 @@ class FastIgnore
|
|
35
41
|
|
36
42
|
def append_rules(anchored, rules)
|
37
43
|
rules.each do |rule|
|
38
|
-
@
|
39
|
-
@
|
44
|
+
@dir_rules << rule
|
45
|
+
@file_rules << rule unless rule.dir_only?
|
40
46
|
@any_not_anchored ||= !anchored
|
41
47
|
end
|
42
48
|
end
|
43
49
|
|
44
50
|
def length
|
45
|
-
@
|
51
|
+
@dir_rules.length
|
46
52
|
end
|
47
53
|
|
48
54
|
def empty?
|
49
|
-
@
|
55
|
+
@dir_rules.empty?
|
50
56
|
end
|
51
57
|
end
|
52
58
|
end
|
@@ -1,8 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative 'rule_set'
|
4
|
-
require_relative 'rule_parser'
|
5
|
-
|
6
3
|
class FastIgnore
|
7
4
|
class RuleSetBuilder
|
8
5
|
def self.from_args( # rubocop:disable Metrics/ParameterLists, Metrics/MethodLength
|
@@ -12,28 +9,32 @@ class FastIgnore
|
|
12
9
|
gitignore: :auto,
|
13
10
|
include_rules: nil,
|
14
11
|
include_files: nil,
|
15
|
-
argv_rules: nil
|
12
|
+
argv_rules: nil,
|
13
|
+
and_no_ext: false
|
16
14
|
)
|
17
15
|
rule_sets = [
|
18
16
|
from_array(ignore_rules, root: root),
|
19
17
|
*from_files(ignore_files, project_root: root),
|
20
18
|
from_array('.git', root: root),
|
21
19
|
from_gitignore_arg(gitignore, root: root),
|
22
|
-
from_array(include_rules, root: root, allow: true),
|
23
|
-
*from_files(include_files, allow: true, project_root: root),
|
24
|
-
from_array(argv_rules, root: root, allow: true, expand_path: true)
|
20
|
+
from_array(include_rules, root: root, allow: true, and_no_ext: and_no_ext),
|
21
|
+
*from_files(include_files, allow: true, project_root: root, and_no_ext: and_no_ext),
|
22
|
+
from_array(argv_rules, root: root, allow: true, expand_path: true, and_no_ext: and_no_ext)
|
25
23
|
]
|
26
24
|
|
27
25
|
rule_sets.compact!
|
28
26
|
rule_sets.reject!(&:empty?)
|
27
|
+
if and_no_ext && rule_sets.none?(&:allow?)
|
28
|
+
rule_sets << ::FastIgnore::RuleSet.new(project_root: root, allow: true, and_no_ext: and_no_ext)
|
29
|
+
end
|
29
30
|
rule_sets.sort_by!(&:length)
|
30
31
|
rule_sets
|
31
32
|
end
|
32
33
|
|
33
|
-
def self.from_file(filename, allow: false, project_root: Dir.pwd)
|
34
|
+
def self.from_file(filename, allow: false, project_root: Dir.pwd, and_no_ext: false)
|
34
35
|
filename = ::File.expand_path(filename)
|
35
36
|
root = ::File.dirname(filename)
|
36
|
-
rule_set = ::FastIgnore::RuleSet.new(project_root: project_root, allow: allow)
|
37
|
+
rule_set = ::FastIgnore::RuleSet.new(project_root: project_root, allow: allow, and_no_ext: and_no_ext)
|
37
38
|
|
38
39
|
::IO.foreach(filename) do |rule_string|
|
39
40
|
parse_rules(rule_string, allow: allow, rule_set: rule_set, root: root)
|
@@ -42,9 +43,9 @@ class FastIgnore
|
|
42
43
|
rule_set
|
43
44
|
end
|
44
45
|
|
45
|
-
def self.from_files(files, allow: false, project_root: Dir.pwd)
|
46
|
+
def self.from_files(files, allow: false, project_root: Dir.pwd, and_no_ext: false)
|
46
47
|
Array(files).map do |file|
|
47
|
-
from_file(file, allow: allow, project_root: project_root)
|
48
|
+
from_file(file, allow: allow, project_root: project_root, and_no_ext: and_no_ext)
|
48
49
|
end
|
49
50
|
end
|
50
51
|
|
@@ -64,11 +65,11 @@ class FastIgnore
|
|
64
65
|
end
|
65
66
|
end
|
66
67
|
|
67
|
-
def self.from_array(rules, allow: false, expand_path: false, root: Dir.pwd)
|
68
|
+
def self.from_array(rules, allow: false, expand_path: false, root: Dir.pwd, and_no_ext: false)
|
68
69
|
rules = Array(rules)
|
69
70
|
return if rules.empty?
|
70
71
|
|
71
|
-
rule_set = ::FastIgnore::RuleSet.new(project_root: root, allow: allow)
|
72
|
+
rule_set = ::FastIgnore::RuleSet.new(project_root: root, allow: allow, and_no_ext: and_no_ext)
|
72
73
|
|
73
74
|
rules.each_with_object(rule_set) do |rule_string, set|
|
74
75
|
rule_string.each_line do |rule_line|
|
data/lib/fast_ignore/version.rb
CHANGED
data/lib/fast_ignore.rb
CHANGED
@@ -1,8 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative './fast_ignore/rule_set_builder'
|
4
3
|
require_relative './fast_ignore/backports'
|
5
4
|
|
5
|
+
require_relative './fast_ignore/rule_parser'
|
6
|
+
require_relative './fast_ignore/rule_set_builder'
|
7
|
+
require_relative './fast_ignore/rule_set'
|
8
|
+
require_relative './fast_ignore/rule'
|
9
|
+
|
6
10
|
class FastIgnore
|
7
11
|
include ::Enumerable
|
8
12
|
|
@@ -24,10 +28,12 @@ class FastIgnore
|
|
24
28
|
gitignore: :auto,
|
25
29
|
include_rules: nil,
|
26
30
|
include_files: nil,
|
31
|
+
include_shebangs: nil,
|
27
32
|
argv_rules: nil
|
28
33
|
)
|
29
34
|
@root = root.delete_suffix('/')
|
30
35
|
@root_trailing_slash = "#{@root}/"
|
36
|
+
@shebang_pattern = prepare_shebang_pattern(include_shebangs)
|
31
37
|
|
32
38
|
@rule_sets = ::FastIgnore::RuleSetBuilder.from_args(
|
33
39
|
root: @root,
|
@@ -36,7 +42,8 @@ class FastIgnore
|
|
36
42
|
gitignore: gitignore,
|
37
43
|
include_rules: include_rules,
|
38
44
|
include_files: include_files,
|
39
|
-
argv_rules: argv_rules
|
45
|
+
argv_rules: argv_rules,
|
46
|
+
and_no_ext: @shebang_pattern
|
40
47
|
)
|
41
48
|
|
42
49
|
@relative = relative
|
@@ -56,7 +63,9 @@ class FastIgnore
|
|
56
63
|
dir = stat.directory?
|
57
64
|
return false if dir
|
58
65
|
|
59
|
-
|
66
|
+
basename = ::File.basename(path)
|
67
|
+
|
68
|
+
@rule_sets.all? { |r| r.allowed_recursive?(path, dir, basename) } && match_shebang?(path, basename)
|
60
69
|
rescue Errno::ENOENT, Errno::EACCES, Errno::ENOTDIR, Errno::ELOOP, Errno::ENAMETOOLONG
|
61
70
|
false
|
62
71
|
end
|
@@ -68,17 +77,22 @@ class FastIgnore
|
|
68
77
|
end
|
69
78
|
|
70
79
|
def each_allowed(path = @root_trailing_slash, &block) # rubocop:disable Metrics/MethodLength
|
71
|
-
Dir.each_child(path) do |
|
80
|
+
Dir.each_child(path) do |basename|
|
72
81
|
begin
|
73
|
-
child = path +
|
82
|
+
child = path + basename
|
74
83
|
stat = ::File.stat(child)
|
75
84
|
|
76
85
|
dir = stat.directory?
|
77
|
-
next unless @rule_sets.all? { |r| r.allowed_unrecursive?(child, dir) }
|
78
86
|
|
79
87
|
if dir
|
88
|
+
next unless @rule_sets.all? { |r| r.allowed_unrecursive?(child, dir, nil) }
|
89
|
+
|
80
90
|
each_allowed("#{child}/", &block)
|
81
91
|
else
|
92
|
+
unless @rule_sets.all? { |r| r.allowed_unrecursive?(child, dir, basename) } && match_shebang?(child, basename)
|
93
|
+
next
|
94
|
+
end
|
95
|
+
|
82
96
|
yield prepare_path(child)
|
83
97
|
end
|
84
98
|
rescue Errno::ENOENT, Errno::EACCES, Errno::ENOTDIR, Errno::ELOOP, Errno::ENAMETOOLONG
|
@@ -86,4 +100,26 @@ class FastIgnore
|
|
86
100
|
end
|
87
101
|
end
|
88
102
|
end
|
103
|
+
|
104
|
+
def match_shebang?(path, basename)
|
105
|
+
return true unless @shebang_pattern
|
106
|
+
return true if basename.include?('.')
|
107
|
+
|
108
|
+
begin
|
109
|
+
f = ::File.new(path)
|
110
|
+
# i can't imagine a shebang being longer than 20 characters, lets multiply that by 10 just in case.
|
111
|
+
fragment = f.sysread(256)
|
112
|
+
f.close
|
113
|
+
rescue SystemCallError, EOFError
|
114
|
+
return
|
115
|
+
end
|
116
|
+
|
117
|
+
@shebang_pattern.match?(fragment)
|
118
|
+
end
|
119
|
+
|
120
|
+
def prepare_shebang_pattern(rules)
|
121
|
+
return if !rules || rules.empty?
|
122
|
+
|
123
|
+
/\A#!.*\b(?:#{rules.map { |s| Regexp.escape(s.to_s) }.join('|')})\b/.freeze
|
124
|
+
end
|
89
125
|
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.8.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: 2020-
|
11
|
+
date: 2020-04-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -42,16 +42,16 @@ dependencies:
|
|
42
42
|
name: rake
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - "
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: 12.3.3
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - "
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: 12.3.3
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rspec
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -118,6 +118,7 @@ files:
|
|
118
118
|
- ".gitignore"
|
119
119
|
- ".rspec"
|
120
120
|
- ".rubocop.yml"
|
121
|
+
- ".simplecov"
|
121
122
|
- ".travis.yml"
|
122
123
|
- CHANGELOG.md
|
123
124
|
- Gemfile
|
@@ -127,6 +128,7 @@ files:
|
|
127
128
|
- bin/console
|
128
129
|
- bin/ls
|
129
130
|
- bin/ls-disable-gems
|
131
|
+
- bin/ls-shebangs
|
130
132
|
- bin/setup
|
131
133
|
- fast_ignore.gemspec
|
132
134
|
- lib/fast_ignore.rb
|