fast_ignore 0.10.0 → 0.10.1
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 +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
|