leftovers 0.2.3 → 0.3.0

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.
@@ -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