rubocop-github 0.19.0 → 0.22.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.
- checksums.yaml +4 -4
- data/README.md +10 -5
- data/STYLEGUIDE.md +190 -4
- data/config/default.yml +72 -23
- data/config/default_pending.yml +116 -0
- data/config/rails.yml +15 -18
- data/config/rails_cops.yml +3 -15
- data/config/rails_pending.yml +102 -0
- data/lib/rubocop/cop/github/avoid_object_send_with_dynamic_method.rb +77 -0
- data/lib/rubocop/cop/github/rails_controller_render_literal.rb +1 -1
- data/lib/rubocop/cop/github/rails_view_render_shorthand.rb +8 -2
- data/lib/rubocop/cop/github/render_literal_helpers.rb +2 -1
- data/lib/rubocop-github-rails.rb +0 -2
- data/lib/rubocop-github.rb +1 -0
- data/lib/version.rb +3 -0
- metadata +19 -15
- data/guides/rails-render-inline.md +0 -27
- data/lib/rubocop/cop/github/rails_application_record.rb +0 -29
- data/lib/rubocop/cop/github/rails_render_inline.rb +0 -29
@@ -0,0 +1,77 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rubocop"
|
4
|
+
|
5
|
+
module RuboCop
|
6
|
+
module Cop
|
7
|
+
module GitHub
|
8
|
+
# Public: A Rubocop to discourage using methods like Object#send that allow you to dynamically call other
|
9
|
+
# methods on a Ruby object, when the method being called is itself completely dynamic. Instead, explicitly call
|
10
|
+
# methods by name.
|
11
|
+
#
|
12
|
+
# Examples:
|
13
|
+
#
|
14
|
+
# # bad
|
15
|
+
# foo.send(some_variable)
|
16
|
+
#
|
17
|
+
# # good
|
18
|
+
# case some_variable
|
19
|
+
# when "bar"
|
20
|
+
# foo.bar
|
21
|
+
# else
|
22
|
+
# foo.baz
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# # fine
|
26
|
+
# foo.send(:bar)
|
27
|
+
# foo.public_send("some_method")
|
28
|
+
# foo.__send__("some_#{variable}_method")
|
29
|
+
class AvoidObjectSendWithDynamicMethod < Base
|
30
|
+
MESSAGE_TEMPLATE = "Avoid using Object#%s with a dynamic method name."
|
31
|
+
SEND_METHODS = %i(send public_send __send__).freeze
|
32
|
+
CONSTANT_TYPES = %i(sym str const).freeze
|
33
|
+
|
34
|
+
def on_send(node)
|
35
|
+
return unless send_method?(node)
|
36
|
+
return if method_being_sent_is_constrained?(node)
|
37
|
+
add_offense(source_range_for_method_call(node), message: MESSAGE_TEMPLATE % node.method_name)
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def send_method?(node)
|
43
|
+
SEND_METHODS.include?(node.method_name)
|
44
|
+
end
|
45
|
+
|
46
|
+
def method_being_sent_is_constrained?(node)
|
47
|
+
method_name_being_sent_is_constant?(node) || method_name_being_sent_is_dynamic_string_with_constants?(node)
|
48
|
+
end
|
49
|
+
|
50
|
+
def method_name_being_sent_is_constant?(node)
|
51
|
+
method_being_sent = node.arguments.first
|
52
|
+
# e.g., `worker.send(:perform)` or `base.send("extend", Foo)`
|
53
|
+
CONSTANT_TYPES.include?(method_being_sent.type)
|
54
|
+
end
|
55
|
+
|
56
|
+
def method_name_being_sent_is_dynamic_string_with_constants?(node)
|
57
|
+
method_being_sent = node.arguments.first
|
58
|
+
return false unless method_being_sent.type == :dstr
|
59
|
+
|
60
|
+
# e.g., `foo.send("can_#{action}?")`
|
61
|
+
method_being_sent.child_nodes.any? { |child_node| CONSTANT_TYPES.include?(child_node.type) }
|
62
|
+
end
|
63
|
+
|
64
|
+
def source_range_for_method_call(node)
|
65
|
+
begin_pos =
|
66
|
+
if node.receiver # e.g., for `foo.send(:bar)`, `foo` is the receiver
|
67
|
+
node.receiver.source_range.end_pos
|
68
|
+
else # e.g., `send(:bar)`
|
69
|
+
node.source_range.begin_pos
|
70
|
+
end
|
71
|
+
end_pos = node.loc.selector.end_pos
|
72
|
+
Parser::Source::Range.new(processed_source.buffer, begin_pos, end_pos)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -9,7 +9,7 @@ module RuboCop
|
|
9
9
|
class RailsControllerRenderLiteral < Base
|
10
10
|
include RenderLiteralHelpers
|
11
11
|
|
12
|
-
MSG = "render must be used with a string literal or an instance of a Class"
|
12
|
+
MSG = "render must be used with a string literal or an instance of a Class, and use literals for locals keys"
|
13
13
|
|
14
14
|
def_node_matcher :ignore_key?, <<-PATTERN
|
15
15
|
(pair (sym {
|
@@ -6,6 +6,8 @@ module RuboCop
|
|
6
6
|
module Cop
|
7
7
|
module GitHub
|
8
8
|
class RailsViewRenderShorthand < Base
|
9
|
+
extend AutoCorrector
|
10
|
+
|
9
11
|
MSG = "Prefer `render` partial shorthand"
|
10
12
|
|
11
13
|
def_node_matcher :render_with_options?, <<-PATTERN
|
@@ -26,9 +28,13 @@ module RuboCop
|
|
26
28
|
locals_key = option_pairs.map { |pair| locals_key?(pair) }.compact.first
|
27
29
|
|
28
30
|
if option_pairs.length == 1 && partial_key
|
29
|
-
add_offense(node, message: "Use `render #{partial_key.source}` instead")
|
31
|
+
add_offense(node, message: "Use `render #{partial_key.source}` instead") do |corrector|
|
32
|
+
corrector.replace(node.source_range, "render #{partial_key.source}")
|
33
|
+
end
|
30
34
|
elsif option_pairs.length == 2 && partial_key && locals_key
|
31
|
-
add_offense(node, message: "Use `render #{partial_key.source}, #{locals_key.source}` instead")
|
35
|
+
add_offense(node, message: "Use `render #{partial_key.source}, #{locals_key.source}` instead") do |corrector|
|
36
|
+
corrector.replace(node.source_range, "render #{partial_key.source}, #{locals_key.source}")
|
37
|
+
end
|
32
38
|
end
|
33
39
|
end
|
34
40
|
end
|
@@ -41,7 +41,8 @@ module RuboCop
|
|
41
41
|
PATTERN
|
42
42
|
|
43
43
|
def hash_with_literal_keys?(hash)
|
44
|
-
hash.
|
44
|
+
hash.children.all? { |child| child.pair_type? } &&
|
45
|
+
hash.pairs.all? { |pair| literal?(pair.key) }
|
45
46
|
end
|
46
47
|
|
47
48
|
def render_view_component?(node)
|
data/lib/rubocop-github-rails.rb
CHANGED
@@ -6,12 +6,10 @@ require "rubocop/github/inject"
|
|
6
6
|
|
7
7
|
RuboCop::GitHub::Inject.rails_defaults!
|
8
8
|
|
9
|
-
require "rubocop/cop/github/rails_application_record"
|
10
9
|
require "rubocop/cop/github/rails_controller_render_action_symbol"
|
11
10
|
require "rubocop/cop/github/rails_controller_render_literal"
|
12
11
|
require "rubocop/cop/github/rails_controller_render_paths_exist"
|
13
12
|
require "rubocop/cop/github/rails_controller_render_shorthand"
|
14
|
-
require "rubocop/cop/github/rails_render_inline"
|
15
13
|
require "rubocop/cop/github/rails_render_object_collection"
|
16
14
|
require "rubocop/cop/github/rails_view_render_literal"
|
17
15
|
require "rubocop/cop/github/rails_view_render_paths_exist"
|
data/lib/rubocop-github.rb
CHANGED
data/lib/version.rb
ADDED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubocop-github
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.22.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- GitHub
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2025-02-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rubocop
|
@@ -16,42 +16,42 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 1.
|
19
|
+
version: '1.37'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 1.
|
26
|
+
version: '1.37'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rubocop-performance
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '1.15'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '1.15'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rubocop-rails
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '2.17'
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '2.17'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: actionview
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -94,7 +94,7 @@ dependencies:
|
|
94
94
|
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
|
-
description:
|
97
|
+
description: Code style checking for GitHub Ruby repositories
|
98
98
|
email: engineering@github.com
|
99
99
|
executables: []
|
100
100
|
extensions: []
|
@@ -105,21 +105,21 @@ files:
|
|
105
105
|
- STYLEGUIDE.md
|
106
106
|
- config/default.yml
|
107
107
|
- config/default_cops.yml
|
108
|
+
- config/default_pending.yml
|
108
109
|
- config/rails.yml
|
109
110
|
- config/rails_cops.yml
|
111
|
+
- config/rails_pending.yml
|
110
112
|
- guides/rails-controller-render-shorthand.md
|
111
|
-
- guides/rails-render-inline.md
|
112
113
|
- guides/rails-render-literal.md
|
113
114
|
- lib/rubocop-github-rails.rb
|
114
115
|
- lib/rubocop-github.rb
|
115
116
|
- lib/rubocop/cop/github.rb
|
117
|
+
- lib/rubocop/cop/github/avoid_object_send_with_dynamic_method.rb
|
116
118
|
- lib/rubocop/cop/github/insecure_hash_algorithm.rb
|
117
|
-
- lib/rubocop/cop/github/rails_application_record.rb
|
118
119
|
- lib/rubocop/cop/github/rails_controller_render_action_symbol.rb
|
119
120
|
- lib/rubocop/cop/github/rails_controller_render_literal.rb
|
120
121
|
- lib/rubocop/cop/github/rails_controller_render_paths_exist.rb
|
121
122
|
- lib/rubocop/cop/github/rails_controller_render_shorthand.rb
|
122
|
-
- lib/rubocop/cop/github/rails_render_inline.rb
|
123
123
|
- lib/rubocop/cop/github/rails_render_object_collection.rb
|
124
124
|
- lib/rubocop/cop/github/rails_view_render_literal.rb
|
125
125
|
- lib/rubocop/cop/github/rails_view_render_paths_exist.rb
|
@@ -127,10 +127,14 @@ files:
|
|
127
127
|
- lib/rubocop/cop/github/render_literal_helpers.rb
|
128
128
|
- lib/rubocop/github.rb
|
129
129
|
- lib/rubocop/github/inject.rb
|
130
|
+
- lib/version.rb
|
130
131
|
homepage: https://github.com/github/rubocop-github
|
131
132
|
licenses:
|
132
133
|
- MIT
|
133
|
-
metadata:
|
134
|
+
metadata:
|
135
|
+
source_code_uri: https://github.com/github/rubocop-github
|
136
|
+
documentation_uri: https://github.com/github/rubocop-github
|
137
|
+
bug_tracker_uri: https://github.com/github/rubocop-github/issues
|
134
138
|
post_install_message:
|
135
139
|
rdoc_options: []
|
136
140
|
require_paths:
|
@@ -139,14 +143,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
139
143
|
requirements:
|
140
144
|
- - ">="
|
141
145
|
- !ruby/object:Gem::Version
|
142
|
-
version:
|
146
|
+
version: 3.0.0
|
143
147
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
144
148
|
requirements:
|
145
149
|
- - ">="
|
146
150
|
- !ruby/object:Gem::Version
|
147
151
|
version: '0'
|
148
152
|
requirements: []
|
149
|
-
rubygems_version: 3.
|
153
|
+
rubygems_version: 3.4.6
|
150
154
|
signing_key:
|
151
155
|
specification_version: 4
|
152
156
|
summary: RuboCop GitHub
|
@@ -1,27 +0,0 @@
|
|
1
|
-
# GitHub/RailsRenderInline
|
2
|
-
|
3
|
-
tldr; Do not use `render inline:`.
|
4
|
-
|
5
|
-
## Rendering plain text
|
6
|
-
|
7
|
-
``` ruby
|
8
|
-
render inline: "Just plain text" # bad
|
9
|
-
```
|
10
|
-
|
11
|
-
The `inline:` option is often misused when plain text is being returned. Instead use `render plain: "Just plain text"`.
|
12
|
-
|
13
|
-
## Rendering a dynamic ERB string
|
14
|
-
|
15
|
-
String `#{}` interpolation is often misused with `render inline:` instead of using `<%= %>` interpolation. This will lead to a memory leak where an ERB method will be compiled and cached for each invocation of `render inline:`.
|
16
|
-
|
17
|
-
``` ruby
|
18
|
-
render inline: "Hello #{@name}" # bad
|
19
|
-
```
|
20
|
-
|
21
|
-
## Rendering static ERB strings
|
22
|
-
|
23
|
-
``` ruby
|
24
|
-
render inline: "Hello <%= @name %>" # bad
|
25
|
-
```
|
26
|
-
|
27
|
-
If you are passing a static ERB string to `render inline:`, this string is best moved to a `.erb` template under `app/views`. Template files are able to be precompiled at boot time.
|
@@ -1,29 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "rubocop"
|
4
|
-
|
5
|
-
module RuboCop
|
6
|
-
module Cop
|
7
|
-
module GitHub
|
8
|
-
class RailsApplicationRecord < Base
|
9
|
-
MSG = "Models should subclass from ApplicationRecord"
|
10
|
-
|
11
|
-
def_node_matcher :active_record_base_const?, <<-PATTERN
|
12
|
-
(const (const nil? :ActiveRecord) :Base)
|
13
|
-
PATTERN
|
14
|
-
|
15
|
-
def_node_matcher :application_record_const?, <<-PATTERN
|
16
|
-
(const nil? :ApplicationRecord)
|
17
|
-
PATTERN
|
18
|
-
|
19
|
-
def on_class(node)
|
20
|
-
klass, superclass, _ = *node
|
21
|
-
|
22
|
-
if active_record_base_const?(superclass) && !(application_record_const?(klass))
|
23
|
-
add_offense(superclass)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "rubocop"
|
4
|
-
|
5
|
-
module RuboCop
|
6
|
-
module Cop
|
7
|
-
module GitHub
|
8
|
-
class RailsRenderInline < Base
|
9
|
-
MSG = "Avoid `render inline:`"
|
10
|
-
|
11
|
-
def_node_matcher :render_with_options?, <<-PATTERN
|
12
|
-
(send nil? {:render :render_to_string} (hash $...))
|
13
|
-
PATTERN
|
14
|
-
|
15
|
-
def_node_matcher :inline_key?, <<-PATTERN
|
16
|
-
(pair (sym :inline) $_)
|
17
|
-
PATTERN
|
18
|
-
|
19
|
-
def on_send(node)
|
20
|
-
if option_pairs = render_with_options?(node)
|
21
|
-
if option_pairs.detect { |pair| inline_key?(pair) }
|
22
|
-
add_offense(node)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|