leftovers 0.2.3 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -6,34 +6,36 @@ require_relative 'name_rule'
6
6
 
7
7
  module Leftovers
8
8
  class HashRule
9
- def initialize(patterns) # rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/AbcSize, Metrics/PerceivedComplexity
9
+ # :nocov:
10
+ using ::Leftovers::SetCaseEq if defined?(::Leftovers::SetCaseEq)
11
+ # :nocov:
12
+
13
+ def initialize(patterns) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
10
14
  keys = []
11
15
  pairs = []
12
16
  Leftovers.each_or_self(patterns) do |pat|
13
17
  if pat.is_a?(Hash) && pat[:value]
14
18
  pairs << [
15
- (NameRule.new(pat[:keyword]) if pat[:keyword]),
16
- (ValueRule.new(pat[:value]) if pat[:value])
19
+ NameRule.wrap(pat[:keyword] || pat[:index]),
20
+ ValueRule.new(pat[:value])
17
21
  ]
18
22
  else
19
- keys << NameRule.new(pat)
23
+ keys << NameRule.wrap(pat)
20
24
  end
21
25
  end
22
26
 
23
- @keys = (NameRule.new(keys) if keys)
27
+ @keys = NameRule.wrap(keys, false)
24
28
 
25
29
  @pairs = (pairs unless pairs.empty?)
26
30
 
27
31
  freeze
28
32
  end
29
33
 
30
- def match_pair?(key_node, value_node)
31
- return true if @keys&.match?(key_node.to_sym, key_node.to_s)
34
+ def match_pair?(key, value_node)
35
+ return true if @keys === key
32
36
 
33
37
  @pairs&.any? do |(key_rule, value_rule)|
34
- next unless !key_rule || key_rule.match?(key_node.to_sym, key_node.to_s)
35
-
36
- (!value_rule || value_rule.match?(value_node))
38
+ key_rule === key && value_rule.match?(value_node)
37
39
  end
38
40
  end
39
41
  end
@@ -9,18 +9,19 @@ module Leftovers
9
9
  def initialize
10
10
  @configs = []
11
11
  @loaded_configs = Set.new
12
- self.<< Leftovers::Config.new(:ruby)
13
- self.<< project_config
12
+ self << :ruby
13
+ self << project_config
14
14
  load_bundled_gem_config
15
15
  end
16
16
 
17
- def <<(config)
17
+ def <<(config) # rubocop:disable Metrics/MethodLength
18
+ config = Leftovers::Config.new(config) unless config.is_a?(Leftovers::Config)
18
19
  return if @loaded_configs.include?(config.name)
19
20
 
20
21
  unmemoize
21
22
  @configs << config
22
23
  @loaded_configs << config.name
23
- config.gems.each { |gem| self.<< Leftovers::Config.new(gem) }
24
+ config.gems.each { |gem| self << gem }
24
25
  end
25
26
 
26
27
  def project_config
@@ -45,7 +46,8 @@ module Leftovers
45
46
  def test_paths
46
47
  @test_paths ||= FastIgnore.new(
47
48
  include_rules: @configs.flat_map(&:test_paths),
48
- gitignore: false
49
+ gitignore: false,
50
+ root: Leftovers.pwd
49
51
  )
50
52
  end
51
53
 
@@ -60,11 +62,10 @@ module Leftovers
60
62
  private
61
63
 
62
64
  def load_bundled_gem_config
63
- Leftovers.try_require('bundler')
64
- return unless defined?(Bundler)
65
+ return unless Leftovers.try_require('bundler')
65
66
 
66
67
  Bundler.locked_gems.specs.each do |spec|
67
- self.<< Leftovers::Config.new(spec.name.to_sym)
68
+ self << spec.name
68
69
  end
69
70
  end
70
71
  end
@@ -3,51 +3,96 @@
3
3
  require 'set'
4
4
  module Leftovers
5
5
  class NameRule
6
- attr_reader :sym, :syms, :regexp
6
+ # :nocov:
7
+ using ::Leftovers::SetCaseEq if defined?(::Leftovers::SetCaseEq)
8
+ # :nocov:
7
9
 
8
- def initialize(patterns) # rubocop:disable Metrics/PerceivedComplexity, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/AbcSize
10
+ module TrueReturner
11
+ def self.===(_value)
12
+ true
13
+ end
14
+ end
15
+
16
+ module FalseReturner
17
+ def self.===(_value)
18
+ false
19
+ end
20
+ end
21
+
22
+ attr_reader :syms, :regexp
23
+
24
+ def self.wrap(patterns, default = true) # rubocop:disable Metrics/PerceivedComplexity, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/AbcSize
9
25
  regexps = []
10
26
  syms = Set.new
11
- Leftovers.each_or_self(patterns) do |pat|
27
+
28
+ Leftovers.each_or_self(patterns) do |pat| # rubocop:disable Metrics/BlockLength
29
+ # can't have these as part of the case statement because case equality
30
+ next if pat == Leftovers::NameRule::TrueReturner
31
+ next if pat == Leftovers::NameRule::FalseReturner
32
+
12
33
  case pat
34
+ when nil
35
+ nil # do nothing
13
36
  when Leftovers::NameRule
14
- syms.merge(pat.sym) if pat.sym
15
- syms.merge(pat.syms) if pat.syms
16
- regexps.concat(pat.regexp) if pat.regexp
37
+ pat.syms.is_a?(Set) ? syms.merge(pat.syms) : syms << pat.syms
38
+ regexps << pat.regexp
17
39
  when String
18
40
  syms.merge(pat.split(/\s+/).map(&:to_sym))
41
+ when Symbol
42
+ syms << pat
43
+ when Integer
44
+ syms << pat
45
+ when Set
46
+ syms.merge(pat)
47
+ when Regexp
48
+ regexps << pat
19
49
  when Hash
20
50
  if pat[:match]
21
- regexps << /\A#{pattern[:match]}\z/
51
+ regexps << /\A#{pat[:match]}\z/
52
+ elsif pat[:matches]
53
+ regexps << /\A#{pat[:matches]}\z/
22
54
  elsif pat[:has_prefix] && pat[:has_suffix]
23
55
  regexps << /\A#{Regexp.escape(pat[:has_prefix])}.*#{Regexp.escape(pat[:has_suffix])}\z/
24
56
  elsif pat[:has_prefix]
25
57
  regexps << /\A#{Regexp.escape(pat[:has_prefix])}/
26
58
  elsif pat[:has_suffix]
27
59
  regexps << /#{Regexp.escape(pat[:has_suffix])}\z/
60
+ else
61
+ raise Leftovers::ConfigError, "Invalid value for name #{pat}, "\
62
+ 'valid keys are matches, has_prefix, has_suffix'
28
63
  end
64
+ else
65
+ raise Leftovers::ConfigError, "Invalid value type for name #{pat}, "\
66
+ 'valid types are a String, or an object with keys matches, has_prefix, has_suffix'
29
67
  end
30
68
  end
31
69
 
32
- if syms.length <= 0
33
- @sym = syms.first
34
- @syms = nil
70
+ syms = syms.first if syms.length <= 1
71
+
72
+ regexp = if regexps.empty?
73
+ nil
35
74
  else
36
- @sym = nil
37
- @syms = syms
75
+ Regexp.union(regexps).freeze
38
76
  end
39
77
 
40
- @regexp = if regexps.empty?
41
- nil
78
+ if syms && regexp
79
+ new(syms, regexp)
42
80
  else
43
- Regexp.union(regexps)
81
+ syms || regexp || (
82
+ default ? ::Leftovers::NameRule::TrueReturner : ::Leftovers::NameRule::FalseReturner
83
+ )
44
84
  end
85
+ end
86
+
87
+ def initialize(syms, regexp)
88
+ @syms = syms
89
+ @regexp = regexp
45
90
 
46
91
  freeze
47
92
  end
48
93
 
49
- def match?(sym, string)
50
- @sym&.==(sym) || @syms&.include?(sym) || @regexp&.match?(string)
94
+ def ===(sym)
95
+ @syms === sym || @regexp === sym
51
96
  end
52
97
  end
53
98
  end
@@ -49,9 +49,9 @@ module Leftovers
49
49
  end
50
50
 
51
51
  def run(argv)
52
- Leftovers::CLI.new(argv: argv)
53
- rescue SystemExit => e
54
- raise unless e.status == 0
52
+ exitstatus = Leftovers::CLI.new(argv: argv).run
53
+
54
+ exit exitstatus unless exitstatus == 0
55
55
  end
56
56
 
57
57
  def argv_or_default(task_argv)
@@ -4,7 +4,7 @@ module Leftovers
4
4
  class Reporter
5
5
  def call(definition)
6
6
  Leftovers.puts(
7
- "\e[36m#{definition.full_location}\e[0m #{definition.full_name} \e[2m#{definition.highlighted_source("\e[33m", "\e[0;2m")}\e[0m" # rubocop:disable Layout/LineLength
7
+ "\e[36m#{definition.full_location}\e[0m #{definition} \e[2m#{definition.highlighted_source("\e[33m", "\e[0;2m")}\e[0m" # rubocop:disable Layout/LineLength
8
8
  )
9
9
  end
10
10
  end
@@ -6,6 +6,10 @@ require 'fast_ignore'
6
6
 
7
7
  module Leftovers
8
8
  class Rule
9
+ # :nocov:
10
+ using ::Leftovers::SetCaseEq if defined?(::Leftovers::SetCaseEq)
11
+ # :nocov:
12
+
9
13
  def self.wrap(rules)
10
14
  case rules
11
15
  when Array then rules.flat_map { |r| wrap(r) }
@@ -28,29 +32,33 @@ module Leftovers
28
32
  path: nil,
29
33
  paths: nil
30
34
  )
31
- raise ArgumentError, 'Only use one of name/names' if name && names
32
- raise ArgumentError, 'Only use one of path/paths' if path && paths
33
- raise ArgumentError, 'Only use one of call/calls' if call && calls
34
- raise ArgumentError, 'Only use one of define/defines' if define && defines
35
- if skip && (defines || calls)
36
- raise ArgumentError, "skip can't exist with defines or calls for #{name || names}"
35
+ raise Leftovers::ConfigError, 'Only use one of name/names' if name && names
36
+ raise Leftovers::ConfigError, 'Only use one of path/paths' if path && paths
37
+ raise Leftovers::ConfigError, 'Only use one of call/calls' if call && calls
38
+ raise Leftovers::ConfigError, 'Only use one of define/defines' if define && defines
39
+ if skip && (defines || calls || define || call)
40
+ raise Leftovers::ConfigError, "skip can't exist with defines or calls"
37
41
  end
38
42
 
39
- @name_matcher = NameRule.new(name || names)
40
- @path = FastIgnore.new(include_rules: path || paths, gitignore: false) if path || paths
43
+ @name_matcher = NameRule.wrap(name || names)
44
+ if path || paths
45
+ @path = FastIgnore.new(include_rules: path || paths, gitignore: false, root: Leftovers.pwd)
46
+ end
41
47
  @skip = skip
42
48
 
43
49
  begin
44
50
  @calls = ArgumentRule.wrap(calls)
45
- rescue ArgumentError => e
46
- raise e, "#{e.message} for calls for #{name}", e.backtrace
51
+ rescue ArgumentError, Leftovers::ConfigError => e
52
+ raise e, "#{e.message} for calls", e.backtrace
47
53
  end
48
54
 
49
55
  begin
50
56
  @defines = ArgumentRule.wrap(defines, definer: true)
51
- rescue ArgumentError => e
52
- raise e, "#{e.message} for defines for #{name}", e.backtrace
57
+ rescue ArgumentError, Leftovers::ConfigError => e
58
+ raise e, "#{e.message} for defines", e.backtrace
53
59
  end
60
+ rescue ArgumentError, Leftovers::ConfigError => e
61
+ raise e, "#{e.message} for #{Array(name || names).map(&:to_s).join(', ')}", e.backtrace
54
62
  end
55
63
 
56
64
  def filename?(file)
@@ -59,8 +67,8 @@ module Leftovers
59
67
  @path.allowed?(file)
60
68
  end
61
69
 
62
- def match?(name, name_s, file)
63
- @name_matcher.match?(name, name_s) && filename?(file)
70
+ def match?(name, file)
71
+ @name_matcher === name && filename?(file)
64
72
  end
65
73
 
66
74
  def calls(node)
@@ -37,9 +37,7 @@ module Leftovers
37
37
  replace_with
38
38
  }.freeze
39
39
 
40
- VALID_TRANSFORMS = RUBY_STRING_METHODS + ACTIVESUPPORT_STRING_METHODS + CUSTOM_TRANSFORMS
41
- # more possible transformations
42
- # gsub sub tr tr_s
40
+ VALID_TRANSFORMS = CUSTOM_TRANSFORMS + RUBY_STRING_METHODS + ACTIVESUPPORT_STRING_METHODS
43
41
  def initialize(transforms)
44
42
  @transforms = prepare_transforms(transforms)
45
43
 
@@ -58,9 +56,9 @@ module Leftovers
58
56
  def prepare_transforms(transforms) # rubocop:disable Metrics/MethodLength
59
57
  transforms.map do |key, value|
60
58
  unless VALID_TRANSFORMS.include?(key)
61
- raise ArgumentError, <<~MESSAGE
62
- invalid transform key: (#{key}: #{value}).
63
- Valid transform keys are #{ALL_VALID_TRANSFORMS}"
59
+ raise Leftovers::ConfigError, <<~MESSAGE
60
+ invalid transform key: (#{key}: #{value})
61
+ Valid transform keys are #{VALID_TRANSFORMS.join(', ')}
64
62
  MESSAGE
65
63
  end
66
64
 
@@ -74,18 +72,18 @@ module Leftovers
74
72
  HASH_VALUE_TRANSFORMS = %i{add_prefix add_suffix}.freeze
75
73
  HASH_VALUE_KEYS = %i{from_argument joiner}.freeze
76
74
  def prepare_hash_value(method, hash) # rubocop:disable Metrics/MethodLength
77
- raise ArgumentError, <<~MESSAGE unless HASH_VALUE_TRANSFORMS.include?(method)
78
- invalid transform value (#{key}: #{value}).
79
- Hash values are only valid for #{HASH_VALUE_TRANSFORMS}
75
+ raise Leftovers::ConfigError, <<~MESSAGE unless HASH_VALUE_TRANSFORMS.include?(method)
76
+ invalid transform value (#{method}: #{hash.inspect}).
77
+ Hash values are only valid for #{HASH_VALUE_TRANSFORMS.join(', ')}
80
78
  MESSAGE
81
79
 
82
80
  hash = hash.map do |k, v|
83
- raise ArgumentError, <<~MESSAGE unless HASH_VALUE_KEYS.include?(k)
81
+ raise Leftovers::ConfigError, <<~MESSAGE unless HASH_VALUE_KEYS.include?(k)
84
82
  invalid transform value argument (#{method}: { #{k}: #{v} }).
85
- Hash values are only valid for #{HASH_VALUE_TRANSFORMS}
83
+ Valid keys are #{HASH_VALUE_KEYS.join(', ')}
86
84
  MESSAGE
87
85
 
88
- [k, v.to_sym]
86
+ [k, (v.respond_to?(:to_sym) ? v.to_sym : v)]
89
87
  end.to_h
90
88
 
91
89
  ["#{method}_dynamic", hash]
@@ -143,26 +141,26 @@ module Leftovers
143
141
  end
144
142
 
145
143
  def add_prefix_dynamic(string, method_node)
146
- "#{dynamic_value(@add_prefix_dynamic, method_node)}#{@add_prefix_dynamic[:joiner]}#{string}"
144
+ prefix = dynamic_value(@add_prefix_dynamic, method_node)
145
+ "#{prefix}#{@add_prefix_dynamic[:joiner] if prefix}#{string}"
147
146
  end
148
147
 
149
148
  def add_suffix_dynamic(string, method_node)
150
- "#{string}#{@add_suffix_dynamic[:joiner]}#{dynamic_value(@add_suffix_dynamic, method_node)}"
149
+ suffix = dynamic_value(@add_suffix_dynamic, method_node)
150
+ "#{string}#{@add_suffix_dynamic[:joiner] if suffix}#{suffix}"
151
151
  end
152
152
 
153
153
  def dynamic_value(value, method_node)
154
- method_node.kwargs[value[:from_argument]].to_s if value[:from_argument]
154
+ method_node[value[:from_argument]] if value[:from_argument]
155
155
  end
156
156
 
157
157
  def activesupport_available?(method) # rubocop:disable Metrics/MethodLength
158
- Leftovers.try_require(
159
- 'active_support/core_ext/string', 'active_support/inflections',
160
- message: <<~MESSAGE
161
- Tried transforming a string using an activesupport method (#{method}), but the activesupport gem was not available
162
- `gem install activesupport`
163
- MESSAGE
164
- )
165
-
158
+ message = <<~MESSAGE
159
+ Tried transforming a string using an activesupport method (#{method}), but the activesupport gem was not available
160
+ `gem install activesupport`
161
+ MESSAGE
162
+ Leftovers.try_require('active_support/core_ext/string', message: message)
163
+ Leftovers.try_require('active_support/inflections', message: message)
166
164
  Leftovers.try_require(::File.join(Leftovers.pwd, 'config', 'initializers', 'inflections.rb'))
167
165
 
168
166
  defined?(ActiveSupport)
@@ -9,19 +9,20 @@ module Leftovers
9
9
  Leftovers.each_or_self(values) do |value|
10
10
  case value
11
11
  when Hash
12
- raise ArgumentError, "invalid value #{value.inspect}" unless value[:type]
12
+ raise Leftovers::ConfigError, "invalid value #{value.inspect}" unless value[:type]
13
13
 
14
14
  value_types.merge(
15
15
  Array(value[:type]).map do |v|
16
16
  case v
17
- when 'String', :String then :str
18
- when 'Symbol', :Symbol then :sym
17
+ when 'String' then :str
18
+ when 'Symbol' then :sym
19
+ when 'Integer' then :int
19
20
  else v.to_s.downcase.to_sym
20
21
  end
21
22
  end
22
23
  )
23
24
  else
24
- (literal_values << value) if value
25
+ literal_values << value
25
26
  end
26
27
  end
27
28
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Leftovers
4
- VERSION = '0.2.3'
4
+ VERSION = '0.3.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: leftovers
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dana Sherson
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-04-22 00:00:00.000000000 Z
11
+ date: 2020-05-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -100,14 +100,14 @@ dependencies:
100
100
  requirements:
101
101
  - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: '0.74'
103
+ version: '0.82'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: '0.74'
110
+ version: '0.82'
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: rubocop-performance
113
113
  requirement: !ruby/object:Gem::Requirement
@@ -136,6 +136,48 @@ dependencies:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
138
  version: '1.35'
139
+ - !ruby/object:Gem::Dependency
140
+ name: simplecov
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: 0.18.5
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: 0.18.5
153
+ - !ruby/object:Gem::Dependency
154
+ name: simplecov-console
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: tty_string
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: 0.2.1
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: 0.2.1
139
181
  - !ruby/object:Gem::Dependency
140
182
  name: spellr
141
183
  requirement: !ruby/object:Gem::Requirement
@@ -156,14 +198,14 @@ dependencies:
156
198
  requirements:
157
199
  - - ">="
158
200
  - !ruby/object:Gem::Version
159
- version: 0.10.0
201
+ version: 0.11.0
160
202
  type: :runtime
161
203
  prerelease: false
162
204
  version_requirements: !ruby/object:Gem::Requirement
163
205
  requirements:
164
206
  - - ">="
165
207
  - !ruby/object:Gem::Version
166
- version: 0.10.0
208
+ version: 0.11.0
167
209
  - !ruby/object:Gem::Dependency
168
210
  name: parallel
169
211
  requirement: !ruby/object:Gem::Requirement
@@ -226,7 +268,7 @@ files:
226
268
  - lib/config/rollbar.yml
227
269
  - lib/config/rspec.yml
228
270
  - lib/config/ruby.yml
229
- - lib/config/selenium.yml
271
+ - lib/config/selenium-webdriver.yml
230
272
  - lib/config/sidekiq.yml
231
273
  - lib/config/simplecov.yml
232
274
  - lib/config/will_paginate.yml