forked from rubocop/rubocop
/
deprecated_attribute_assignment.rb
92 lines (79 loc) · 2.53 KB
/
deprecated_attribute_assignment.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# frozen_string_literal: true
module RuboCop
module Cop
module Gemspec
# Checks that deprecated attribute attributes are not set in a gemspec file.
# Removing deprecated attributes allows the user to receive smaller packed gems.
#
# @example
#
# # bad
# Gem::Specification.new do |spec|
# spec.name = 'your_cool_gem_name'
# spec.test_files = Dir.glob('test/**/*')
# end
#
# # bad
# Gem::Specification.new do |spec|
# spec.name = 'your_cool_gem_name'
# spec.test_files += Dir.glob('test/**/*')
# end
#
# # good
# Gem::Specification.new do |spec|
# spec.name = 'your_cool_gem_name'
# end
#
class DeprecatedAttributeAssignment < Base
include RangeHelp
extend AutoCorrector
MSG = 'Do not set `%<attribute>s` in gemspec.'
# @!method gem_specification(node)
def_node_matcher :gem_specification, <<~PATTERN
(block
(send
(const
(const {cbase nil?} :Gem) :Specification) :new)
...)
PATTERN
def on_block(block_node)
return unless gem_specification(block_node)
block_parameter = block_node.arguments.first.source
assignment = block_node.descendants.detect do |node|
use_deprecated_attributes?(node, block_parameter)
end
return unless assignment
message = format_message_from
add_offense(assignment, message: message) do |corrector|
range = range_by_whole_lines(assignment.source_range, include_final_newline: true)
corrector.remove(range)
end
end
private
def node_and_method_name(node, attribute)
if node.op_asgn_type?
lhs, _op, _rhs = *node
[lhs, attribute]
else
[node, "#{attribute}=".to_sym]
end
end
def use_deprecated_attributes?(node, block_parameter)
%i[test_files date].each do |attribute|
node, method_name = node_and_method_name(node, attribute)
unless node.send_type? && node.receiver&.source == block_parameter &&
node.method?(method_name)
next
end
@attribute = attribute.to_s
return true
end
false
end
def format_message_from
format(MSG, attribute: @attribute)
end
end
end
end
end