rubocop-github 0.15.0 → 0.17.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/STYLEGUIDE.md +41 -26
- data/config/_default_shared.yml +4 -1
- data/lib/rubocop/cop/github/insecure_hash_algorithm.rb +139 -0
- data/lib/rubocop/cop/github/rails_controller_render_action_symbol.rb +2 -2
- data/lib/rubocop/cop/github/rails_controller_render_literal.rb +32 -25
- data/lib/rubocop/cop/github/rails_controller_render_paths_exist.rb +3 -3
- data/lib/rubocop/cop/github/rails_controller_render_shorthand.rb +1 -1
- data/lib/rubocop/cop/github/rails_render_inline.rb +1 -1
- data/lib/rubocop/cop/github/rails_render_object_collection.rb +1 -1
- data/lib/rubocop/cop/github/rails_view_render_literal.rb +26 -25
- data/lib/rubocop/cop/github/rails_view_render_paths_exist.rb +3 -3
- data/lib/rubocop/cop/github/rails_view_render_shorthand.rb +1 -1
- data/lib/rubocop/cop/github/render_literal_helpers.rb +55 -0
- data/lib/rubocop/cop/github.rb +1 -0
- metadata +31 -29
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0fd87ba9b81dbf0489ef9f8bdddfdc7ad832c7735e4376851165a03369a4493d
|
4
|
+
data.tar.gz: 294732c21b2ac89bde8bc654854d659293b7347ca478013e2eeeda8be3b92c4d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 75eca6f6d9a4c688a24f57f6b282d8a7515e7408db7c403ae0c3acdcd677d9cbb6acaa0713c55f8544baed002a077a1bcb3f2a4efd24d9118b720b7175d84a2c
|
7
|
+
data.tar.gz: 4770a141ce649d7bb034a9071db481a52858461672804e63ba62ea928072e0094177630d747a40b50ec017dafb323b5e6f4d4249d2e4ab543a20ebd5c53cfb14
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# RuboCop GitHub
|
1
|
+
# RuboCop GitHub ![CI](https://github.com/github/rubocop-github/workflows/CI/badge.svg?event=push)
|
2
2
|
|
3
3
|
This repository provides recommended RuboCop configuration and additional Cops for use on GitHub open source and internal Ruby projects.
|
4
4
|
|
data/STYLEGUIDE.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
* Use soft-tabs with a two space indent.
|
4
4
|
|
5
|
-
* Keep each line of code to a readable length. Unless you have a reason to, keep lines to
|
5
|
+
* Keep each line of code to a readable length. Unless you have a reason to, keep lines to a maximum of 118 characters. Why 118? That's the width at which the pull request diff UI needs horizontal scrolling (making pull requests harder to review).
|
6
6
|
|
7
7
|
* Never leave trailing whitespace.
|
8
8
|
|
@@ -31,9 +31,34 @@ some(arg).other
|
|
31
31
|
!array.include?(element)
|
32
32
|
```
|
33
33
|
|
34
|
-
* Indent `when`
|
34
|
+
* Indent `when` with the start of the `case` expression.
|
35
35
|
|
36
36
|
``` ruby
|
37
|
+
# bad
|
38
|
+
message = case
|
39
|
+
when song.name == "Misty"
|
40
|
+
"Not again!"
|
41
|
+
when song.duration > 120
|
42
|
+
"Too long!"
|
43
|
+
when Time.now.hour > 21
|
44
|
+
"It's too late"
|
45
|
+
else
|
46
|
+
song.to_s
|
47
|
+
end
|
48
|
+
|
49
|
+
# good
|
50
|
+
message = case
|
51
|
+
when song.name == "Misty"
|
52
|
+
"Not again!"
|
53
|
+
when song.duration > 120
|
54
|
+
"Too long!"
|
55
|
+
when Time.now.hour > 21
|
56
|
+
"It's too late"
|
57
|
+
else
|
58
|
+
song.to_s
|
59
|
+
end
|
60
|
+
|
61
|
+
# good
|
37
62
|
case
|
38
63
|
when song.name == "Misty"
|
39
64
|
puts "Not again!"
|
@@ -44,15 +69,6 @@ when Time.now.hour > 21
|
|
44
69
|
else
|
45
70
|
song.play
|
46
71
|
end
|
47
|
-
|
48
|
-
kind = case year
|
49
|
-
when 1850..1889 then "Blues"
|
50
|
-
when 1890..1909 then "Ragtime"
|
51
|
-
when 1910..1929 then "New Orleans Jazz"
|
52
|
-
when 1930..1939 then "Swing"
|
53
|
-
when 1940..1950 then "Bebop"
|
54
|
-
else "Jazz"
|
55
|
-
end
|
56
72
|
```
|
57
73
|
|
58
74
|
* Use empty lines between `def`s and to break up a method into logical
|
@@ -292,44 +308,43 @@ end
|
|
292
308
|
Use the Ruby 1.9 syntax for hash literals when all the keys are symbols:
|
293
309
|
|
294
310
|
``` ruby
|
295
|
-
# good
|
296
|
-
user = {
|
297
|
-
login: "defunkt",
|
298
|
-
name: "Chris Wanstrath"
|
299
|
-
}
|
300
|
-
|
301
311
|
# bad
|
302
312
|
user = {
|
303
313
|
:login => "defunkt",
|
304
314
|
:name => "Chris Wanstrath"
|
305
315
|
}
|
306
316
|
|
317
|
+
# good
|
318
|
+
user = {
|
319
|
+
login: "defunkt",
|
320
|
+
name: "Chris Wanstrath"
|
321
|
+
}
|
307
322
|
```
|
308
323
|
|
309
324
|
Use the 1.9 syntax when calling a method with Hash options arguments or named arguments:
|
310
325
|
|
311
326
|
``` ruby
|
312
|
-
# good
|
313
|
-
user = User.create(login: "jane")
|
314
|
-
link_to("Account", controller: "users", action: "show", id: user)
|
315
|
-
|
316
327
|
# bad
|
317
328
|
user = User.create(:login => "jane")
|
318
329
|
link_to("Account", :controller => "users", :action => "show", :id => user)
|
330
|
+
|
331
|
+
# good
|
332
|
+
user = User.create(login: "jane")
|
333
|
+
link_to("Account", controller: "users", action: "show", id: user)
|
319
334
|
```
|
320
335
|
|
321
336
|
If you have a hash with mixed key types, use the legacy hashrocket style to avoid mixing styles within the same hash:
|
322
337
|
|
323
338
|
``` ruby
|
324
|
-
#
|
339
|
+
# bad
|
325
340
|
hsh = {
|
326
|
-
:
|
341
|
+
user_id: 55,
|
327
342
|
"followers-count" => 1000
|
328
343
|
}
|
329
344
|
|
330
|
-
#
|
345
|
+
# good
|
331
346
|
hsh = {
|
332
|
-
user_id
|
347
|
+
:user_id => 55,
|
333
348
|
"followers-count" => 1000
|
334
349
|
}
|
335
350
|
```
|
@@ -355,7 +370,7 @@ def remove_member(user, skip_membership_check: false)
|
|
355
370
|
end
|
356
371
|
|
357
372
|
# Elsewhere, now with more clarity:
|
358
|
-
remove_member
|
373
|
+
remove_member(user, skip_membership_check: true)
|
359
374
|
```
|
360
375
|
|
361
376
|
## Naming
|
data/config/_default_shared.yml
CHANGED
@@ -10,6 +10,9 @@ Bundler/DuplicatedGem:
|
|
10
10
|
Bundler/OrderedGems:
|
11
11
|
Enabled: true
|
12
12
|
|
13
|
+
GitHub/InsecureHashAlgorithm:
|
14
|
+
Enabled: true
|
15
|
+
|
13
16
|
Layout/BlockAlignment:
|
14
17
|
Enabled: true
|
15
18
|
|
@@ -163,7 +166,7 @@ Lint/RedundantSplatExpansion:
|
|
163
166
|
Lint/UnreachableCode:
|
164
167
|
Enabled: true
|
165
168
|
|
166
|
-
Lint/
|
169
|
+
Lint/BinaryOperatorWithIdenticalOperands:
|
167
170
|
Enabled: true
|
168
171
|
|
169
172
|
Lint/UselessSetterCall:
|
@@ -0,0 +1,139 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rubocop"
|
4
|
+
|
5
|
+
module RuboCop
|
6
|
+
module Cop
|
7
|
+
module GitHub
|
8
|
+
class InsecureHashAlgorithm < Cop
|
9
|
+
MSG = "This hash function is not allowed"
|
10
|
+
UUID_V3_MSG = "uuid_v3 uses MD5, which is not allowed"
|
11
|
+
UUID_V5_MSG = "uuid_v5 uses SHA1, which is not allowed"
|
12
|
+
|
13
|
+
# Matches constants like these:
|
14
|
+
# Digest::MD5
|
15
|
+
# OpenSSL::Digest::MD5
|
16
|
+
def_node_matcher :insecure_const?, <<-PATTERN
|
17
|
+
(const (const _ :Digest) #insecure_algorithm?)
|
18
|
+
PATTERN
|
19
|
+
|
20
|
+
# Matches calls like these:
|
21
|
+
# Digest.new('md5')
|
22
|
+
# Digest.hexdigest('md5', 'str')
|
23
|
+
# OpenSSL::Digest.new('md5')
|
24
|
+
# OpenSSL::Digest.hexdigest('md5', 'str')
|
25
|
+
# OpenSSL::Digest::Digest.new('md5')
|
26
|
+
# OpenSSL::Digest::Digest.hexdigest('md5', 'str')
|
27
|
+
# OpenSSL::Digest::Digest.new(:MD5)
|
28
|
+
# OpenSSL::Digest::Digest.hexdigest(:MD5, 'str')
|
29
|
+
def_node_matcher :insecure_digest?, <<-PATTERN
|
30
|
+
(send
|
31
|
+
(const _ {:Digest :HMAC})
|
32
|
+
#not_just_encoding?
|
33
|
+
#insecure_algorithm?
|
34
|
+
...)
|
35
|
+
PATTERN
|
36
|
+
|
37
|
+
# Matches calls like "Digest(:MD5)".
|
38
|
+
def_node_matcher :insecure_hash_lookup?, <<-PATTERN
|
39
|
+
(send _ :Digest #insecure_algorithm?)
|
40
|
+
PATTERN
|
41
|
+
|
42
|
+
# Matches calls like "OpenSSL::HMAC.new(secret, hash)"
|
43
|
+
def_node_matcher :openssl_hmac_new?, <<-PATTERN
|
44
|
+
(send (const (const _ :OpenSSL) :HMAC) :new ...)
|
45
|
+
PATTERN
|
46
|
+
|
47
|
+
# Matches calls like "OpenSSL::HMAC.new(secret, 'sha1')"
|
48
|
+
def_node_matcher :openssl_hmac_new_insecure?, <<-PATTERN
|
49
|
+
(send (const (const _ :OpenSSL) :HMAC) :new _ #insecure_algorithm?)
|
50
|
+
PATTERN
|
51
|
+
|
52
|
+
# Matches Rails's Digest::UUID.
|
53
|
+
def_node_matcher :digest_uuid?, <<-PATTERN
|
54
|
+
(const (const _ :Digest) :UUID)
|
55
|
+
PATTERN
|
56
|
+
|
57
|
+
def_node_matcher :uuid_v3?, <<-PATTERN
|
58
|
+
(send (const _ :UUID) :uuid_v3 ...)
|
59
|
+
PATTERN
|
60
|
+
|
61
|
+
def_node_matcher :uuid_v5?, <<-PATTERN
|
62
|
+
(send (const _ :UUID) :uuid_v5 ...)
|
63
|
+
PATTERN
|
64
|
+
|
65
|
+
def insecure_algorithm?(val)
|
66
|
+
return false if val == :Digest # Don't match "Digest::Digest".
|
67
|
+
case alg_name(val)
|
68
|
+
when *allowed_hash_functions
|
69
|
+
false
|
70
|
+
when Symbol
|
71
|
+
# can't figure this one out, it's nil or a var or const.
|
72
|
+
false
|
73
|
+
else
|
74
|
+
true
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def not_just_encoding?(val)
|
79
|
+
!just_encoding?(val)
|
80
|
+
end
|
81
|
+
|
82
|
+
def just_encoding?(val)
|
83
|
+
val == :hexencode || val == :bubblebabble
|
84
|
+
end
|
85
|
+
|
86
|
+
# Built-in hash functions are listed in these docs:
|
87
|
+
# https://ruby-doc.org/stdlib-2.7.0/libdoc/digest/rdoc/Digest.html
|
88
|
+
# https://ruby-doc.org/stdlib-2.7.0/libdoc/openssl/rdoc/OpenSSL/Digest.html
|
89
|
+
DEFAULT_ALLOWED = %w[
|
90
|
+
SHA256
|
91
|
+
SHA384
|
92
|
+
SHA512
|
93
|
+
].freeze
|
94
|
+
|
95
|
+
def allowed_hash_functions
|
96
|
+
@allowed_algorithms ||= cop_config.fetch("Allowed", DEFAULT_ALLOWED).map(&:downcase)
|
97
|
+
end
|
98
|
+
|
99
|
+
def alg_name(val)
|
100
|
+
return :nil if val.nil?
|
101
|
+
return val.to_s.downcase unless val.is_a?(RuboCop::AST::Node)
|
102
|
+
case val.type
|
103
|
+
when :sym, :str
|
104
|
+
val.children.first.to_s.downcase
|
105
|
+
else
|
106
|
+
val.type
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def on_const(const_node)
|
111
|
+
if insecure_const?(const_node) && !digest_uuid?(const_node)
|
112
|
+
add_offense(const_node, message: MSG)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def on_send(send_node)
|
117
|
+
case
|
118
|
+
when uuid_v3?(send_node)
|
119
|
+
unless allowed_hash_functions.include?("md5")
|
120
|
+
add_offense(send_node, message: UUID_V3_MSG)
|
121
|
+
end
|
122
|
+
when uuid_v5?(send_node)
|
123
|
+
unless allowed_hash_functions.include?("sha1")
|
124
|
+
add_offense(send_node, message: UUID_V5_MSG)
|
125
|
+
end
|
126
|
+
when openssl_hmac_new?(send_node)
|
127
|
+
if openssl_hmac_new_insecure?(send_node)
|
128
|
+
add_offense(send_node, message: MSG)
|
129
|
+
end
|
130
|
+
when insecure_digest?(send_node)
|
131
|
+
add_offense(send_node, message: MSG)
|
132
|
+
when insecure_hash_lookup?(send_node)
|
133
|
+
add_offense(send_node, message: MSG)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
@@ -9,11 +9,11 @@ module RuboCop
|
|
9
9
|
MSG = "Prefer `render` with string instead of symbol"
|
10
10
|
|
11
11
|
def_node_matcher :render_sym?, <<-PATTERN
|
12
|
-
(send nil? :render $(sym _))
|
12
|
+
(send nil? {:render :render_to_string} $(sym _))
|
13
13
|
PATTERN
|
14
14
|
|
15
15
|
def_node_matcher :render_with_options?, <<-PATTERN
|
16
|
-
(send nil? :render (hash $...))
|
16
|
+
(send nil? {:render :render_to_string} (hash $...))
|
17
17
|
PATTERN
|
18
18
|
|
19
19
|
def_node_matcher :action_key?, <<-PATTERN
|
@@ -1,36 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "rubocop"
|
4
|
+
require "rubocop/cop/github/render_literal_helpers"
|
4
5
|
|
5
6
|
module RuboCop
|
6
7
|
module Cop
|
7
8
|
module GitHub
|
8
9
|
class RailsControllerRenderLiteral < Cop
|
9
|
-
|
10
|
-
|
11
|
-
def_node_matcher :literal?, <<-PATTERN
|
12
|
-
({str sym true false nil?} ...)
|
13
|
-
PATTERN
|
14
|
-
|
15
|
-
def_node_matcher :render?, <<-PATTERN
|
16
|
-
(send nil? :render ...)
|
17
|
-
PATTERN
|
18
|
-
|
19
|
-
def_node_matcher :render_literal?, <<-PATTERN
|
20
|
-
(send nil? :render ({str sym} $_) $...)
|
21
|
-
PATTERN
|
10
|
+
include RenderLiteralHelpers
|
22
11
|
|
23
|
-
|
24
|
-
(send nil? :render (const _ _) ...)
|
25
|
-
PATTERN
|
26
|
-
|
27
|
-
def_node_matcher :render_inst?, <<-PATTERN
|
28
|
-
(send nil? :render (send _ :new ...) ...)
|
29
|
-
PATTERN
|
30
|
-
|
31
|
-
def_node_matcher :render_with_options?, <<-PATTERN
|
32
|
-
(send nil? :render (hash $...))
|
33
|
-
PATTERN
|
12
|
+
MSG = "render must be used with a string literal or an instance of a Class"
|
34
13
|
|
35
14
|
def_node_matcher :ignore_key?, <<-PATTERN
|
36
15
|
(pair (sym {
|
@@ -68,10 +47,16 @@ module RuboCop
|
|
68
47
|
}) ...)
|
69
48
|
PATTERN
|
70
49
|
|
50
|
+
def_node_matcher :render_const?, <<-PATTERN
|
51
|
+
(send nil? {:render :render_to_string} (const _ _) ...)
|
52
|
+
PATTERN
|
53
|
+
|
71
54
|
def on_send(node)
|
72
55
|
return unless render?(node)
|
73
56
|
|
74
|
-
if
|
57
|
+
return if render_view_component?(node) || render_const?(node)
|
58
|
+
|
59
|
+
if render_literal?(node)
|
75
60
|
elsif option_pairs = render_with_options?(node)
|
76
61
|
option_pairs = option_pairs.reject { |pair| options_key?(pair) }
|
77
62
|
|
@@ -82,18 +67,40 @@ module RuboCop
|
|
82
67
|
if template_node = option_pairs.map { |pair| template_key?(pair) }.compact.first
|
83
68
|
if !literal?(template_node)
|
84
69
|
add_offense(node, location: :expression)
|
70
|
+
return
|
85
71
|
end
|
86
72
|
else
|
87
73
|
add_offense(node, location: :expression)
|
74
|
+
return
|
88
75
|
end
|
89
76
|
|
90
77
|
if layout_node = option_pairs.map { |pair| layout_key?(pair) }.compact.first
|
91
78
|
if !literal?(layout_node)
|
92
79
|
add_offense(node, location: :expression)
|
80
|
+
return
|
93
81
|
end
|
94
82
|
end
|
95
83
|
else
|
96
84
|
add_offense(node, location: :expression)
|
85
|
+
return
|
86
|
+
end
|
87
|
+
|
88
|
+
if render_literal?(node)
|
89
|
+
option_hash = node.arguments[1]
|
90
|
+
if option_hash && !option_hash.hash_type?
|
91
|
+
add_offense(node, location: :expression)
|
92
|
+
return
|
93
|
+
end
|
94
|
+
option_pairs = option_hash && option_hash.pairs
|
95
|
+
else
|
96
|
+
option_pairs = node.arguments[0].pairs
|
97
|
+
end
|
98
|
+
|
99
|
+
if option_pairs
|
100
|
+
locals = option_pairs.map { |pair| locals_key?(pair) }.compact.first
|
101
|
+
if locals && (!locals.hash_type? || !hash_with_literal_keys?(locals))
|
102
|
+
add_offense(node, location: :expression)
|
103
|
+
end
|
97
104
|
end
|
98
105
|
end
|
99
106
|
end
|
@@ -7,15 +7,15 @@ module RuboCop
|
|
7
7
|
module GitHub
|
8
8
|
class RailsControllerRenderPathsExist < Cop
|
9
9
|
def_node_matcher :render?, <<-PATTERN
|
10
|
-
(send nil? :render $...)
|
10
|
+
(send nil? {:render :render_to_string} $...)
|
11
11
|
PATTERN
|
12
12
|
|
13
13
|
def_node_matcher :render_str?, <<-PATTERN
|
14
|
-
(send nil? :render $({str sym} $_) ...)
|
14
|
+
(send nil? {:render :render_to_string} $({str sym} $_) ...)
|
15
15
|
PATTERN
|
16
16
|
|
17
17
|
def_node_matcher :render_options?, <<-PATTERN
|
18
|
-
(send nil? :render (hash $...))
|
18
|
+
(send nil? {:render :render_to_string} (hash $...))
|
19
19
|
PATTERN
|
20
20
|
|
21
21
|
def_node_matcher :render_key?, <<-PATTERN
|
@@ -9,7 +9,7 @@ module RuboCop
|
|
9
9
|
MSG = "Prefer `render` template shorthand"
|
10
10
|
|
11
11
|
def_node_matcher :render_with_options?, <<-PATTERN
|
12
|
-
(send nil? :render (hash $...))
|
12
|
+
(send nil? {:render :render_to_string} (hash $...))
|
13
13
|
PATTERN
|
14
14
|
|
15
15
|
def_node_matcher :action_key?, <<-PATTERN
|
@@ -1,36 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "rubocop"
|
4
|
+
require "rubocop/cop/github/render_literal_helpers"
|
4
5
|
|
5
6
|
module RuboCop
|
6
7
|
module Cop
|
7
8
|
module GitHub
|
8
9
|
class RailsViewRenderLiteral < Cop
|
9
|
-
|
10
|
+
include RenderLiteralHelpers
|
10
11
|
|
11
|
-
|
12
|
-
({str sym true false nil?} ...)
|
13
|
-
PATTERN
|
14
|
-
|
15
|
-
def_node_matcher :render?, <<-PATTERN
|
16
|
-
(send nil? :render $...)
|
17
|
-
PATTERN
|
18
|
-
|
19
|
-
def_node_matcher :render_literal?, <<-PATTERN
|
20
|
-
(send nil? :render ({str sym} $_) $...)
|
21
|
-
PATTERN
|
22
|
-
|
23
|
-
def_node_matcher :render_inst?, <<-PATTERN
|
24
|
-
(send nil? :render (send _ :new ...) ...)
|
25
|
-
PATTERN
|
26
|
-
|
27
|
-
def_node_matcher :render_const?, <<-PATTERN
|
28
|
-
(send nil? :render (const _ _) ...)
|
29
|
-
PATTERN
|
30
|
-
|
31
|
-
def_node_matcher :render_with_options?, <<-PATTERN
|
32
|
-
(send nil? :render (hash $...) ...)
|
33
|
-
PATTERN
|
12
|
+
MSG = "render must be used with a literal template and use literals for locals keys"
|
34
13
|
|
35
14
|
def_node_matcher :ignore_key?, <<-PATTERN
|
36
15
|
(pair (sym {
|
@@ -50,7 +29,10 @@ module RuboCop
|
|
50
29
|
def on_send(node)
|
51
30
|
return unless render?(node)
|
52
31
|
|
53
|
-
|
32
|
+
# Ignore "component"-style renders
|
33
|
+
return if render_view_component?(node)
|
34
|
+
|
35
|
+
if render_literal?(node)
|
54
36
|
elsif option_pairs = render_with_options?(node)
|
55
37
|
if option_pairs.any? { |pair| ignore_key?(pair) }
|
56
38
|
return
|
@@ -59,12 +41,31 @@ module RuboCop
|
|
59
41
|
if partial_node = option_pairs.map { |pair| partial_key?(pair) }.compact.first
|
60
42
|
if !literal?(partial_node)
|
61
43
|
add_offense(node, location: :expression)
|
44
|
+
return
|
62
45
|
end
|
63
46
|
else
|
64
47
|
add_offense(node, location: :expression)
|
48
|
+
return
|
65
49
|
end
|
66
50
|
else
|
67
51
|
add_offense(node, location: :expression)
|
52
|
+
return
|
53
|
+
end
|
54
|
+
|
55
|
+
if render_literal?(node) && node.arguments.count > 1
|
56
|
+
locals = node.arguments[1]
|
57
|
+
elsif options_pairs = render_with_options?(node)
|
58
|
+
locals = option_pairs.map { |pair| locals_key?(pair) }.compact.first
|
59
|
+
end
|
60
|
+
|
61
|
+
if locals
|
62
|
+
if locals.hash_type?
|
63
|
+
if !hash_with_literal_keys?(locals)
|
64
|
+
add_offense(node, location: :expression)
|
65
|
+
end
|
66
|
+
else
|
67
|
+
add_offense(node, location: :expression)
|
68
|
+
end
|
68
69
|
end
|
69
70
|
end
|
70
71
|
end
|
@@ -7,15 +7,15 @@ module RuboCop
|
|
7
7
|
module GitHub
|
8
8
|
class RailsViewRenderPathsExist < Cop
|
9
9
|
def_node_matcher :render?, <<-PATTERN
|
10
|
-
(send nil? :render $...)
|
10
|
+
(send nil? {:render :render_to_string} $...)
|
11
11
|
PATTERN
|
12
12
|
|
13
13
|
def_node_matcher :render_str?, <<-PATTERN
|
14
|
-
(send nil? :render $(str $_) ...)
|
14
|
+
(send nil? {:render :render_to_string} $(str $_) ...)
|
15
15
|
PATTERN
|
16
16
|
|
17
17
|
def_node_matcher :render_options?, <<-PATTERN
|
18
|
-
(send nil? :render (hash $...))
|
18
|
+
(send nil? {:render :render_to_string} (hash $...))
|
19
19
|
PATTERN
|
20
20
|
|
21
21
|
def_node_matcher :partial_key?, <<-PATTERN
|
@@ -9,7 +9,7 @@ module RuboCop
|
|
9
9
|
MSG = "Prefer `render` partial shorthand"
|
10
10
|
|
11
11
|
def_node_matcher :render_with_options?, <<-PATTERN
|
12
|
-
(send nil? :render (hash $...))
|
12
|
+
(send nil? {:render :render_to_string} (hash $...))
|
13
13
|
PATTERN
|
14
14
|
|
15
15
|
def_node_matcher :partial_key?, <<-PATTERN
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
#
|
3
|
+
require "rubocop"
|
4
|
+
|
5
|
+
module RuboCop
|
6
|
+
module Cop
|
7
|
+
module GitHub
|
8
|
+
module RenderLiteralHelpers
|
9
|
+
extend NodePattern::Macros
|
10
|
+
|
11
|
+
def_node_matcher :literal?, <<-PATTERN
|
12
|
+
({str sym true false nil?} ...)
|
13
|
+
PATTERN
|
14
|
+
|
15
|
+
def_node_matcher :render?, <<-PATTERN
|
16
|
+
(send nil? {:render :render_to_string} ...)
|
17
|
+
PATTERN
|
18
|
+
|
19
|
+
def_node_matcher :render_literal?, <<-PATTERN
|
20
|
+
(send nil? {:render :render_to_string} ({str sym} $_) $...)
|
21
|
+
PATTERN
|
22
|
+
|
23
|
+
def_node_matcher :render_with_options?, <<-PATTERN
|
24
|
+
(send nil? {:render :render_to_string} (hash $...) ...)
|
25
|
+
PATTERN
|
26
|
+
|
27
|
+
def_node_matcher :render_view_component_instance?, <<-PATTERN
|
28
|
+
(send nil? {:render :render_to_string} (send _ :new ...) ...)
|
29
|
+
PATTERN
|
30
|
+
|
31
|
+
def_node_matcher :render_view_component_instance_with_content?, <<-PATTERN
|
32
|
+
(send nil? {:render :render_to_string} (send (send _ :new ...) `:with_content ...))
|
33
|
+
PATTERN
|
34
|
+
|
35
|
+
def_node_matcher :render_view_component_collection?, <<-PATTERN
|
36
|
+
(send nil? {:render :render_to_string} (send _ :with_collection ...) ...)
|
37
|
+
PATTERN
|
38
|
+
|
39
|
+
def_node_matcher :locals_key?, <<-PATTERN
|
40
|
+
(pair (sym :locals) $_)
|
41
|
+
PATTERN
|
42
|
+
|
43
|
+
def hash_with_literal_keys?(hash)
|
44
|
+
hash.pairs.all? { |pair| literal?(pair.key) }
|
45
|
+
end
|
46
|
+
|
47
|
+
def render_view_component?(node)
|
48
|
+
render_view_component_instance_with_content?(node) ||
|
49
|
+
render_view_component_instance?(node) ||
|
50
|
+
render_view_component_collection?(node)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
data/lib/rubocop/cop/github.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "rubocop/cop/github/insecure_hash_algorithm"
|
3
4
|
require "rubocop/cop/github/rails_application_record"
|
4
5
|
require "rubocop/cop/github/rails_controller_render_action_symbol"
|
5
6
|
require "rubocop/cop/github/rails_controller_render_literal"
|
metadata
CHANGED
@@ -1,99 +1,99 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubocop-github
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.17.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- GitHub
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-01-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rubocop
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0
|
19
|
+
version: '0'
|
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: 0
|
26
|
+
version: '0'
|
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: '0'
|
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: '0'
|
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: '0'
|
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: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: actionview
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
61
|
+
version: '6.1'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
68
|
+
version: '6.1'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: minitest
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - "
|
73
|
+
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
75
|
+
version: '0'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- - "
|
80
|
+
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: '
|
82
|
+
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: rake
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- - "
|
87
|
+
- - ">="
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: '
|
89
|
+
version: '0'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- - "
|
94
|
+
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: '
|
96
|
+
version: '0'
|
97
97
|
description: 'Code style checking for GitHub Ruby repositories '
|
98
98
|
email: engineering@github.com
|
99
99
|
executables: []
|
@@ -115,6 +115,7 @@ files:
|
|
115
115
|
- guides/rails-render-inline.md
|
116
116
|
- guides/rails-render-literal.md
|
117
117
|
- lib/rubocop/cop/github.rb
|
118
|
+
- lib/rubocop/cop/github/insecure_hash_algorithm.rb
|
118
119
|
- lib/rubocop/cop/github/rails_application_record.rb
|
119
120
|
- lib/rubocop/cop/github/rails_controller_render_action_symbol.rb
|
120
121
|
- lib/rubocop/cop/github/rails_controller_render_literal.rb
|
@@ -125,11 +126,12 @@ files:
|
|
125
126
|
- lib/rubocop/cop/github/rails_view_render_literal.rb
|
126
127
|
- lib/rubocop/cop/github/rails_view_render_paths_exist.rb
|
127
128
|
- lib/rubocop/cop/github/rails_view_render_shorthand.rb
|
129
|
+
- lib/rubocop/cop/github/render_literal_helpers.rb
|
128
130
|
homepage: https://github.com/github/rubocop-github
|
129
131
|
licenses:
|
130
132
|
- MIT
|
131
133
|
metadata: {}
|
132
|
-
post_install_message:
|
134
|
+
post_install_message:
|
133
135
|
rdoc_options: []
|
134
136
|
require_paths:
|
135
137
|
- lib
|
@@ -137,15 +139,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
137
139
|
requirements:
|
138
140
|
- - ">="
|
139
141
|
- !ruby/object:Gem::Version
|
140
|
-
version: 2.
|
142
|
+
version: 2.5.0
|
141
143
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
142
144
|
requirements:
|
143
145
|
- - ">="
|
144
146
|
- !ruby/object:Gem::Version
|
145
147
|
version: '0'
|
146
148
|
requirements: []
|
147
|
-
rubygems_version: 3.1.
|
148
|
-
signing_key:
|
149
|
+
rubygems_version: 3.1.6
|
150
|
+
signing_key:
|
149
151
|
specification_version: 4
|
150
152
|
summary: RuboCop GitHub
|
151
153
|
test_files: []
|