leftovers 0.4.0 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 02f0f5136df6e16a7d27e47d118446f9118395f9242e29a32c91476ccd070591
4
- data.tar.gz: fa438c525a212769b17cae1b2e2f05495c2772da5c9f3a05c9dd2d869743e969
3
+ metadata.gz: a3fb0707b239e6e7581c2997969483c72b3ff272895173828fc3434c08de165a
4
+ data.tar.gz: aadfba4e9fc93b110599c8e2bd66f723efbce39cabf4deda036d904358cfa131
5
5
  SHA512:
6
- metadata.gz: 3c88300e0a1e822f510dd22ff72a91ab1db5ed35ac7cdd323ec3fe194f347748faad08efd62ac727501ed6f854e5623b6958589e216a4e2389ed44f9fc878b54
7
- data.tar.gz: '08deaf4ffb911b2a1d53960e5bfc6c46a3990d0a6197d28f18b8ccfc60031b48c3701dca1e1d1ffe7db5e1ab892b1630c9332e87706769326141b0793115a2d6'
6
+ metadata.gz: 129fe2d42ec0f47d9f76105c1d53f0209133864d77688db231cb9fbc3c5ad3e6ea3ea8bdd95b1902b480b8a7e78709f2c197b261e1132ae0ce3cddc618e39899
7
+ data.tar.gz: 1d01550bdf1762344c2744d21f01c1590b928a751439714e5ad364211b2a914aec486415f1d5769113b1d3bf23023319c3d68bf72b733367dc7851fdc9e4ffb9
@@ -1,3 +1,5 @@
1
+ # v0.4.1
2
+ - add `test_only:` to mark methods/constants/assignments as test_only in the config rather than just with magic comments
1
3
 
2
4
  # v0.4.0
3
5
  - add `requires:` to .leftovers.yml config to e.g. load inflections in a different place than `config/initializers/inflections`
data/README.md CHANGED
@@ -72,16 +72,16 @@ class MyClass
72
72
  end
73
73
  ```
74
74
  This would report `MyClass` is unused, but not my_method
75
- To do this for all definitions of this name, add the name with `skip: true` in the configuration file.
75
+ To do this for all definitions of this name, instead of adding a comment, add the name to the [`keep:`](https://github.com/robotdana/leftovers/tree/main/docs/Configuration.md#keep) list in the [configuration file](#configuration-file).
76
76
 
77
- ### `# leftovers:test`
77
+ ### `# leftovers:test_only`
78
78
  _aliases `leftovers:for_test`, `leftovers:for_tests`, `leftovers:test`, `leftovers:tests`, `leftovers:testing`_
79
79
 
80
- To mark a definition from a non-test dir, as intentionally only used by tests, use `leftovers:test`
80
+ To mark a definition from a non-test dir, as intentionally only used by tests, use `leftovers:test_only`
81
81
  ```ruby
82
82
  # app/my_class.rb
83
83
  class MyClass
84
- def my_method # leftovers:test
84
+ def my_method # leftovers:test_only
85
85
  true
86
86
  end
87
87
  end
@@ -95,6 +95,8 @@ end
95
95
 
96
96
  This would consider `my_method` to be used, even though it is only called by tests.
97
97
 
98
+ To do this for all definitions of this name, instead of adding a comment, add the name to the [`test_only:`](https://github.com/robotdana/leftovers/tree/main/docs/Configuration.md#test_only) list in the [configuration file](#configuration-file).
99
+
98
100
  ### `# leftovers:call`
99
101
  _aliases `leftovers:calls`_
100
102
  To mark a dynamic call that doesn't use literal values, use `leftovers:call` with the method name listed
@@ -116,6 +118,7 @@ Its presence is optional and all of these settings are optional.
116
118
  - [`requires:`](https://github.com/robotdana/leftovers/tree/main/docs/Configuration.md#requires)
117
119
  - [`gems:`](https://github.com/robotdana/leftovers/tree/main/docs/Configuration.md#gems)
118
120
  - [`keep:`](https://github.com/robotdana/leftovers/tree/main/docs/Configuration.md#keep)
121
+ - [`test_only:`](https://github.com/robotdana/leftovers/tree/main/docs/Configuration.md#test_only)
119
122
  - [`dynamic:`](https://github.com/robotdana/leftovers/tree/main/docs/Configuration.md#dynamic)
120
123
 
121
124
  see the [complete config documentation](https://github.com/robotdana/leftovers/tree/main/docs/Configuration.md) for details.
@@ -9,6 +9,7 @@ Its presence is optional and all of these settings are optional.
9
9
  - [`requires:`](#requires)
10
10
  - [`gems:`](#gems)
11
11
  - [`keep:`](#keep)
12
+ - [`test_only:](#test_only)
12
13
  - [`dynamic:`](#dynamic)
13
14
 
14
15
  see the [built in config files](https://github.com/robotdana/leftovers/tree/main/lib/config) or [this repo's own config](https://github.com/robotdana/leftovers/tree/main/.leftovers.yml) for examples.
@@ -120,6 +121,34 @@ keep:
120
121
 
121
122
  Alternatively, you can mark method/constants/variables in-place using [magic comments](https://github.com/robotdana/leftovers/tree/main/README.md#magic-comments).
122
123
 
124
+ ## `test_only:`
125
+
126
+ This is a list of methods/constants/variables that are ok to be defined outside of [test paths](#test_paths), but only used within test paths, maybe because they're your public api, or convenience methods for tests etc.
127
+
128
+ Each entry can be a string (an exact match for a method, constant, or variable name that includes the sigil), or have at least one of the following properties:
129
+ - [`names:`](#names)
130
+ or the properties from `names:`
131
+ - [`has_prefix:`](#has_prefix)
132
+ - [`has_suffix:`](#has_suffix)
133
+ - [`matches:`](#matches) (can't be used in the same entry as `has_prefix:` or `has_suffix:`)
134
+ - [`paths:`](#paths)
135
+ - [`has_arguments:`](#has_arguments)
136
+ - [`unless`](#unless)
137
+
138
+ Arrays are not necessary for single values
139
+
140
+ example from rails.yml
141
+ ```yml
142
+ test_only:
143
+ - APP_PATH
144
+ - ssl_configured?
145
+ - has_suffix: Helper
146
+ path: /app/helpers
147
+ ...
148
+ ```
149
+
150
+ Alternatively, you can mark method/constants/variables in-place using [magic comments](https://github.com/robotdana/leftovers/tree/main/README.md#magic-comments).
151
+
123
152
  ## `dynamic:`
124
153
 
125
154
  This is a list of methods, constants, or variables whose called arguments or assigned value/s are used to dynamically `call:` or define (`define:`) other methods, constants, or variables
@@ -11,6 +11,7 @@ module Leftovers # rubocop:disable Metrics/ModuleLength
11
11
  autoload(:Collector, "#{__dir__}/leftovers/collector")
12
12
  autoload(:ConfigValidator, "#{__dir__}/leftovers/config_validator")
13
13
  autoload(:Config, "#{__dir__}/leftovers/config")
14
+ autoload(:DefinitionNode, "#{__dir__}/leftovers/definition_node")
14
15
  autoload(:DefinitionSet, "#{__dir__}/leftovers/definition_set")
15
16
  autoload(:Definition, "#{__dir__}/leftovers/definition")
16
17
  autoload(:ERB, "#{__dir__}/leftovers/erb")
@@ -25,12 +25,12 @@ module Leftovers
25
25
  @memo[:path] ||= loc.expression.source_buffer.name.to_s
26
26
  end
27
27
 
28
- def test?
29
- @memo[:test]
28
+ def test_line?
29
+ @memo[:test_line]
30
30
  end
31
31
 
32
- def test=(value)
33
- @memo[:test] = value
32
+ def test_line=(value)
33
+ @memo[:test_line] = value
34
34
  end
35
35
 
36
36
  def keep_line=(value)
@@ -40,6 +40,10 @@ module Leftovers
40
40
  @keep ||= ::Leftovers::MatcherBuilders::Node.build(yaml[:keep])
41
41
  end
42
42
 
43
+ def test_only
44
+ @test_only ||= ::Leftovers::MatcherBuilders::Node.build(yaml[:test_only])
45
+ end
46
+
43
47
  def requires
44
48
  @requires ||= Array(yaml[:requires])
45
49
  end
@@ -445,7 +445,7 @@ module Leftovers
445
445
  { '$ref' => '#/definitions/dynamic' }
446
446
  ]
447
447
  },
448
- 'keep' => {
448
+ 'keepTestOnly' => {
449
449
  'anyOf' => [
450
450
  { '$ref' => '#/definitions/string' },
451
451
  {
@@ -460,7 +460,7 @@ module Leftovers
460
460
  'has_prefix' => true, 'has_suffix' => true, 'matches' => true,
461
461
  'path' => true, 'paths' => true,
462
462
  'has_argument' => true, 'has_arguments' => true,
463
- 'unless' => { '$ref' => '#/definitions/keepList' }
463
+ 'unless' => { '$ref' => '#/definitions/keepTestOnlyList' }
464
464
  },
465
465
  'additionalProperties' => false,
466
466
  'minProperties' => 1
@@ -469,15 +469,15 @@ module Leftovers
469
469
  }
470
470
  ]
471
471
  },
472
- 'keepList' => {
472
+ 'keepTestOnlyList' => {
473
473
  'anyOf' => [
474
474
  {
475
475
  'type' => 'array',
476
- 'items' => { '$ref' => '#/definitions/keep' },
476
+ 'items' => { '$ref' => '#/definitions/keepTestOnly' },
477
477
  'minItems' => 1,
478
478
  'uniqueItems' => true
479
479
  },
480
- { '$ref' => '#/definitions/keep' }
480
+ { '$ref' => '#/definitions/keepTestOnly' }
481
481
  ]
482
482
  }
483
483
  },
@@ -487,7 +487,8 @@ module Leftovers
487
487
  'test_paths' => { '$ref' => '#/definitions/stringList' },
488
488
  'requires' => { '$ref' => '#/definitions/stringList' },
489
489
  'gems' => { '$ref' => '#/definitions/stringList' },
490
- 'keep' => { '$ref' => '#/definitions/keepList' },
490
+ 'keep' => { '$ref' => '#/definitions/keepTestOnlyList' },
491
+ 'test_only' => { '$ref' => '#/definitions/keepTestOnlyList' },
491
492
  'dynamic' => { '$ref' => '#/definitions/dynamicList' }
492
493
  }
493
494
  }.freeze
@@ -9,11 +9,11 @@ module Leftovers
9
9
 
10
10
  def initialize(
11
11
  name,
12
- method_node: nil,
13
12
  location: method_node.loc.expression,
14
- test: method_node.test?
13
+ test: method_node.test_line?
15
14
  )
16
15
  @name = name
16
+ @path = location.source_buffer.name.to_s
17
17
  @location_source_line = location.source_line.to_s
18
18
  @location_column_range_begin = location.column_range.begin.to_i
19
19
  @location_column_range_end = location.column_range.end.to_i
@@ -0,0 +1,36 @@
1
+ # frozen-string-literal: true
2
+
3
+ # To give to matchers before creating a Definition
4
+
5
+ module Leftovers
6
+ class DefinitionNode
7
+ attr_reader :path, :name
8
+
9
+ def initialize(name, path)
10
+ @name = name
11
+ @path = path
12
+
13
+ freeze
14
+ end
15
+
16
+ # these are the methods checked by things in lib/leftovers/matchers
17
+ def kwargs
18
+ nil
19
+ end
20
+
21
+ def positional_arguments
22
+ nil
23
+ end
24
+
25
+ # these two i'm not sure are possible with the current config flags
26
+ # :nocov:
27
+ def scalar?
28
+ false
29
+ end
30
+
31
+ def type
32
+ :leftovers_definition
33
+ end
34
+ # :nocov:
35
+ end
36
+ end
@@ -1,18 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Leftovers
4
- class DefinitionSet < ::Leftovers::Definition
4
+ class DefinitionSet
5
5
  attr_reader :definitions
6
6
 
7
- def initialize(
8
- definitions,
9
- method_node: nil,
10
- location: method_node.loc.expression,
11
- test: method_node.test?
12
- )
7
+ def initialize(definitions)
13
8
  @definitions = definitions
14
9
 
15
- super
10
+ freeze
16
11
  end
17
12
 
18
13
  def names
@@ -23,10 +18,22 @@ module Leftovers
23
18
  @definitions.map(&:to_s).join(', ')
24
19
  end
25
20
 
21
+ def location_s
22
+ @definitions.first.location_s
23
+ end
24
+
25
+ def highlighted_source(*args)
26
+ @definitions.first.highlighted_source(*args)
27
+ end
28
+
26
29
  def in_collection?
27
30
  @definitions.any?(&:in_collection?)
28
31
  end
29
32
 
33
+ def test?
34
+ @definitions.any?(&:test?)
35
+ end
36
+
30
37
  def in_test_collection?
31
38
  @definitions.any?(&:in_test_collection?)
32
39
  end
@@ -57,7 +57,7 @@ module Leftovers
57
57
  NAME_RE = Regexp.union(METHOD_NAME_RE, NON_ALNUM_METHOD_NAME_RE, CONSTANT_NAME_RE)
58
58
  LEFTOVERS_CALL_RE = /\bleftovers:call(?:s|ed|er|ers|) (#{NAME_RE}(?:[, :]+#{NAME_RE})*)/.freeze
59
59
  LEFTOVERS_ALLOW_RE = /\bleftovers:(?:keeps?|skip(?:s|ped|)|allow(?:s|ed|))\b/.freeze
60
- LEFTOVERS_TEST_RE = /\bleftovers:(?:for_tests?|tests?|testing)\b/.freeze
60
+ LEFTOVERS_TEST_RE = /\bleftovers:(?:for_tests?|tests?|testing|test_only)\b/.freeze
61
61
  def process_comments(comments) # rubocop:disable Metrics/AbcSize
62
62
  comments.each do |comment|
63
63
  @allow_lines << comment.loc.line if comment.text.match?(LEFTOVERS_ALLOW_RE)
@@ -171,15 +171,20 @@ module Leftovers
171
171
 
172
172
  private
173
173
 
174
- def test?(loc)
175
- @file.test? || @test_lines.include?(loc.line)
174
+ def test_line?(loc)
175
+ @file.test? ||
176
+ @test_lines.include?(loc.line)
177
+ end
178
+
179
+ def test_node?(node, loc)
180
+ test_line?(loc) || ::Leftovers.config.test_only === node
176
181
  end
177
182
 
178
183
  def add_definition(node, name: node.name, loc: node.loc.name)
179
184
  return if @allow_lines.include?(loc.line)
180
185
  return if Leftovers.config.keep === node
181
186
 
182
- definitions << Leftovers::Definition.new(name, location: loc, test: test?(loc))
187
+ definitions << Leftovers::Definition.new(name, location: loc, test: test_node?(node, loc))
183
188
  end
184
189
 
185
190
  def add_call(name)
@@ -222,7 +227,7 @@ module Leftovers
222
227
 
223
228
  def collect_dynamic(node) # rubocop:disable Metrics/AbcSize
224
229
  node.keep_line = @allow_lines.include?(node.loc.line)
225
- node.test = test?(node.loc) unless node.keep_line?
230
+ node.test_line = test_line?(node.loc) unless node.keep_line?
226
231
 
227
232
  Leftovers.config.dynamic.process(node, self)
228
233
  rescue StandardError => e
@@ -64,6 +64,10 @@ module Leftovers
64
64
  @keep ||= ::Leftovers::MatcherBuilders::Or.build(@configs.map(&:keep))
65
65
  end
66
66
 
67
+ def test_only
68
+ @test_only ||= ::Leftovers::MatcherBuilders::Or.build(@configs.map(&:test_only))
69
+ end
70
+
67
71
  private
68
72
 
69
73
  def load_bundled_gem_config
@@ -9,7 +9,7 @@ module Leftovers
9
9
  freeze
10
10
  end
11
11
 
12
- def process(str, node, method_node) # rubocop:disable Metrics/MethodLength
12
+ def process(str, node, method_node)
13
13
  definitions = @then_processors.map do |then_processor|
14
14
  processed = then_processor.process(str, node, method_node)
15
15
  return if processed == :keep # rubocop:disable Lint/NonLocalExitFromIterator
@@ -22,11 +22,7 @@ module Leftovers
22
22
 
23
23
  return definitions.first if definitions.length <= 1
24
24
 
25
- ::Leftovers::DefinitionSet.new(
26
- definitions,
27
- location: node.loc.expression,
28
- method_node: method_node
29
- )
25
+ ::Leftovers::DefinitionSet.new(definitions)
30
26
  end
31
27
  end
32
28
  end
@@ -11,12 +11,14 @@ module Leftovers
11
11
  return unless str
12
12
  return if str.empty?
13
13
 
14
- return :keep if ::Leftovers.config.keep === node
14
+ str_node = Leftovers::DefinitionNode.new(str.to_sym, method_node.path)
15
+
16
+ return :keep if ::Leftovers.config.keep === str_node
15
17
 
16
18
  Leftovers::Definition.new(
17
- str.to_sym,
19
+ str_node.name,
18
20
  location: node.loc.expression,
19
- method_node: method_node
21
+ test: method_node.test_line? || ::Leftovers.config.test_only === str_node
20
22
  )
21
23
  end
22
24
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Leftovers
4
- VERSION = '0.4.0'
4
+ VERSION = '0.4.1'
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.4.0
4
+ version: 0.4.1
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-11-03 00:00:00.000000000 Z
11
+ date: 2020-11-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -313,6 +313,7 @@ files:
313
313
  - lib/leftovers/config_validator/error_processor.rb
314
314
  - lib/leftovers/config_validator/schema_hash.rb
315
315
  - lib/leftovers/definition.rb
316
+ - lib/leftovers/definition_node.rb
316
317
  - lib/leftovers/definition_set.rb
317
318
  - lib/leftovers/dynamic_processors.rb
318
319
  - lib/leftovers/dynamic_processors/call.rb
@@ -438,8 +439,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
438
439
  - !ruby/object:Gem::Version
439
440
  version: '0'
440
441
  requirements: []
441
- rubyforge_project:
442
- rubygems_version: 2.7.6
442
+ rubygems_version: 3.1.2
443
443
  signing_key:
444
444
  specification_version: 4
445
445
  summary: Find unused methods and classes/modules