leftovers 0.6.0 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +21 -3
- data/docs/Configuration.md +82 -18
- data/leftovers.gemspec +1 -1
- data/lib/config/actionmailer.yml +11 -11
- data/lib/config/activesupport.yml +1 -1
- data/lib/config/rails.yml +1 -1
- data/lib/config/railties.yml +11 -0
- data/lib/config/ruby.yml +72 -0
- data/lib/leftovers/ast/node.rb +16 -11
- data/lib/leftovers/config.rb +1 -24
- data/lib/leftovers/config_loader/argument_position_schema.rb +11 -0
- data/lib/leftovers/config_loader/argumentless_transform_schema.rb +21 -0
- data/lib/leftovers/config_loader/attribute.rb +30 -0
- data/lib/leftovers/config_loader/document_schema.rb +21 -0
- data/lib/leftovers/config_loader/dynamic_schema.rb +17 -0
- data/lib/leftovers/config_loader/has_argument_schema.rb +13 -0
- data/lib/leftovers/config_loader/has_value_schema.rb +18 -0
- data/lib/leftovers/config_loader/keep_test_only_schema.rb +13 -0
- data/lib/leftovers/config_loader/node.rb +106 -0
- data/lib/leftovers/config_loader/object_schema.rb +189 -0
- data/lib/leftovers/config_loader/privacy_processor_schema.rb +12 -0
- data/lib/leftovers/config_loader/privacy_schema.rb +15 -0
- data/lib/leftovers/config_loader/require_schema.rb +11 -0
- data/lib/leftovers/config_loader/rule_pattern_schema.rb +18 -0
- data/lib/leftovers/config_loader/scalar_argument_schema.rb +14 -0
- data/lib/leftovers/config_loader/scalar_value_schema.rb +14 -0
- data/lib/leftovers/config_loader/schema.rb +21 -0
- data/lib/leftovers/config_loader/string_enum_schema.rb +62 -0
- data/lib/leftovers/config_loader/string_pattern_schema.rb +14 -0
- data/lib/leftovers/config_loader/string_schema.rb +14 -0
- data/lib/leftovers/config_loader/string_value_processor_schema.rb +11 -0
- data/lib/leftovers/config_loader/suggester.rb +22 -0
- data/lib/leftovers/config_loader/transform_schema.rb +28 -0
- data/lib/leftovers/config_loader/true_schema.rb +18 -0
- data/lib/leftovers/config_loader/value_matcher_schema.rb +18 -0
- data/lib/leftovers/config_loader/value_or_array_schema.rb +64 -0
- data/lib/leftovers/config_loader/value_processor_schema.rb +14 -0
- data/lib/leftovers/config_loader/value_type_schema.rb +17 -0
- data/lib/leftovers/config_loader.rb +82 -0
- data/lib/leftovers/definition_node.rb +6 -17
- data/lib/leftovers/definition_node_set.rb +11 -0
- data/lib/leftovers/definition_to_add.rb +31 -0
- data/lib/leftovers/dynamic_processors/call.rb +4 -3
- data/lib/leftovers/dynamic_processors/call_definition.rb +14 -7
- data/lib/leftovers/dynamic_processors/definition.rb +8 -3
- data/lib/leftovers/dynamic_processors/set_default_privacy.rb +18 -0
- data/lib/leftovers/dynamic_processors/set_privacy.rb +23 -0
- data/lib/leftovers/dynamic_processors.rb +2 -0
- data/lib/leftovers/file.rb +5 -1
- data/lib/leftovers/file_collector.rb +44 -17
- data/lib/leftovers/matcher_builders/node.rb +4 -0
- data/lib/leftovers/matcher_builders/node_privacy.rb +13 -0
- data/lib/leftovers/matcher_builders/node_type.rb +4 -4
- data/lib/leftovers/matcher_builders/node_value.rb +1 -1
- data/lib/leftovers/matcher_builders/string_pattern.rb +14 -5
- data/lib/leftovers/matcher_builders.rb +1 -0
- data/lib/leftovers/matchers/node_privacy.rb +19 -0
- data/lib/leftovers/matchers.rb +1 -0
- data/lib/leftovers/merged_config.rb +18 -34
- data/lib/leftovers/processor_builders/add_prefix.rb +1 -1
- data/lib/leftovers/processor_builders/add_suffix.rb +1 -1
- data/lib/leftovers/processor_builders/dynamic.rb +50 -16
- data/lib/leftovers/processor_builders/transform.rb +2 -2
- data/lib/leftovers/processor_builders/transform_set.rb +8 -8
- data/lib/leftovers/value_processors/each_for_definition_set.rb +2 -5
- data/lib/leftovers/value_processors/each_positional_argument.rb +1 -1
- data/lib/leftovers/value_processors/return_definition_node.rb +14 -0
- data/lib/leftovers/value_processors/{return_string.rb → return_sym.rb} +1 -1
- data/lib/leftovers/value_processors.rb +2 -2
- data/lib/leftovers/version.rb +1 -1
- data/lib/leftovers.rb +23 -14
- metadata +54 -22
- data/lib/config/actioncable.yml +0 -4
- data/lib/leftovers/config_validator/error_processor.rb +0 -196
- data/lib/leftovers/config_validator/schema_hash.rb +0 -551
- data/lib/leftovers/config_validator.rb +0 -61
- data/lib/leftovers/value_processors/return_definition.rb +0 -22
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Leftovers
|
4
|
+
class ConfigLoader
|
5
|
+
class ValueTypeSchema < StringEnumSchema
|
6
|
+
value :String
|
7
|
+
value :Symbol
|
8
|
+
value :Integer
|
9
|
+
value :Float
|
10
|
+
value :Array
|
11
|
+
value :Hash
|
12
|
+
value :Proc
|
13
|
+
value :Method
|
14
|
+
value :Constant
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
require 'leftovers'
|
5
|
+
|
6
|
+
module Leftovers
|
7
|
+
class ConfigLoader
|
8
|
+
autoload(:ArgumentPositionSchema, "#{__dir__}/config_loader/argument_position_schema")
|
9
|
+
autoload(:ArgumentlessTransformSchema, "#{__dir__}/config_loader/argumentless_transform_schema")
|
10
|
+
autoload(:Attribute, "#{__dir__}/config_loader/attribute")
|
11
|
+
autoload(:DocumentSchema, "#{__dir__}/config_loader/document_schema")
|
12
|
+
autoload(:DynamicSchema, "#{__dir__}/config_loader/dynamic_schema")
|
13
|
+
autoload(:HasArgumentSchema, "#{__dir__}/config_loader/has_argument_schema")
|
14
|
+
autoload(:HasValueSchema, "#{__dir__}/config_loader/has_value_schema")
|
15
|
+
autoload(:KeepTestOnlySchema, "#{__dir__}/config_loader/keep_test_only_schema")
|
16
|
+
autoload(:Node, "#{__dir__}/config_loader/node")
|
17
|
+
autoload(:ObjectSchema, "#{__dir__}/config_loader/object_schema")
|
18
|
+
autoload(:PrivacyProcessorSchema, "#{__dir__}/config_loader/privacy_processor_schema")
|
19
|
+
autoload(:PrivacySchema, "#{__dir__}/config_loader/privacy_schema")
|
20
|
+
autoload(:RequireSchema, "#{__dir__}/config_loader/require_schema")
|
21
|
+
autoload(:RulePatternSchema, "#{__dir__}/config_loader/rule_pattern_schema")
|
22
|
+
autoload(:ScalarArgumentSchema, "#{__dir__}/config_loader/scalar_argument_schema")
|
23
|
+
autoload(:ScalarValueSchema, "#{__dir__}/config_loader/scalar_value_schema")
|
24
|
+
autoload(:Schema, "#{__dir__}/config_loader/schema")
|
25
|
+
autoload(:Suggester, "#{__dir__}/config_loader/suggester")
|
26
|
+
autoload(:StringEnumSchema, "#{__dir__}/config_loader/string_enum_schema")
|
27
|
+
autoload(:StringPatternSchema, "#{__dir__}/config_loader/string_pattern_schema")
|
28
|
+
autoload(:StringSchema, "#{__dir__}/config_loader/string_schema")
|
29
|
+
autoload(:StringValueProcessorSchema, "#{__dir__}/config_loader/string_value_processor_schema")
|
30
|
+
autoload(:TransformSchema, "#{__dir__}/config_loader/transform_schema")
|
31
|
+
autoload(:TrueSchema, "#{__dir__}/config_loader/true_schema")
|
32
|
+
autoload(:ValueMatcherSchema, "#{__dir__}/config_loader/value_matcher_schema")
|
33
|
+
autoload(:ValueOrArraySchema, "#{__dir__}/config_loader/value_or_array_schema")
|
34
|
+
autoload(:ValueProcessorSchema, "#{__dir__}/config_loader/value_processor_schema")
|
35
|
+
autoload(:ValueTypeSchema, "#{__dir__}/config_loader/value_type_schema")
|
36
|
+
|
37
|
+
def self.load(name, path: nil, content: nil)
|
38
|
+
new(name, path: path, content: content).load
|
39
|
+
end
|
40
|
+
|
41
|
+
attr_reader :name
|
42
|
+
|
43
|
+
def initialize(name, path: nil, content: nil)
|
44
|
+
@name = name
|
45
|
+
@path = path
|
46
|
+
@content = content
|
47
|
+
end
|
48
|
+
|
49
|
+
def load
|
50
|
+
document = ::Leftovers::ConfigLoader::Node.new(parse, file)
|
51
|
+
DocumentSchema.validate(document)
|
52
|
+
|
53
|
+
all_errors = document.all_errors
|
54
|
+
return DocumentSchema.to_ruby(document) if all_errors.empty?
|
55
|
+
|
56
|
+
Leftovers.error(all_errors.join("\n"))
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def path
|
62
|
+
@path ||= ::File.expand_path("../config/#{name}.yml", __dir__)
|
63
|
+
end
|
64
|
+
|
65
|
+
def file
|
66
|
+
@file ||= ::Leftovers::File.new(path)
|
67
|
+
end
|
68
|
+
|
69
|
+
def content
|
70
|
+
@content ||= file.exist? ? file.read : ''
|
71
|
+
end
|
72
|
+
|
73
|
+
def parse
|
74
|
+
parsed = Psych.parse(content)
|
75
|
+
parsed ||= Psych.parse('{}')
|
76
|
+
parsed.children.first
|
77
|
+
rescue ::Psych::SyntaxError => e
|
78
|
+
message = [e.problem, e.context].compact.join(' ')
|
79
|
+
Leftovers.error "Config SyntaxError: #{file.relative_path}:#{e.line}:#{e.column} #{message}"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -1,19 +1,15 @@
|
|
1
1
|
# frozen-string-literal: true
|
2
2
|
|
3
|
-
# To give to matchers before creating a Definition
|
4
|
-
|
5
3
|
module Leftovers
|
6
4
|
class DefinitionNode
|
7
|
-
attr_reader :
|
5
|
+
attr_reader :name, :loc, :node
|
8
6
|
|
9
|
-
def initialize(
|
7
|
+
def initialize(node, name:, location: node.loc.expression)
|
8
|
+
@node = node
|
10
9
|
@name = name
|
11
|
-
@
|
12
|
-
|
13
|
-
freeze
|
10
|
+
@loc = location
|
14
11
|
end
|
15
12
|
|
16
|
-
# these are the methods checked by things in lib/leftovers/matchers
|
17
13
|
def kwargs
|
18
14
|
nil
|
19
15
|
end
|
@@ -22,15 +18,8 @@ module Leftovers
|
|
22
18
|
nil
|
23
19
|
end
|
24
20
|
|
25
|
-
|
26
|
-
|
27
|
-
def scalar?
|
28
|
-
false
|
29
|
-
end
|
30
|
-
|
31
|
-
def type
|
32
|
-
:leftovers_definition
|
21
|
+
def path
|
22
|
+
node.path
|
33
23
|
end
|
34
|
-
# :nocov:
|
35
24
|
end
|
36
25
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
|
3
|
+
module Leftovers
|
4
|
+
class DefinitionToAdd
|
5
|
+
attr_reader :node, :name, :location
|
6
|
+
|
7
|
+
def initialize(node, name: node.name, location: node.loc.name)
|
8
|
+
@node = node
|
9
|
+
@name = name
|
10
|
+
@location = location
|
11
|
+
end
|
12
|
+
|
13
|
+
def privacy=(value)
|
14
|
+
@node.privacy = value
|
15
|
+
end
|
16
|
+
|
17
|
+
def keep?(file_collector)
|
18
|
+
@keep ||= file_collector.keep_line?(location.line) || ::Leftovers.config.keep === node
|
19
|
+
end
|
20
|
+
|
21
|
+
def test?(file_collector)
|
22
|
+
file_collector.test_line?(location.line) || ::Leftovers.config.test_only === node
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_definition(file_collector)
|
26
|
+
return if keep?(file_collector)
|
27
|
+
|
28
|
+
Leftovers::Definition.new(name, location: location, test: test?(file_collector))
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -11,10 +11,11 @@ module Leftovers
|
|
11
11
|
def process(node, file)
|
12
12
|
return unless @matcher === node
|
13
13
|
|
14
|
-
|
15
|
-
return unless call
|
14
|
+
calls = @processor.process(nil, node, node)
|
16
15
|
|
17
|
-
|
16
|
+
::Leftovers.each_or_self(calls) do |call|
|
17
|
+
file.calls << call
|
18
|
+
end
|
18
19
|
end
|
19
20
|
end
|
20
21
|
end
|
@@ -9,18 +9,25 @@ module Leftovers
|
|
9
9
|
@definition_processor = definition_processor
|
10
10
|
end
|
11
11
|
|
12
|
-
def process(node, file)
|
12
|
+
def process(node, file) # rubocop:disable Metrics/MethodLength
|
13
13
|
return unless @matcher === node
|
14
14
|
|
15
|
-
|
16
|
-
(file.calls << call) if call
|
15
|
+
calls = @call_processor.process(nil, node, node)
|
17
16
|
|
18
|
-
|
17
|
+
::Leftovers.each_or_self(calls) do |call|
|
18
|
+
file.calls << call
|
19
|
+
end
|
19
20
|
|
20
|
-
|
21
|
-
return unless definition
|
21
|
+
return if node.keep_line?
|
22
22
|
|
23
|
-
|
23
|
+
definitions = @definition_processor.process(nil, node, node)
|
24
|
+
::Leftovers.each_or_self(definitions) do |definition|
|
25
|
+
if definition.is_a?(DefinitionNodeSet)
|
26
|
+
file.add_definition_set(definition)
|
27
|
+
else
|
28
|
+
file.add_definition(definition, loc: definition.loc)
|
29
|
+
end
|
30
|
+
end
|
24
31
|
end
|
25
32
|
end
|
26
33
|
end
|
@@ -12,10 +12,15 @@ module Leftovers
|
|
12
12
|
return if node.keep_line?
|
13
13
|
return unless @matcher === node
|
14
14
|
|
15
|
-
|
16
|
-
return unless definition
|
15
|
+
definitions = @processor.process(nil, node, node)
|
17
16
|
|
18
|
-
|
17
|
+
::Leftovers.each_or_self(definitions) do |definition|
|
18
|
+
if definition.is_a?(DefinitionNodeSet)
|
19
|
+
file.add_definition_set(definition)
|
20
|
+
else
|
21
|
+
file.add_definition(definition, loc: definition.loc)
|
22
|
+
end
|
23
|
+
end
|
19
24
|
end
|
20
25
|
end
|
21
26
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
|
3
|
+
module Leftovers
|
4
|
+
module DynamicProcessors
|
5
|
+
class SetDefaultPrivacy
|
6
|
+
def initialize(matcher, to)
|
7
|
+
@matcher = matcher
|
8
|
+
@to = to
|
9
|
+
end
|
10
|
+
|
11
|
+
def process(node, file)
|
12
|
+
return unless @matcher === node
|
13
|
+
|
14
|
+
file.default_method_privacy = @to
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
|
3
|
+
module Leftovers
|
4
|
+
module DynamicProcessors
|
5
|
+
class SetPrivacy
|
6
|
+
def initialize(matcher, processor, to)
|
7
|
+
@matcher = matcher
|
8
|
+
@processor = processor
|
9
|
+
@to = to
|
10
|
+
end
|
11
|
+
|
12
|
+
def process(node, file)
|
13
|
+
return unless @matcher === node
|
14
|
+
|
15
|
+
set_privacy = @processor.process(nil, node, node)
|
16
|
+
|
17
|
+
::Leftovers.each_or_self(set_privacy) do |name|
|
18
|
+
file.set_privacy(name, @to)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -7,5 +7,7 @@ module Leftovers
|
|
7
7
|
autoload(:Definition, "#{__dir__}/dynamic_processors/definition")
|
8
8
|
autoload(:Each, "#{__dir__}/dynamic_processors/each")
|
9
9
|
autoload(:Null, "#{__dir__}/dynamic_processors/null")
|
10
|
+
autoload(:SetDefaultPrivacy, "#{__dir__}/dynamic_processors/set_default_privacy")
|
11
|
+
autoload(:SetPrivacy, "#{__dir__}/dynamic_processors/set_privacy")
|
10
12
|
end
|
11
13
|
end
|
data/lib/leftovers/file.rb
CHANGED
@@ -5,7 +5,11 @@ require 'pathname'
|
|
5
5
|
module Leftovers
|
6
6
|
class File < Pathname
|
7
7
|
def relative_path
|
8
|
-
@relative_path ||=
|
8
|
+
@relative_path ||= begin
|
9
|
+
relative_path_from(Leftovers.pwd)
|
10
|
+
rescue ArgumentError
|
11
|
+
self
|
12
|
+
end
|
9
13
|
end
|
10
14
|
|
11
15
|
def test?
|
@@ -5,16 +5,19 @@ require 'parser'
|
|
5
5
|
|
6
6
|
module Leftovers
|
7
7
|
class FileCollector < ::Parser::AST::Processor # rubocop:disable Metrics/ClassLength
|
8
|
-
attr_reader :calls
|
8
|
+
attr_reader :calls
|
9
|
+
attr_accessor :default_method_privacy
|
9
10
|
|
10
11
|
def initialize(ruby, file) # rubocop:disable Lint/MissingSuper
|
11
12
|
@calls = []
|
12
|
-
@
|
13
|
+
@definitions_to_add = {}
|
13
14
|
@allow_lines = Set.new.compare_by_identity
|
14
15
|
@test_lines = Set.new.compare_by_identity
|
15
16
|
@dynamic_lines = {}
|
16
17
|
@ruby = ruby
|
17
18
|
@file = file
|
19
|
+
@default_method_privacy = :public
|
20
|
+
@definition_sets_to_add = []
|
18
21
|
end
|
19
22
|
|
20
23
|
def filename
|
@@ -38,7 +41,6 @@ module Leftovers
|
|
38
41
|
definitions.flatten!
|
39
42
|
definitions.compact!
|
40
43
|
definitions.uniq!
|
41
|
-
definitions.reject! { |v| v == :keep }
|
42
44
|
end
|
43
45
|
|
44
46
|
def collect
|
@@ -76,6 +78,12 @@ module Leftovers
|
|
76
78
|
|
77
79
|
# grab method definitions
|
78
80
|
def on_def(node)
|
81
|
+
node.privacy = default_method_privacy
|
82
|
+
add_definition(node)
|
83
|
+
super
|
84
|
+
end
|
85
|
+
|
86
|
+
def on_defs(node)
|
79
87
|
add_definition(node)
|
80
88
|
super
|
81
89
|
end
|
@@ -184,24 +192,41 @@ module Leftovers
|
|
184
192
|
add_call(original_method.children.first)
|
185
193
|
end
|
186
194
|
|
187
|
-
|
195
|
+
def add_definition(node, name: node.name, loc: node.loc.name)
|
196
|
+
@definitions_to_add[name] =
|
197
|
+
::Leftovers::DefinitionToAdd.new(node, name: name, location: loc)
|
198
|
+
end
|
188
199
|
|
189
|
-
def
|
190
|
-
@
|
191
|
-
|
200
|
+
def add_definition_set(definition_node_set)
|
201
|
+
@definition_sets_to_add << definition_node_set.definitions.map do |definition_node|
|
202
|
+
::Leftovers::DefinitionToAdd.new(definition_node, location: definition_node.loc)
|
203
|
+
end
|
192
204
|
end
|
193
205
|
|
194
|
-
def
|
195
|
-
|
206
|
+
def set_privacy(name, to)
|
207
|
+
@definitions_to_add[name]&.privacy = to
|
196
208
|
end
|
197
209
|
|
198
|
-
def
|
199
|
-
|
200
|
-
|
210
|
+
def definitions
|
211
|
+
@definitions ||= @definitions_to_add.each_value.map { |d| d.to_definition(self) }.compact +
|
212
|
+
@definition_sets_to_add.map do |definition_set|
|
213
|
+
next nil if definition_set.any? { |d| d.keep?(self) }
|
201
214
|
|
202
|
-
|
215
|
+
::Leftovers::DefinitionSet.new(definition_set.map { |d| d.to_definition(self) })
|
216
|
+
end.compact
|
203
217
|
end
|
204
218
|
|
219
|
+
def test_line?(line)
|
220
|
+
@file.test? ||
|
221
|
+
@test_lines.include?(line)
|
222
|
+
end
|
223
|
+
|
224
|
+
def keep_line?(line)
|
225
|
+
@allow_lines.include?(line)
|
226
|
+
end
|
227
|
+
|
228
|
+
private
|
229
|
+
|
205
230
|
def add_call(name)
|
206
231
|
calls << name
|
207
232
|
end
|
@@ -232,11 +257,14 @@ module Leftovers
|
|
232
257
|
|
233
258
|
def collect_op_asgn(node)
|
234
259
|
node = node.children.first
|
235
|
-
# :nocov: # don't need else, it's exhaustive for callers
|
236
260
|
case node.type
|
237
|
-
# :nocov:
|
238
261
|
when :send then collect_send_op_asgn(node)
|
239
262
|
when :ivasgn, :gvasgn, :cvasgn then collect_var_op_asgn(node)
|
263
|
+
when :lvasgn then nil # we don't care about lvasgn
|
264
|
+
# :nocov:
|
265
|
+
else
|
266
|
+
raise "Unrecognized op_asgn node type #{node.type}"
|
267
|
+
# :nocov:
|
240
268
|
end
|
241
269
|
end
|
242
270
|
|
@@ -256,9 +284,8 @@ module Leftovers
|
|
256
284
|
)
|
257
285
|
end
|
258
286
|
|
259
|
-
def collect_dynamic(node)
|
287
|
+
def collect_dynamic(node)
|
260
288
|
node.keep_line = @allow_lines.include?(node.loc.line)
|
261
|
-
node.test_line = test_line?(node.loc) unless node.keep_line?
|
262
289
|
|
263
290
|
Leftovers.config.dynamic.process(node, self)
|
264
291
|
rescue StandardError => e
|
@@ -23,6 +23,8 @@ module Leftovers
|
|
23
23
|
paths: nil,
|
24
24
|
has_arguments: nil,
|
25
25
|
has_receiver: nil,
|
26
|
+
type: nil,
|
27
|
+
privacy: nil,
|
26
28
|
unless_arg: nil
|
27
29
|
)
|
28
30
|
::Leftovers::MatcherBuilders::And.build([
|
@@ -34,6 +36,8 @@ module Leftovers
|
|
34
36
|
::Leftovers::MatcherBuilders::NodePath.build(paths),
|
35
37
|
::Leftovers::MatcherBuilders::NodeHasArgument.build(has_arguments),
|
36
38
|
::Leftovers::MatcherBuilders::NodeHasReceiver.build(has_receiver),
|
39
|
+
::Leftovers::MatcherBuilders::NodePrivacy.build(privacy),
|
40
|
+
::Leftovers::MatcherBuilders::NodeType.build(type),
|
37
41
|
::Leftovers::MatcherBuilders::Unless.build(
|
38
42
|
(::Leftovers::MatcherBuilders::Node.build(unless_arg) if unless_arg)
|
39
43
|
)
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
|
3
|
+
module Leftovers
|
4
|
+
module MatcherBuilders
|
5
|
+
module NodePrivacy
|
6
|
+
def self.build(privacy_settings)
|
7
|
+
::Leftovers::MatcherBuilders::Or.each_or_self(privacy_settings) do |privacy|
|
8
|
+
::Leftovers::Matchers::NodePrivacy.new(privacy)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -14,12 +14,12 @@ module Leftovers
|
|
14
14
|
when 'Float' then ::Leftovers::Matchers::NodeType.new(:float)
|
15
15
|
when 'Array' then ::Leftovers::Matchers::NodeType.new(:array)
|
16
16
|
when 'Hash' then ::Leftovers::Matchers::NodeType.new(:hash)
|
17
|
-
|
18
17
|
when 'Proc' then ::Leftovers::Matchers::Predicate.new(:proc?)
|
19
|
-
|
20
|
-
|
18
|
+
when 'Method' then ::Leftovers::Matchers::NodeType.new(Set[:send, :csend, :def, :defs])
|
19
|
+
when 'Constant'
|
20
|
+
::Leftovers::Matchers::NodeType.new(Set[:const, :class, :module, :casgn])
|
21
21
|
# :nocov:
|
22
|
-
else raise
|
22
|
+
else raise "Unknown type #{type}"
|
23
23
|
# :nocov:
|
24
24
|
end
|
25
25
|
end
|
@@ -7,7 +7,7 @@ module Leftovers
|
|
7
7
|
def build(pattern) # rubocop:disable Metrics/MethodLength
|
8
8
|
::Leftovers::MatcherBuilders::Or.each_or_self(pattern) do |pat|
|
9
9
|
case pat
|
10
|
-
when ::Integer, true, false, nil
|
10
|
+
when ::Integer, ::Float, true, false, nil
|
11
11
|
::Leftovers::Matchers::NodeScalarValue.new(pat)
|
12
12
|
when ::String
|
13
13
|
::Leftovers::MatcherBuilders::NodeName.build(pat)
|
@@ -3,15 +3,24 @@
|
|
3
3
|
module Leftovers
|
4
4
|
module MatcherBuilders
|
5
5
|
module StringPattern
|
6
|
-
def self.build(match: nil, has_prefix: nil, has_suffix: nil)
|
7
|
-
if
|
6
|
+
def self.build(match: nil, has_prefix: nil, has_suffix: nil) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
7
|
+
has_prefix = ::Regexp.escape(has_prefix) if has_prefix
|
8
|
+
has_suffix = ::Regexp.escape(has_suffix) if has_suffix
|
9
|
+
|
10
|
+
if match && has_prefix && has_suffix
|
11
|
+
/\A(?=#{match}\z)(?=#{has_prefix}).*#{has_suffix}\z/
|
12
|
+
elsif match && has_prefix
|
13
|
+
/\A(?=#{match}\z)#{has_prefix}/
|
14
|
+
elsif match && has_suffix
|
15
|
+
/\A(?=#{match}\z).*#{has_suffix}\z/
|
16
|
+
elsif match
|
8
17
|
/\A#{match}\z/
|
9
18
|
elsif has_prefix && has_suffix
|
10
|
-
/\A
|
19
|
+
/\A(?=#{has_prefix}).*#{has_suffix}\z/
|
11
20
|
elsif has_prefix
|
12
|
-
/\A#{
|
21
|
+
/\A#{has_prefix}/
|
13
22
|
elsif has_suffix
|
14
|
-
/#{
|
23
|
+
/#{has_suffix}\z/
|
15
24
|
end
|
16
25
|
end
|
17
26
|
end
|
@@ -15,6 +15,7 @@ module Leftovers
|
|
15
15
|
autoload(:NodePairName, "#{__dir__}/matcher_builders/node_pair_name")
|
16
16
|
autoload(:NodePairValue, "#{__dir__}/matcher_builders/node_pair_value")
|
17
17
|
autoload(:NodePath, "#{__dir__}/matcher_builders/node_path")
|
18
|
+
autoload(:NodePrivacy, "#{__dir__}/matcher_builders/node_privacy")
|
18
19
|
autoload(:NodeType, "#{__dir__}/matcher_builders/node_type")
|
19
20
|
autoload(:NodeValue, "#{__dir__}/matcher_builders/node_value")
|
20
21
|
autoload(:Or, "#{__dir__}/matcher_builders/or")
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Leftovers
|
4
|
+
module Matchers
|
5
|
+
class NodePrivacy
|
6
|
+
def initialize(privacy_matcher)
|
7
|
+
@privacy_matcher = privacy_matcher
|
8
|
+
|
9
|
+
freeze
|
10
|
+
end
|
11
|
+
|
12
|
+
def ===(node)
|
13
|
+
@privacy_matcher === node.privacy
|
14
|
+
end
|
15
|
+
|
16
|
+
freeze
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/leftovers/matchers.rb
CHANGED
@@ -19,6 +19,7 @@ module Leftovers
|
|
19
19
|
autoload(:NodeName, "#{__dir__}/matchers/node_name")
|
20
20
|
autoload(:NodePairValue, "#{__dir__}/matchers/node_pair_value")
|
21
21
|
autoload(:NodePath, "#{__dir__}/matchers/node_path")
|
22
|
+
autoload(:NodePrivacy, "#{__dir__}/matchers/node_privacy")
|
22
23
|
autoload(:NodeScalarValue, "#{__dir__}/matchers/node_scalar_value")
|
23
24
|
autoload(:NodeType, "#{__dir__}/matchers/node_type")
|
24
25
|
autoload(:Not, "#{__dir__}/matchers/not")
|
@@ -4,7 +4,7 @@ require 'set'
|
|
4
4
|
require 'fast_ignore'
|
5
5
|
|
6
6
|
module Leftovers
|
7
|
-
class MergedConfig
|
7
|
+
class MergedConfig
|
8
8
|
def initialize(load_defaults: false)
|
9
9
|
@configs = []
|
10
10
|
@loaded_configs = Set.new
|
@@ -24,9 +24,7 @@ module Leftovers
|
|
24
24
|
@configs << config
|
25
25
|
@loaded_configs << config.name
|
26
26
|
config.gems.each { |gem| self << gem }
|
27
|
-
config
|
28
|
-
Leftovers.try_require(req, message: "cannot require '#{req}' from #{config.name}.yml")
|
29
|
-
end
|
27
|
+
require_requires(config)
|
30
28
|
end
|
31
29
|
|
32
30
|
def project_config
|
@@ -66,51 +64,27 @@ module Leftovers
|
|
66
64
|
end
|
67
65
|
|
68
66
|
def test_paths
|
69
|
-
@test_paths ||=
|
70
|
-
include_rules: @configs.flat_map(&:test_paths),
|
71
|
-
gitignore: false,
|
72
|
-
root: Leftovers.pwd
|
73
|
-
)
|
67
|
+
@test_paths ||= Leftovers::MatcherBuilders::Path.build(@configs.flat_map(&:test_paths))
|
74
68
|
end
|
75
69
|
|
76
70
|
def haml_paths
|
77
|
-
@haml_paths ||=
|
78
|
-
include_rules: @configs.flat_map(&:haml_paths),
|
79
|
-
gitignore: false,
|
80
|
-
root: Leftovers.pwd
|
81
|
-
)
|
71
|
+
@haml_paths ||= Leftovers::MatcherBuilders::Path.build(@configs.flat_map(&:haml_paths))
|
82
72
|
end
|
83
73
|
|
84
74
|
def slim_paths
|
85
|
-
@slim_paths ||=
|
86
|
-
include_rules: @configs.flat_map(&:slim_paths),
|
87
|
-
gitignore: false,
|
88
|
-
root: Leftovers.pwd
|
89
|
-
)
|
75
|
+
@slim_paths ||= Leftovers::MatcherBuilders::Path.build(@configs.flat_map(&:slim_paths))
|
90
76
|
end
|
91
77
|
|
92
78
|
def yaml_paths
|
93
|
-
@yaml_paths ||=
|
94
|
-
include_rules: @configs.flat_map(&:yaml_paths),
|
95
|
-
gitignore: false,
|
96
|
-
root: Leftovers.pwd
|
97
|
-
)
|
79
|
+
@yaml_paths ||= Leftovers::MatcherBuilders::Path.build(@configs.flat_map(&:yaml_paths))
|
98
80
|
end
|
99
81
|
|
100
82
|
def json_paths
|
101
|
-
@json_paths ||=
|
102
|
-
include_rules: @configs.flat_map(&:json_paths),
|
103
|
-
gitignore: false,
|
104
|
-
root: Leftovers.pwd
|
105
|
-
)
|
83
|
+
@json_paths ||= Leftovers::MatcherBuilders::Path.build(@configs.flat_map(&:json_paths))
|
106
84
|
end
|
107
85
|
|
108
86
|
def erb_paths
|
109
|
-
@erb_paths ||=
|
110
|
-
include_rules: @configs.flat_map(&:erb_paths),
|
111
|
-
gitignore: false,
|
112
|
-
root: Leftovers.pwd
|
113
|
-
)
|
87
|
+
@erb_paths ||= Leftovers::MatcherBuilders::Path.build(@configs.flat_map(&:erb_paths))
|
114
88
|
end
|
115
89
|
|
116
90
|
def dynamic
|
@@ -127,6 +101,16 @@ module Leftovers
|
|
127
101
|
|
128
102
|
private
|
129
103
|
|
104
|
+
def require_requires(config)
|
105
|
+
config.requires.each do |req|
|
106
|
+
if req.is_a?(Hash) && req[:quiet]
|
107
|
+
Leftovers.try_require(req[:quiet])
|
108
|
+
else
|
109
|
+
Leftovers.try_require(req, message: "cannot require '#{req}' from #{config.name}.yml")
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
130
114
|
def load_bundled_gem_config
|
131
115
|
return unless Leftovers.try_require('bundler')
|
132
116
|
|