fast_ignore 0.7.0 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|