fast_ignore 0.10.0 → 0.10.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -1
- data/README.md +12 -5
- data/bin/ls +1 -1
- data/bin/time +18 -0
- data/fast_ignore.gemspec +1 -1
- data/lib/fast_ignore.rb +28 -37
- data/lib/fast_ignore/rule.rb +10 -7
- data/lib/fast_ignore/rule_builder.rb +104 -0
- data/lib/fast_ignore/rule_set.rb +8 -16
- data/lib/fast_ignore/rule_set_builder.rb +65 -70
- data/lib/fast_ignore/version.rb +1 -1
- metadata +6 -6
- data/bin/ls-disable-gems +0 -6
- data/lib/fast_ignore/rule_parser.rb +0 -103
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f3d94c089fb5c75d6c9d0650d2391d03425c487c81296495f44f35ed1f6d80ac
|
4
|
+
data.tar.gz: a9bba05df8121aa49d38b39c7aaaa0e3c7d2b30e4b874d083fe517fa36846b97
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e8954fbef86b13d7948744b2c803319b261d67b6afe83412f1e099a377b17adae2aa1106a3445e6f5604449130c8dfc815331fe104f205ca09b87f5ff8caa69e
|
7
|
+
data.tar.gz: e53891e9d8b056a62ede7399695deb2911d5836ad5b8442b2ef90d7876fb4d794f1665697df6e7eeecf616f828217fce841f96c9bdfd39e73ae6c89594a65d5c
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
# v0.10.1
|
2
|
+
- Add option to follow symlinks (turns out i needed it)
|
3
|
+
- performance improvements
|
4
|
+
|
1
5
|
# v0.10.0
|
2
6
|
- patterns with middle slashes are anchored to the root (like the gitignore documentation, now that it more clearly explains)
|
3
7
|
- new shebang pattern (#!:), the previous version was extremely janky.
|
@@ -6,7 +10,6 @@
|
|
6
10
|
- documentation improvements
|
7
11
|
- root can be given as a path relative to PWD
|
8
12
|
- includes with 'a/**/d' now matches a/b/c/d properly
|
9
|
-
-
|
10
13
|
|
11
14
|
# v0.9.0
|
12
15
|
- speed improvements, which may break things (Specifically, only using relative paths internally, is about 30% faster (depending on root depth))
|
data/README.md
CHANGED
@@ -50,12 +50,20 @@ FastIgnore.new.each.with_index { |file, index| puts "#{file}#{index}" }
|
|
50
50
|
```
|
51
51
|
|
52
52
|
### `relative: true`
|
53
|
-
By default, FastIgnore will return full paths. To return paths relative to the current working directory, use:
|
53
|
+
By default, FastIgnore will return full paths. To return paths relative to the current working directory, or the supplied [`root:`](#root), use:
|
54
54
|
|
55
55
|
```ruby
|
56
56
|
FastIgnore.new(relative: true).to_a
|
57
57
|
```
|
58
58
|
|
59
|
+
### `follow_symlinks: true`
|
60
|
+
By default, FastIgnore will match git's behaviour and not follow symbolic links.
|
61
|
+
To make it follow symlinks, use:
|
62
|
+
|
63
|
+
```ruby
|
64
|
+
FastIgnore.new(follow_symlinks: true).to_a
|
65
|
+
```
|
66
|
+
|
59
67
|
### `root:`
|
60
68
|
|
61
69
|
By default, root is PWD (the current working directory)
|
@@ -200,11 +208,10 @@ This does unfortunately lose the file path as the root for `/` and `/**` rules.
|
|
200
208
|
## Known issues
|
201
209
|
- Doesn't take into account project excludes in `.git/info/exclude`
|
202
210
|
- Doesn't take into account globally ignored files in `git config core.excludesFile`.
|
203
|
-
- Doesn't
|
204
|
-
|
205
|
-
> [If the pattern does not contain a slash /, Git treats it as a shell glob pattern and checks for a match against the pathname relative to the location of the `.gitignore` file (relative to the toplevel of the work tree if not from a `.gitignore` file)](https://www.git-scm.com/docs/gitignore#_pattern_format)
|
211
|
+
- Doesn't know what to do if you change the current working directory inside the `FastIgnore#each` block.
|
212
|
+
So don't do that.
|
206
213
|
|
207
|
-
|
214
|
+
(It does handle changing the current working directory between `FastIgnore#allowed?` calls.)
|
208
215
|
|
209
216
|
## Development
|
210
217
|
|
data/bin/ls
CHANGED
data/bin/time
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'open3'
|
5
|
+
RUNS = 30
|
6
|
+
SCRIPT = "time #{__dir__}/ls"
|
7
|
+
Dir.chdir ARGV[0] do
|
8
|
+
times = Array.new(RUNS).map do
|
9
|
+
run_times = Open3.capture3(SCRIPT)[1]
|
10
|
+
puts run_times.lstrip
|
11
|
+
run_times.scan(/(?:\d+(?:.\d+)?)/)
|
12
|
+
end
|
13
|
+
|
14
|
+
puts format(
|
15
|
+
"\e[1mAverage:\n\e[32m%0.2f real %0.2f user %0.2f sys\e[0m", # rubocop:disable Style/FormatStringToken
|
16
|
+
*times.transpose.map { |n| (n.map(&:to_f).sum / RUNS) }
|
17
|
+
)
|
18
|
+
end
|
data/fast_ignore.gemspec
CHANGED
@@ -30,7 +30,7 @@ Gem::Specification.new do |spec|
|
|
30
30
|
spec.require_paths = ['lib']
|
31
31
|
|
32
32
|
spec.add_development_dependency 'bundler', '>= 1.17'
|
33
|
-
spec.add_development_dependency 'leftovers', '>= 0.2.
|
33
|
+
spec.add_development_dependency 'leftovers', '>= 0.2.2'
|
34
34
|
spec.add_development_dependency 'pry', '> 0'
|
35
35
|
spec.add_development_dependency 'rake', '>= 12.3.3'
|
36
36
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
data/lib/fast_ignore.rb
CHANGED
@@ -2,8 +2,8 @@
|
|
2
2
|
|
3
3
|
require_relative './fast_ignore/backports'
|
4
4
|
|
5
|
-
require_relative './fast_ignore/rule_parser'
|
6
5
|
require_relative './fast_ignore/rule_set_builder'
|
6
|
+
require_relative './fast_ignore/rule_builder'
|
7
7
|
require_relative './fast_ignore/rule_set'
|
8
8
|
require_relative './fast_ignore/rule'
|
9
9
|
|
@@ -22,70 +22,61 @@ class FastIgnore
|
|
22
22
|
end
|
23
23
|
# :nocov:
|
24
24
|
|
25
|
-
def initialize(
|
26
|
-
relative: false,
|
27
|
-
root: nil,
|
28
|
-
include_shebangs: nil,
|
29
|
-
**rule_set_builder_args
|
30
|
-
)
|
31
|
-
# :nocov:
|
32
|
-
if include_shebangs && !Array(include_shebangs).empty?
|
33
|
-
|
34
|
-
warn <<~WARNING
|
35
|
-
Removed FastIgnore `include_shebangs:` argument.
|
36
|
-
It will be ignored. Please replace with the include_rules: in the shebang format
|
37
|
-
https://github.com/robotdana/fast_ignore#shebang-rules
|
38
|
-
WARNING
|
39
|
-
end
|
40
|
-
# :nocov:
|
41
|
-
|
42
|
-
root = root ? File.expand_path(root, ::Dir.pwd) : ::Dir.pwd
|
43
|
-
@root = "#{root}/"
|
44
|
-
|
45
|
-
@rule_sets = ::FastIgnore::RuleSetBuilder.from_args(root: @root, **rule_set_builder_args)
|
25
|
+
def initialize(relative: false, root: nil, follow_symlinks: false, **rule_set_builder_args)
|
46
26
|
@relative = relative
|
27
|
+
@follow_symlinks = follow_symlinks
|
28
|
+
dir_pwd = Dir.pwd
|
29
|
+
@root = "#{::File.expand_path(root.to_s, dir_pwd)}/"
|
30
|
+
@rule_sets = ::FastIgnore::RuleSetBuilder.build(root: @root, **rule_set_builder_args)
|
47
31
|
|
48
32
|
freeze
|
49
33
|
end
|
50
34
|
|
51
35
|
def each(&block)
|
52
|
-
|
53
|
-
|
36
|
+
return enum_for(:each) unless block_given?
|
37
|
+
|
38
|
+
dir_pwd = Dir.pwd
|
39
|
+
root_from_pwd = @root.start_with?(dir_pwd) ? ".#{@root.delete_prefix(dir_pwd)}" : @root
|
40
|
+
|
41
|
+
each_recursive(root_from_pwd, '', &block)
|
42
|
+
end
|
43
|
+
|
44
|
+
def directory?(path)
|
45
|
+
if @follow_symlinks
|
46
|
+
::File.stat(path).directory?
|
54
47
|
else
|
55
|
-
|
48
|
+
::File.lstat(path).directory?
|
56
49
|
end
|
57
50
|
end
|
58
51
|
|
59
52
|
def allowed?(path)
|
60
53
|
full_path = ::File.expand_path(path, @root)
|
61
54
|
return false unless full_path.start_with?(@root)
|
62
|
-
|
63
|
-
dir = ::File.lstat(full_path).directory?
|
64
|
-
return false if dir
|
55
|
+
return false if directory?(full_path)
|
65
56
|
|
66
57
|
relative_path = full_path.delete_prefix(@root)
|
67
58
|
filename = ::File.basename(relative_path)
|
68
59
|
|
69
|
-
@rule_sets.all? { |r| r.allowed_recursive?(relative_path,
|
60
|
+
@rule_sets.all? { |r| r.allowed_recursive?(relative_path, false, filename) }
|
70
61
|
rescue ::Errno::ENOENT, ::Errno::EACCES, ::Errno::ENOTDIR, ::Errno::ELOOP, ::Errno::ENAMETOOLONG
|
71
62
|
false
|
72
63
|
end
|
73
64
|
|
74
65
|
private
|
75
66
|
|
76
|
-
def
|
77
|
-
::Dir.each_child(
|
67
|
+
def each_recursive(parent_full_path, parent_relative_path, &block) # rubocop:disable Metrics/MethodLength
|
68
|
+
::Dir.each_child(parent_full_path) do |filename|
|
78
69
|
begin
|
79
|
-
|
80
|
-
|
81
|
-
dir =
|
70
|
+
full_path = parent_full_path + filename
|
71
|
+
relative_path = parent_relative_path + filename
|
72
|
+
dir = directory?(full_path)
|
82
73
|
|
83
|
-
next unless @rule_sets.all? { |r| r.allowed_unrecursive?(
|
74
|
+
next unless @rule_sets.all? { |r| r.allowed_unrecursive?(relative_path, dir, filename) }
|
84
75
|
|
85
76
|
if dir
|
86
|
-
|
77
|
+
each_recursive(full_path + '/', relative_path + '/', &block)
|
87
78
|
else
|
88
|
-
yield(@relative ?
|
79
|
+
yield(@relative ? relative_path : @root + relative_path)
|
89
80
|
end
|
90
81
|
rescue ::Errno::ENOENT, ::Errno::EACCES, ::Errno::ENOTDIR, ::Errno::ELOOP, ::Errno::ENAMETOOLONG
|
91
82
|
nil
|
data/lib/fast_ignore/rule.rb
CHANGED
@@ -10,18 +10,20 @@ class FastIgnore
|
|
10
10
|
|
11
11
|
attr_reader :negation
|
12
12
|
alias_method :negation?, :negation
|
13
|
+
|
13
14
|
attr_reader :dir_only
|
14
15
|
alias_method :dir_only?, :dir_only
|
15
|
-
attr_reader :file_only
|
16
|
-
alias_method :file_only?, :file_only
|
17
16
|
|
18
17
|
attr_reader :shebang
|
19
|
-
|
18
|
+
alias_method :file_only?, :shebang
|
19
|
+
|
20
|
+
attr_reader :unanchored
|
21
|
+
alias_method :unanchored?, :unanchored
|
20
22
|
|
21
|
-
def initialize(rule,
|
23
|
+
def initialize(rule, unanchored, dir_only, negation, shebang = nil)
|
22
24
|
@rule = rule
|
25
|
+
@unanchored = unanchored
|
23
26
|
@dir_only = dir_only
|
24
|
-
@file_only = file_only
|
25
27
|
@negation = negation
|
26
28
|
@shebang = shebang
|
27
29
|
|
@@ -31,9 +33,9 @@ class FastIgnore
|
|
31
33
|
# :nocov:
|
32
34
|
def inspect
|
33
35
|
if shebang
|
34
|
-
"#<Rule #{'allow ' if negation
|
36
|
+
"#<Rule #{'allow ' if @negation}#!:#{@shebang.to_s[15..-4]}>"
|
35
37
|
else
|
36
|
-
"#<Rule #{'!' if negation
|
38
|
+
"#<Rule #{'!' if @negation}#{@rule}#{'/' if @dir_only}>"
|
37
39
|
end
|
38
40
|
end
|
39
41
|
# :nocov:
|
@@ -42,6 +44,7 @@ class FastIgnore
|
|
42
44
|
if @shebang
|
43
45
|
match_shebang?(path, filename)
|
44
46
|
else
|
47
|
+
# 14 = FNMATCH_OPTIONS
|
45
48
|
::File.fnmatch?(@rule, path, 14)
|
46
49
|
end
|
47
50
|
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class FastIgnore
|
4
|
+
module RuleBuilder
|
5
|
+
# rule or nil
|
6
|
+
class << self
|
7
|
+
# :nocov:
|
8
|
+
if ::FastIgnore::Backports.ruby_version_less_than?(2, 5)
|
9
|
+
require_relative 'backports/delete_prefix_suffix'
|
10
|
+
using ::FastIgnore::Backports::DeletePrefixSuffix
|
11
|
+
end
|
12
|
+
# :nocov:
|
13
|
+
|
14
|
+
def build(rule, allow, expand_path, file_root)
|
15
|
+
strip(rule)
|
16
|
+
|
17
|
+
return shebang_rules(rule, allow) if remove_shebang(rule)
|
18
|
+
return [] if skip?(rule)
|
19
|
+
|
20
|
+
gitignore_rules(rule, allow, expand_path, file_root)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def strip(rule)
|
26
|
+
rule.chomp!
|
27
|
+
rule.rstrip! unless rule.end_with?('\\ ')
|
28
|
+
end
|
29
|
+
|
30
|
+
def remove_shebang(rule)
|
31
|
+
return unless rule.delete_prefix!('#!:')
|
32
|
+
|
33
|
+
rule.strip!
|
34
|
+
|
35
|
+
true
|
36
|
+
end
|
37
|
+
|
38
|
+
def shebang_rules(rule, allow)
|
39
|
+
rules = [::FastIgnore::Rule.new(nil, true, false, allow, /\A#!.*\b#{Regexp.escape(rule)}\b/.freeze)]
|
40
|
+
return rules unless allow
|
41
|
+
|
42
|
+
rules << ::FastIgnore::Rule.new('**/*', true, true, true)
|
43
|
+
rules
|
44
|
+
end
|
45
|
+
|
46
|
+
def skip?(rule)
|
47
|
+
rule.empty? || rule.start_with?('#')
|
48
|
+
end
|
49
|
+
|
50
|
+
def gitignore_rules(rule, allow, expand_path, file_root)
|
51
|
+
dir_only = extract_dir_only(rule)
|
52
|
+
negation = extract_negation(rule, allow)
|
53
|
+
|
54
|
+
expand_rule_path(rule, expand_path) if expand_path
|
55
|
+
unanchored = unanchored?(rule)
|
56
|
+
rule.delete_prefix!('/')
|
57
|
+
|
58
|
+
rule.prepend("#{file_root}#{'**/' if unanchored}") if file_root || unanchored
|
59
|
+
|
60
|
+
build_gitignore_rules(rule, unanchored, allow, dir_only, negation)
|
61
|
+
end
|
62
|
+
|
63
|
+
def extract_dir_only(rule)
|
64
|
+
rule.delete_suffix!('/')
|
65
|
+
end
|
66
|
+
|
67
|
+
def extract_negation(rule, allow)
|
68
|
+
return allow unless rule.delete_prefix!('!')
|
69
|
+
|
70
|
+
not allow
|
71
|
+
end
|
72
|
+
|
73
|
+
EXPAND_PATH_RE = %r{^(?:[~/]|\.{1,2}/)}.freeze
|
74
|
+
def expand_rule_path(rule, root)
|
75
|
+
rule.replace(::File.expand_path(rule)) if rule.match?(EXPAND_PATH_RE)
|
76
|
+
rule.delete_prefix!(root)
|
77
|
+
rule.prepend('/') unless rule.start_with?('*') || rule.start_with?('/')
|
78
|
+
end
|
79
|
+
|
80
|
+
def unanchored?(rule)
|
81
|
+
not rule.include?('/') # we've already removed the trailing '/' with extract_dir_only
|
82
|
+
end
|
83
|
+
|
84
|
+
def build_gitignore_rules(rule, unanchored, allow, dir_only, negation)
|
85
|
+
rules = [::FastIgnore::Rule.new(rule.freeze, unanchored, dir_only, negation)]
|
86
|
+
return rules unless allow
|
87
|
+
|
88
|
+
rules << ::FastIgnore::Rule.new("#{rule}/**/*", unanchored, false, negation)
|
89
|
+
rules + ancestor_rules(rule, unanchored)
|
90
|
+
end
|
91
|
+
|
92
|
+
def ancestor_rules(parent, unanchored)
|
93
|
+
ancestor_rules = []
|
94
|
+
|
95
|
+
while (parent = ::File.dirname(parent)) != '.'
|
96
|
+
rule = ::File.basename(parent) == '**' ? "#{parent}/*" : parent.freeze
|
97
|
+
ancestor_rules << ::FastIgnore::Rule.new(rule, unanchored, true, true)
|
98
|
+
end
|
99
|
+
|
100
|
+
ancestor_rules
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
data/lib/fast_ignore/rule_set.rb
CHANGED
@@ -2,12 +2,15 @@
|
|
2
2
|
|
3
3
|
class FastIgnore
|
4
4
|
class RuleSet
|
5
|
-
def initialize(allow
|
6
|
-
@dir_rules =
|
7
|
-
@file_rules =
|
5
|
+
def initialize(rules, allow)
|
6
|
+
@dir_rules = rules.reject(&:file_only?).freeze
|
7
|
+
@file_rules = rules.reject(&:dir_only?).freeze
|
8
|
+
@any_not_anchored = rules.any?(&:unanchored?)
|
9
|
+
@has_shebang_rules = rules.any?(&:shebang)
|
8
10
|
@allowed_recursive = { '.' => true }
|
9
|
-
@any_not_anchored = false
|
10
11
|
@allow = allow
|
12
|
+
|
13
|
+
freeze
|
11
14
|
end
|
12
15
|
|
13
16
|
def freeze
|
@@ -26,21 +29,10 @@ class FastIgnore
|
|
26
29
|
|
27
30
|
def allowed_unrecursive?(path, dir, filename)
|
28
31
|
(dir ? @dir_rules : @file_rules).reverse_each do |rule|
|
29
|
-
# 14 = Rule::FNMATCH_OPTIONS
|
30
|
-
|
31
32
|
return rule.negation? if rule.match?(path, filename)
|
32
33
|
end
|
33
34
|
|
34
|
-
(not @allow) || (@any_not_anchored
|
35
|
-
end
|
36
|
-
|
37
|
-
def append_rules(anchored, rules)
|
38
|
-
rules.each do |rule|
|
39
|
-
(@dir_rules << rule) unless rule.file_only?
|
40
|
-
(@file_rules << rule) unless rule.dir_only?
|
41
|
-
@any_not_anchored ||= !anchored
|
42
|
-
@has_shebang_rules ||= rule.shebang
|
43
|
-
end
|
35
|
+
(not @allow) || (dir && @any_not_anchored)
|
44
36
|
end
|
45
37
|
|
46
38
|
def weight
|
@@ -1,92 +1,87 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class FastIgnore
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
4
|
+
module RuleSetBuilder
|
5
|
+
class << self
|
6
|
+
# :nocov:
|
7
|
+
if ::FastIgnore::Backports.ruby_version_less_than?(2, 5)
|
8
|
+
require_relative 'backports/delete_prefix_suffix'
|
9
|
+
using ::FastIgnore::Backports::DeletePrefixSuffix
|
10
|
+
end
|
11
|
+
# :nocov:
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
13
|
+
def build( # rubocop:disable Metrics/ParameterLists
|
14
|
+
root:,
|
15
|
+
ignore_rules: nil,
|
16
|
+
ignore_files: nil,
|
17
|
+
gitignore: :auto,
|
18
|
+
include_rules: nil,
|
19
|
+
include_files: nil,
|
20
|
+
argv_rules: nil
|
21
|
+
)
|
22
|
+
prepare [
|
23
|
+
from_array(ignore_rules),
|
24
|
+
*from_files(ignore_files, project_root: root),
|
25
|
+
from_array('.git'),
|
26
|
+
from_gitignore_arg(gitignore, project_root: root),
|
27
|
+
from_array(include_rules, allow: true),
|
28
|
+
*from_files(include_files, allow: true, project_root: root),
|
29
|
+
from_array(argv_rules, allow: true, expand_path: root)
|
30
|
+
]
|
31
|
+
end
|
30
32
|
|
31
|
-
|
32
|
-
rule_sets.reject!(&:empty?)
|
33
|
-
rule_sets.sort_by!(&:weight)
|
34
|
-
rule_sets
|
35
|
-
end
|
33
|
+
private
|
36
34
|
|
37
|
-
|
38
|
-
|
39
|
-
|
35
|
+
def prepare(rule_sets)
|
36
|
+
rule_sets.compact!
|
37
|
+
rule_sets.reject!(&:empty?)
|
38
|
+
rule_sets.sort_by!(&:weight)
|
39
|
+
rule_sets
|
40
|
+
end
|
40
41
|
|
41
|
-
|
42
|
-
|
42
|
+
def from_file(filename, project_root:, allow: false)
|
43
|
+
filename = ::File.expand_path(filename, project_root)
|
44
|
+
raise FastIgnore::Error, "#{filename} is not within #{project_root}" unless filename.start_with?(project_root)
|
43
45
|
|
44
|
-
|
45
|
-
|
46
|
+
file_root = "#{::File.dirname(filename)}/".delete_prefix(project_root)
|
47
|
+
build_rule_set(::File.readlines(filename), allow, file_root: file_root)
|
46
48
|
end
|
47
49
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
Array(files).map do |file|
|
53
|
-
from_file(file, allow: allow, project_root: project_root)
|
50
|
+
def from_files(files, project_root:, allow: false)
|
51
|
+
Array(files).map do |file|
|
52
|
+
from_file(file, project_root: project_root, allow: allow)
|
53
|
+
end
|
54
54
|
end
|
55
|
-
end
|
56
55
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
56
|
+
def from_gitignore_arg(gitignore, project_root:)
|
57
|
+
default_path = ::File.join(project_root, '.gitignore')
|
58
|
+
case gitignore
|
59
|
+
when :auto
|
60
|
+
from_file(default_path, project_root: project_root) if ::File.exist?(default_path)
|
61
|
+
when true
|
62
|
+
from_file(default_path, project_root: project_root)
|
63
|
+
end
|
64
64
|
end
|
65
|
-
end
|
66
65
|
|
67
|
-
|
68
|
-
|
69
|
-
return if rules.empty?
|
66
|
+
def from_array(rules, allow: false, expand_path: false)
|
67
|
+
return unless rules
|
70
68
|
|
71
|
-
|
69
|
+
rules = Array(rules)
|
72
70
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
71
|
+
return if rules.empty?
|
72
|
+
|
73
|
+
rules = rules.flat_map { |string| string.to_s.lines }
|
74
|
+
|
75
|
+
build_rule_set(rules, allow, expand_path: expand_path)
|
77
76
|
end
|
78
77
|
|
79
|
-
|
80
|
-
|
78
|
+
def build_rule_set(rules, allow, expand_path: false, file_root: nil)
|
79
|
+
rules = rules.flat_map do |rule|
|
80
|
+
::FastIgnore::RuleBuilder.build(rule, allow, expand_path, file_root)
|
81
|
+
end
|
81
82
|
|
82
|
-
|
83
|
-
|
84
|
-
rule_line,
|
85
|
-
rule_set: rule_set,
|
86
|
-
allow: allow,
|
87
|
-
expand_path: expand_path,
|
88
|
-
file_root: file_root
|
89
|
-
)
|
83
|
+
::FastIgnore::RuleSet.new(rules, allow).freeze
|
84
|
+
end
|
90
85
|
end
|
91
86
|
end
|
92
87
|
end
|
data/lib/fast_ignore/version.rb
CHANGED
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.10.
|
4
|
+
version: 0.10.1
|
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-04-
|
11
|
+
date: 2020-04-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.2.
|
33
|
+
version: 0.2.2
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 0.2.
|
40
|
+
version: 0.2.2
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: pry
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -160,15 +160,15 @@ files:
|
|
160
160
|
- Rakefile
|
161
161
|
- bin/console
|
162
162
|
- bin/ls
|
163
|
-
- bin/ls-disable-gems
|
164
163
|
- bin/setup
|
164
|
+
- bin/time
|
165
165
|
- fast_ignore.gemspec
|
166
166
|
- lib/fast_ignore.rb
|
167
167
|
- lib/fast_ignore/backports.rb
|
168
168
|
- lib/fast_ignore/backports/delete_prefix_suffix.rb
|
169
169
|
- lib/fast_ignore/backports/dir_each_child.rb
|
170
170
|
- lib/fast_ignore/rule.rb
|
171
|
-
- lib/fast_ignore/
|
171
|
+
- lib/fast_ignore/rule_builder.rb
|
172
172
|
- lib/fast_ignore/rule_set.rb
|
173
173
|
- lib/fast_ignore/rule_set_builder.rb
|
174
174
|
- lib/fast_ignore/version.rb
|
data/bin/ls-disable-gems
DELETED
@@ -1,103 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
class FastIgnore
|
4
|
-
class RuleParser
|
5
|
-
# :nocov:
|
6
|
-
if ::FastIgnore::Backports.ruby_version_less_than?(2, 5)
|
7
|
-
require_relative 'backports/delete_prefix_suffix'
|
8
|
-
using ::FastIgnore::Backports::DeletePrefixSuffix
|
9
|
-
end
|
10
|
-
# :nocov:
|
11
|
-
|
12
|
-
# rule or nil
|
13
|
-
class << self
|
14
|
-
def new_rule(rule, rule_set:, allow: false, expand_path: false, file_root: nil) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
15
|
-
rule = rule.dup
|
16
|
-
strip(rule)
|
17
|
-
|
18
|
-
return rule_set.append_rules(false, shebang_rules(rule, allow)) if extract_shebang(rule)
|
19
|
-
|
20
|
-
return if skip?(rule)
|
21
|
-
|
22
|
-
dir_only = extract_dir_only(rule)
|
23
|
-
negation = extract_negation(rule, allow)
|
24
|
-
|
25
|
-
expand_rule_path(rule, expand_path) if expand_path
|
26
|
-
anchored = anchored?(rule)
|
27
|
-
rule.delete_prefix!('/')
|
28
|
-
|
29
|
-
rule.prepend("#{file_root}#{'**/' unless anchored}") if file_root || (not anchored)
|
30
|
-
|
31
|
-
rule.freeze
|
32
|
-
|
33
|
-
rule_set.append_rules(
|
34
|
-
anchored,
|
35
|
-
rules(rule, allow, dir_only, negation)
|
36
|
-
)
|
37
|
-
end
|
38
|
-
|
39
|
-
private
|
40
|
-
|
41
|
-
def shebang_rules(rule, allow)
|
42
|
-
rules = [::FastIgnore::Rule.new(nil, false, true, allow, /\A#!.*\b#{Regexp.escape(rule)}\b/)]
|
43
|
-
return rules unless allow
|
44
|
-
|
45
|
-
rules << ::FastIgnore::Rule.new('**/*', true, false, true)
|
46
|
-
rules
|
47
|
-
end
|
48
|
-
|
49
|
-
def rules(rule, allow, dir_only, negation)
|
50
|
-
rules = [::FastIgnore::Rule.new(rule, dir_only, false, negation)]
|
51
|
-
return rules unless allow
|
52
|
-
|
53
|
-
rules << ::FastIgnore::Rule.new("#{rule}/**/*", false, false, negation)
|
54
|
-
rules + ancestor_rules(rule)
|
55
|
-
end
|
56
|
-
|
57
|
-
def ancestor_rules(parent)
|
58
|
-
ancestor_rules = []
|
59
|
-
|
60
|
-
while (parent = ::File.dirname(parent)) != '.'
|
61
|
-
rule = ::File.basename(parent) == '**' ? "#{parent}/*" : parent.freeze
|
62
|
-
ancestor_rules << ::FastIgnore::Rule.new(rule, true, false, true)
|
63
|
-
end
|
64
|
-
|
65
|
-
ancestor_rules
|
66
|
-
end
|
67
|
-
|
68
|
-
def extract_negation(rule, allow)
|
69
|
-
return allow unless rule.delete_prefix!('!')
|
70
|
-
|
71
|
-
not allow
|
72
|
-
end
|
73
|
-
|
74
|
-
def extract_dir_only(rule)
|
75
|
-
rule.delete_suffix!('/')
|
76
|
-
end
|
77
|
-
|
78
|
-
def strip(rule)
|
79
|
-
rule.chomp!
|
80
|
-
rule.rstrip! unless rule.end_with?('\\ ')
|
81
|
-
end
|
82
|
-
|
83
|
-
def anchored?(rule)
|
84
|
-
rule.include?('/') # we've already removed the trailing '/' with extract_dir_only
|
85
|
-
end
|
86
|
-
|
87
|
-
EXPAND_PATH_RE = %r{^(?:[~/]|\.{1,2}/)}.freeze
|
88
|
-
def expand_rule_path(rule, root)
|
89
|
-
rule.replace(::File.expand_path(rule)) if rule.match?(EXPAND_PATH_RE)
|
90
|
-
rule.delete_prefix!(root)
|
91
|
-
rule.prepend('/') unless rule.start_with?('*') || rule.start_with?('/')
|
92
|
-
end
|
93
|
-
|
94
|
-
def extract_shebang(rule)
|
95
|
-
rule.delete_prefix!('#!:') && (rule.strip! || true)
|
96
|
-
end
|
97
|
-
|
98
|
-
def skip?(rule)
|
99
|
-
rule.empty? || rule.start_with?('#')
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|