fast_ignore 0.12.0 → 0.15.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1 +0,0 @@
1
- rspec
@@ -1,3 +0,0 @@
1
- env
2
- euo
3
- usr
@@ -1,11 +0,0 @@
1
- ---
2
- sudo: false
3
- language: ruby
4
- cache: bundler
5
- before_install: gem install bundler
6
- rvm:
7
- - 2.4
8
- - 2.5
9
- - 2.6
10
- - 2.7
11
- - jruby
data/Gemfile DELETED
@@ -1,9 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- source 'https://rubygems.org'
4
-
5
- git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
6
-
7
- # Specify your gem's dependencies in fast_ignore.gemspec
8
-
9
- gemspec
data/Rakefile DELETED
@@ -1,18 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'bundler/gem_tasks'
4
- require 'rspec/core/rake_task'
5
- require 'rubocop/rake_task'
6
- require 'spellr/rake_task'
7
- require 'leftovers/rake_task'
8
-
9
- RuboCop::RakeTask.new
10
- RSpec::Core::RakeTask.new(:spec)
11
- Spellr::RakeTask.generate_task
12
- Leftovers::RakeTask.generate_task
13
-
14
- if RUBY_PLATFORM == 'java'
15
- task default: :spec
16
- else
17
- task default: [:spec, :rubocop, :spellr, :leftovers]
18
- end
@@ -1,8 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- require 'bundler/setup'
5
- require 'fast_ignore'
6
-
7
- require 'pry'
8
- Pry.start
data/bin/ls DELETED
@@ -1,6 +0,0 @@
1
- #!/usr/bin/env ruby --disable-all
2
- # frozen_string_literal: true
3
-
4
- require_relative '../lib/fast_ignore'
5
-
6
- puts FastIgnore.new(relative: true, argv_rules: ARGV).to_a
@@ -1,21 +0,0 @@
1
- #!/usr/bin/env ruby --disable-all
2
- # frozen_string_literal: true
3
-
4
- require_relative '../lib/fast_ignore'
5
-
6
- t1 = Process.clock_gettime(Process::CLOCK_MONOTONIC)
7
- new_a = FastIgnore.new(relative: true, argv_rules: ARGV).to_a
8
- t2 = Process.clock_gettime(Process::CLOCK_MONOTONIC)
9
- puts "new #{new_a.count}: #{t2 - t1}"
10
- fi = FastIgnore.new(relative: true, argv_rules: ARGV)
11
- fi.to_a
12
- t3 = Process.clock_gettime(Process::CLOCK_MONOTONIC)
13
- cached_a = fi.to_a
14
- t4 = Process.clock_gettime(Process::CLOCK_MONOTONIC)
15
- puts "cached #{cached_a.count}: #{t4 - t3}"
16
- t5 = Process.clock_gettime(Process::CLOCK_MONOTONIC)
17
- git_a = `git ls-files`.split("\n")
18
- t6 = Process.clock_gettime(Process::CLOCK_MONOTONIC)
19
- puts "git ls-files #{git_a.count}: #{t6 - t5}"
20
-
21
- exit 1 unless new_a.length == cached_a.length && new_a.length == git_a.length
data/bin/setup DELETED
@@ -1,8 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
- set -vx
5
-
6
- bundle install
7
-
8
- # Do any other automated setup that you need to do here
data/bin/time DELETED
@@ -1,21 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- # use mac terminal not vs code terminal
5
- # ensure nothing else is watching that dir in the filesystem e.g. webpack
6
-
7
- require 'open3'
8
- require 'shellwords'
9
- RUNS = 30
10
- SCRIPT = "time #{__dir__}/ls #{Shellwords.join(ARGV)}"
11
-
12
- times = Array.new(RUNS).map do
13
- run_times = Open3.capture3(SCRIPT)[1]
14
- puts run_times.lstrip
15
- run_times.scan(/(?:\d+(?:.\d+)?)/)
16
- end
17
-
18
- puts format(
19
- "\e[1mAverage:\n\e[32m%0.2f real %0.2f user %0.2f sys\e[0m", # rubocop:disable Style/FormatStringToken
20
- *times.transpose.map { |n| (n.map(&:to_f).sum / RUNS) }
21
- )
@@ -1,41 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- lib = File.expand_path('lib', __dir__)
4
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
- require 'fast_ignore/version'
6
-
7
- Gem::Specification.new do |spec|
8
- spec.name = 'fast_ignore'
9
- spec.version = FastIgnore::VERSION
10
- spec.authors = ['Dana Sherson']
11
- spec.email = ['robot@dana.sh']
12
-
13
- spec.summary = 'Parse gitignore files, quickly'
14
- spec.homepage = 'https://github.com/robotdana/fast_ignore'
15
- spec.license = 'MIT'
16
-
17
- spec.required_ruby_version = '~> 2.4'
18
-
19
- if spec.respond_to?(:metadata)
20
- spec.metadata['homepage_uri'] = spec.homepage
21
- spec.metadata['source_code_uri'] = 'https://github.com/robotdana/fast_ignore'
22
- spec.metadata['changelog_uri'] = 'https://github.com/robotdana/fast_ignore/blob/master/CHANGELOG.md'
23
- end
24
-
25
- # Specify which files should be added to the gem when it is released.
26
- # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
27
- spec.files = Dir.chdir(File.expand_path(__dir__)) do
28
- `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
29
- end
30
- spec.require_paths = ['lib']
31
-
32
- spec.add_development_dependency 'bundler', '>= 1.17'
33
- spec.add_development_dependency 'leftovers', '>= 0.2.2'
34
- spec.add_development_dependency 'pry', '> 0'
35
- spec.add_development_dependency 'rake', '>= 12.3.3'
36
- spec.add_development_dependency 'rspec', '~> 3.0'
37
- spec.add_development_dependency 'rubocop', '>= 0.74.0'
38
- spec.add_development_dependency 'rubocop-rspec', '~> 1'
39
- spec.add_development_dependency 'simplecov', '~> 0.18.5'
40
- spec.add_development_dependency 'spellr', '>= 0.8.3'
41
- end
@@ -1,96 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class FastIgnore
4
- module FNMatchToRegex
5
- # This doesn't look rubyish because i ported it from rust (the only rust i ever wrote that worked)
6
- class << self
7
- def call(pattern) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
8
- re = '\\A'.dup
9
-
10
- in_character_group = false
11
- has_characters_in_group = false
12
- escape_next_character = false
13
- last_char_opened_character_group = false
14
- negated_character_group = false
15
- stars = 0
16
-
17
- pattern.each_char do |char| # rubocop:disable Metrics/BlockLength
18
- if escape_next_character
19
- re << Regexp.escape(char)
20
- escape_next_character = false
21
- elsif char == '\\' # single char, just needs to be escaped
22
- escape_next_character = true
23
- elsif in_character_group
24
- if char == '/'
25
- if negated_character_group
26
- has_characters_in_group = true
27
- re << char
28
- end
29
- elsif char == '^'
30
- if last_char_opened_character_group
31
- re << char
32
- negated_character_group = true
33
- else
34
- re << '\\^'
35
- has_characters_in_group = true
36
- end
37
- # not characters in group
38
- elsif char == ']'
39
- break unless has_characters_in_group
40
-
41
- re << ']'
42
- in_character_group = false
43
- has_characters_in_group = false
44
- negated_character_group = false
45
- last_char_opened_character_group = false
46
- elsif char == '-'
47
- has_characters_in_group = true
48
- re << char
49
- else
50
- has_characters_in_group = true
51
- re << Regexp.escape(char)
52
- end
53
- last_char_opened_character_group = false
54
- elsif char == '*'
55
- stars += 1
56
- elsif char == '/'
57
- re << if stars >= 2
58
- '(?:.*/)?'
59
- elsif stars.positive?
60
- '[^/]*/'
61
- else
62
- char
63
- end
64
- stars = 0
65
- else
66
- if stars.positive?
67
- re << '[^/]*'
68
- stars = 0
69
- end
70
- if char == '?'
71
- re << '[^/]'
72
- elsif char == '['
73
- re << '['
74
- in_character_group = true
75
- last_char_opened_character_group = true
76
- else
77
- re << Regexp.escape(char)
78
- end
79
- end
80
- end
81
-
82
- if in_character_group
83
- return /(?!)/ # impossible to match anything
84
- end
85
-
86
- if stars >= 2
87
- re << '.*'
88
- elsif stars.positive?
89
- re << '[^/]*'
90
- end
91
- re << '\\z'
92
- Regexp.new(re, Regexp::IGNORECASE)
93
- end
94
- end
95
- end
96
- end
@@ -1,126 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class FastIgnore
4
- module RuleSetBuilder
5
- class << self
6
- # :nocov:
7
- using ::FastIgnore::Backports::DeletePrefixSuffix if defined?(::FastIgnore::Backports::DeletePrefixSuffix)
8
- # :nocov:
9
-
10
- def build( # rubocop:disable Metrics/ParameterLists
11
- root:,
12
- ignore_rules: nil,
13
- ignore_files: nil,
14
- gitignore: :auto,
15
- include_rules: nil,
16
- include_files: nil,
17
- argv_rules: nil
18
- )
19
- prepare [
20
- from_array(ignore_rules),
21
- *from_files(ignore_files, project_root: root),
22
- from_array('.git'),
23
- from_gitignore_arg(gitignore, project_root: root),
24
- from_array(include_rules, allow: true),
25
- *from_files(include_files, allow: true, project_root: root),
26
- from_array(argv_rules, allow: true, expand_path: root)
27
- ]
28
- end
29
-
30
- def append_gitignore(rule_sets, project_root:, relative_path:, soft: true)
31
- new_gitignore = from_file(relative_path, project_root: project_root, gitignore: true, soft: soft)
32
- return unless new_gitignore
33
-
34
- base_gitignore = rule_sets.find(&:gitignore?)
35
- if base_gitignore
36
- base_gitignore << new_gitignore
37
- else
38
- rule_sets << new_gitignore
39
- prepare(rule_sets)
40
- end
41
- end
42
-
43
- private
44
-
45
- def prepare(rule_sets)
46
- rule_sets.compact!
47
- rule_sets.reject!(&:empty?)
48
- rule_sets.sort_by!(&:weight)
49
- rule_sets
50
- end
51
-
52
- def from_file(filename, project_root:, allow: false, file_root: nil, gitignore: false, soft: false) # rubocop:disable Metrics/ParameterLists
53
- filename = ::File.expand_path(filename, project_root)
54
- return if soft && !::File.exist?(filename)
55
- unless file_root || filename.start_with?(project_root)
56
- raise FastIgnore::Error, "#{filename} is not within #{project_root}"
57
- end
58
-
59
- file_root ||= "#{::File.dirname(filename)}/".delete_prefix(project_root)
60
- build_rule_set(::File.readlines(filename), allow, file_root: file_root, gitignore: gitignore)
61
- end
62
-
63
- def from_files(files, project_root:, allow: false)
64
- Array(files).map do |file|
65
- from_file(file, project_root: project_root, allow: allow)
66
- end
67
- end
68
-
69
- def from_gitignore_arg(gitignore, project_root:)
70
- return unless gitignore
71
-
72
- gi = ::FastIgnore::RuleSet.new([], false, true)
73
- gi << from_gitignore_file(gitconfig_global_gitignore_path || default_global_gitignore_path)
74
- gi << from_gitignore_file(::File.join(project_root, '.git/info/exclude'))
75
- gi << from_gitignore_file(::File.join(project_root, '.gitignore'), soft: gitignore == :auto)
76
- gi
77
- end
78
-
79
- def from_gitignore_file(path, soft: true)
80
- return if soft && !::File.exist?(path)
81
-
82
- build_rule_set(::File.readlines(path), false, file_root: '', gitignore: true)
83
- end
84
-
85
- def gitconfig_global_gitignore_path
86
- config_path = ::File.expand_path('~/.gitconfig')
87
- return unless ::File.exist?(config_path)
88
-
89
- ignore_path = ::File.readlines(config_path).find { |l| l.start_with?("\texcludesfile = ") }
90
- return unless ignore_path
91
-
92
- ignore_path.delete_prefix!("\texcludesfile = ")
93
- ignore_path.strip!
94
- ::File.expand_path(ignore_path)
95
- end
96
-
97
- def default_global_gitignore_path
98
- if ENV['XDG_CONFIG_HOME'] && !ENV['XDG_CONFIG_HOME'].empty?
99
- ::File.expand_path('git/ignore', ENV['XDG_CONFIG_HOME'])
100
- else
101
- ::File.expand_path('~/.config/git/ignore')
102
- end
103
- end
104
-
105
- def from_array(rules, allow: false, expand_path: false)
106
- return unless rules
107
-
108
- rules = Array(rules)
109
-
110
- return if rules.empty?
111
-
112
- rules = rules.flat_map { |string| string.to_s.lines }
113
-
114
- build_rule_set(rules, allow, expand_path: expand_path)
115
- end
116
-
117
- def build_rule_set(rules, allow, expand_path: false, file_root: nil, gitignore: false)
118
- rules = rules.flat_map do |rule|
119
- ::FastIgnore::RuleBuilder.build(rule, allow, expand_path, file_root)
120
- end
121
-
122
- ::FastIgnore::RuleSet.new(rules, allow, gitignore)
123
- end
124
- end
125
- end
126
- end