rubocop-standard 4.2.0 → 5.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/{LICENSE → LICENSE.txt} +0 -0
- data/README.md +4 -8
- data/config/default.yml +9 -347
- data/config/rails.yml +0 -108
- metadata +8 -49
- data/STYLEGUIDE.md +0 -763
- data/guides/rails-controller-render-shorthand.md +0 -9
- data/guides/rails-render-inline.md +0 -27
- data/guides/rails-render-literal.md +0 -8
- data/lib/rubocop/cop/standard/rails.rb +0 -10
- data/lib/rubocop/cop/standard/rails/rails_application_record.rb +0 -27
- data/lib/rubocop/cop/standard/rails/rails_controller_render_action_symbol.rb +0 -43
- data/lib/rubocop/cop/standard/rails/rails_controller_render_paths_exist.rb +0 -63
- data/lib/rubocop/cop/standard/rails/rails_controller_render_shorthand.rb +0 -51
- data/lib/rubocop/cop/standard/rails/rails_render_inline.rb +0 -27
- data/lib/rubocop/cop/standard/rails/rails_render_object_collection.rb +0 -45
- data/lib/rubocop/cop/standard/rails/rails_view_render_paths_exist.rb +0 -55
- data/lib/rubocop/cop/standard/rails/rails_view_render_shorthand.rb +0 -38
@@ -1,27 +0,0 @@
|
|
1
|
-
# Standard/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,8 +0,0 @@
|
|
1
|
-
# Standard/RailsRenderLiteral
|
2
|
-
|
3
|
-
tldr; `render` MUST be passed a string literal template path.
|
4
|
-
|
5
|
-
* When used in conjunction with `Standard/RailsViewRenderPathsExist`, linters can ensure the target file exists on disk and would not crash rendering a missing template.
|
6
|
-
* Makes it easier for humans to trace callers of a template. Simply search for the full path of the target template to find **all** call sites.
|
7
|
-
* This same call site tracing enables automated unused template checking. If no callers are found, the template can be safely removed.
|
8
|
-
* Enables render precompilation and inlining optimizations. Target templates can be compiled and inlined on boot time rather than deferring to first render to lazily compile templates.
|
@@ -1,10 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'rubocop/cop/standard/rails/rails_application_record'
|
4
|
-
require 'rubocop/cop/standard/rails/rails_controller_render_action_symbol'
|
5
|
-
require 'rubocop/cop/standard/rails/rails_controller_render_paths_exist'
|
6
|
-
require 'rubocop/cop/standard/rails/rails_controller_render_shorthand'
|
7
|
-
require 'rubocop/cop/standard/rails/rails_render_inline'
|
8
|
-
require 'rubocop/cop/standard/rails/rails_render_object_collection'
|
9
|
-
require 'rubocop/cop/standard/rails/rails_view_render_paths_exist'
|
10
|
-
require 'rubocop/cop/standard/rails/rails_view_render_shorthand'
|
@@ -1,27 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'rubocop'
|
4
|
-
|
5
|
-
module RuboCop
|
6
|
-
module Cop
|
7
|
-
module Standard
|
8
|
-
class RailsApplicationRecord < Cop
|
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
|
-
add_offense(superclass, location: :expression) if active_record_base_const?(superclass) && !application_record_const?(klass)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
@@ -1,43 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'rubocop'
|
4
|
-
|
5
|
-
module RuboCop
|
6
|
-
module Cop
|
7
|
-
module Standard
|
8
|
-
class RailsControllerRenderActionSymbol < Cop
|
9
|
-
MSG = 'Prefer `render` with string instead of symbol'
|
10
|
-
|
11
|
-
def_node_matcher :render_sym?, <<-PATTERN
|
12
|
-
(send nil? :render $(sym _))
|
13
|
-
PATTERN
|
14
|
-
|
15
|
-
def_node_matcher :render_with_options?, <<-PATTERN
|
16
|
-
(send nil? :render (hash $...))
|
17
|
-
PATTERN
|
18
|
-
|
19
|
-
def_node_matcher :action_key?, <<-PATTERN
|
20
|
-
(pair (sym {:action :template}) $(sym _))
|
21
|
-
PATTERN
|
22
|
-
|
23
|
-
def on_send(node)
|
24
|
-
if (sym_node = render_sym?(node))
|
25
|
-
add_offense(sym_node, location: :expression)
|
26
|
-
elsif (option_pairs = render_with_options?(node))
|
27
|
-
option_pairs.each do |pair|
|
28
|
-
if (sym_node = action_key?(pair))
|
29
|
-
add_offense(sym_node, location: :expression)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
def autocorrect(node)
|
36
|
-
lambda do |corrector|
|
37
|
-
corrector.replace(node.source_range, "\"#{node.children[0]}\"")
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
@@ -1,63 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'rubocop'
|
4
|
-
|
5
|
-
module RuboCop
|
6
|
-
module Cop
|
7
|
-
module Standard
|
8
|
-
class RailsControllerRenderPathsExist < Cop
|
9
|
-
def_node_matcher :render?, <<-PATTERN
|
10
|
-
(send nil? :render $...)
|
11
|
-
PATTERN
|
12
|
-
|
13
|
-
def_node_matcher :render_str?, <<-PATTERN
|
14
|
-
(send nil? :render $({str sym} $_) ...)
|
15
|
-
PATTERN
|
16
|
-
|
17
|
-
def_node_matcher :render_options?, <<-PATTERN
|
18
|
-
(send nil? :render (hash $...))
|
19
|
-
PATTERN
|
20
|
-
|
21
|
-
def_node_matcher :render_key?, <<-PATTERN
|
22
|
-
(pair (sym ${:action :partial :template}) $({str sym} $_))
|
23
|
-
PATTERN
|
24
|
-
|
25
|
-
def on_send(node)
|
26
|
-
return unless cop_config['ViewPath']
|
27
|
-
|
28
|
-
if (args = render_str?(node))
|
29
|
-
node, path = args
|
30
|
-
add_offense(node, location: :expression, message: 'Template could not be found') unless resolve_template(path.to_s)
|
31
|
-
elsif (pairs = render_options?(node))
|
32
|
-
if (pair = pairs.detect { |p| render_key?(p) })
|
33
|
-
key, node, path = render_key?(pair)
|
34
|
-
|
35
|
-
case key
|
36
|
-
when :action, :template
|
37
|
-
add_offense(node, location: :expression, message: 'Template could not be found') unless resolve_template(path.to_s)
|
38
|
-
when :partial
|
39
|
-
add_offense(node, location: :expression, message: 'Partial template could not be found') unless resolve_partial(path.to_s)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
def resolve_template(path)
|
46
|
-
cop_config['ViewPath'].each do |view_path|
|
47
|
-
if (m = Dir[File.join(config.path_relative_to_config(view_path), path) + '*'].first)
|
48
|
-
return m
|
49
|
-
end
|
50
|
-
end
|
51
|
-
nil
|
52
|
-
end
|
53
|
-
|
54
|
-
def resolve_partial(path)
|
55
|
-
parts = path.split(File::SEPARATOR)
|
56
|
-
parts << "_#{parts.pop}"
|
57
|
-
path = parts.join(File::SEPARATOR)
|
58
|
-
resolve_template(path)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
@@ -1,51 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'rubocop'
|
4
|
-
|
5
|
-
module RuboCop
|
6
|
-
module Cop
|
7
|
-
module Standard
|
8
|
-
class RailsControllerRenderShorthand < Cop
|
9
|
-
MSG = 'Prefer `render` template shorthand'
|
10
|
-
|
11
|
-
def_node_matcher :render_with_options?, <<-PATTERN
|
12
|
-
(send nil? :render (hash $...))
|
13
|
-
PATTERN
|
14
|
-
|
15
|
-
def_node_matcher :action_key?, <<-PATTERN
|
16
|
-
(pair (sym {:action :template}) $({str sym} _))
|
17
|
-
PATTERN
|
18
|
-
|
19
|
-
def_node_matcher :str, <<-PATTERN
|
20
|
-
({str sym} $_)
|
21
|
-
PATTERN
|
22
|
-
|
23
|
-
def investigate(*)
|
24
|
-
@autocorrect = {}
|
25
|
-
end
|
26
|
-
|
27
|
-
def autocorrect(node)
|
28
|
-
@autocorrect[node]
|
29
|
-
end
|
30
|
-
|
31
|
-
def on_send(node)
|
32
|
-
return unless (option_pairs = render_with_options?(node))
|
33
|
-
|
34
|
-
option_pairs.each do |pair|
|
35
|
-
next unless (value_node = action_key?(pair))
|
36
|
-
|
37
|
-
comma = option_pairs.length > 1 ? ', ' : ''
|
38
|
-
corrected_source = node.source
|
39
|
-
.sub(/#{pair.source}(,\s*)?/, '')
|
40
|
-
.sub('render ', "render \"#{str(value_node)}\"#{comma}")
|
41
|
-
|
42
|
-
@autocorrect[node] = lambda do |corrector|
|
43
|
-
corrector.replace(node.source_range, corrected_source)
|
44
|
-
end
|
45
|
-
add_offense(node, location: :expression, message: "Use `#{corrected_source}` instead")
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
@@ -1,27 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'rubocop'
|
4
|
-
|
5
|
-
module RuboCop
|
6
|
-
module Cop
|
7
|
-
module Standard
|
8
|
-
class RailsRenderInline < Cop
|
9
|
-
MSG = 'Avoid `render inline:`'
|
10
|
-
|
11
|
-
def_node_matcher :render_with_options?, <<-PATTERN
|
12
|
-
(send nil? :render (hash $...))
|
13
|
-
PATTERN
|
14
|
-
|
15
|
-
def_node_matcher :inline_key?, <<-PATTERN
|
16
|
-
(pair (sym :inline) $_)
|
17
|
-
PATTERN
|
18
|
-
|
19
|
-
def on_send(node)
|
20
|
-
return unless (option_pairs = render_with_options?(node))
|
21
|
-
|
22
|
-
add_offense(node, location: :expression) if option_pairs.detect { |pair| inline_key?(pair) }
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
@@ -1,45 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'rubocop'
|
4
|
-
|
5
|
-
module RuboCop
|
6
|
-
module Cop
|
7
|
-
module Standard
|
8
|
-
class RailsRenderObjectCollection < Cop
|
9
|
-
MSG = 'Avoid `render object:`'
|
10
|
-
|
11
|
-
def_node_matcher :render_with_options?, <<-PATTERN
|
12
|
-
(send nil? :render (hash $...) ...)
|
13
|
-
PATTERN
|
14
|
-
|
15
|
-
def_node_matcher :partial_key?, <<-PATTERN
|
16
|
-
(pair (sym :partial) $_)
|
17
|
-
PATTERN
|
18
|
-
|
19
|
-
def_node_matcher :object_key?, <<-PATTERN
|
20
|
-
(pair (sym ${:object :collection :spacer_template}) $_)
|
21
|
-
PATTERN
|
22
|
-
|
23
|
-
def on_send(node)
|
24
|
-
return unless (option_pairs = render_with_options?(node))
|
25
|
-
|
26
|
-
partial_pair = option_pairs.detect { |pair| partial_key?(pair) }
|
27
|
-
object_pair = option_pairs.detect { |pair| object_key?(pair) }
|
28
|
-
|
29
|
-
return unless partial_pair && object_pair
|
30
|
-
|
31
|
-
partial_name = partial_key?(partial_pair)
|
32
|
-
object_sym, object_node = object_key?(object_pair)
|
33
|
-
|
34
|
-
case object_sym
|
35
|
-
when :object
|
36
|
-
suggestion = ", instead `render partial: #{partial_name.source}, locals: { #{File.basename(partial_name.children[0], '.html.erb')}: #{object_node.source} }`" if partial_name.children[0].is_a?(String)
|
37
|
-
add_offense(node, location: :expression, message: "Avoid `render object:`#{suggestion}")
|
38
|
-
when :collection, :spacer_template
|
39
|
-
add_offense(node, location: :expression, message: 'Avoid `render collection:`')
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
@@ -1,55 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'rubocop'
|
4
|
-
|
5
|
-
module RuboCop
|
6
|
-
module Cop
|
7
|
-
module Standard
|
8
|
-
class RailsViewRenderPathsExist < Cop
|
9
|
-
def_node_matcher :render?, <<-PATTERN
|
10
|
-
(send nil? :render $...)
|
11
|
-
PATTERN
|
12
|
-
|
13
|
-
def_node_matcher :render_str?, <<-PATTERN
|
14
|
-
(send nil? :render $(str $_) ...)
|
15
|
-
PATTERN
|
16
|
-
|
17
|
-
def_node_matcher :render_options?, <<-PATTERN
|
18
|
-
(send nil? :render (hash $...))
|
19
|
-
PATTERN
|
20
|
-
|
21
|
-
def_node_matcher :partial_key?, <<-PATTERN
|
22
|
-
(pair (sym :partial) $(str $_))
|
23
|
-
PATTERN
|
24
|
-
|
25
|
-
def on_send(node)
|
26
|
-
return unless cop_config['ViewPath']
|
27
|
-
|
28
|
-
if (args = render_str?(node))
|
29
|
-
node, path = args
|
30
|
-
add_offense(node, location: :expression, message: 'Partial template could not be found') unless resolve_partial(path.to_s)
|
31
|
-
elsif (pairs = render_options?(node))
|
32
|
-
if (pair = pairs.detect { |p| partial_key?(p) })
|
33
|
-
node, path = partial_key?(pair)
|
34
|
-
|
35
|
-
add_offense(node, location: :expression, message: 'Partial template could not be found') unless resolve_partial(path.to_s)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
def resolve_partial(path)
|
41
|
-
parts = path.split(File::SEPARATOR)
|
42
|
-
parts << "_#{parts.pop}"
|
43
|
-
path = parts.join(File::SEPARATOR)
|
44
|
-
|
45
|
-
cop_config['ViewPath'].each do |view_path|
|
46
|
-
if (m = Dir[File.join(config.path_relative_to_config(view_path), path) + '*'].first)
|
47
|
-
return m
|
48
|
-
end
|
49
|
-
end
|
50
|
-
nil
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
@@ -1,38 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'rubocop'
|
4
|
-
|
5
|
-
module RuboCop
|
6
|
-
module Cop
|
7
|
-
module Standard
|
8
|
-
class RailsViewRenderShorthand < Cop
|
9
|
-
MSG = 'Prefer `render` partial shorthand'
|
10
|
-
|
11
|
-
def_node_matcher :render_with_options?, <<-PATTERN
|
12
|
-
(send nil? :render (hash $...))
|
13
|
-
PATTERN
|
14
|
-
|
15
|
-
def_node_matcher :partial_key?, <<-PATTERN
|
16
|
-
(pair (sym :partial) $(str _))
|
17
|
-
PATTERN
|
18
|
-
|
19
|
-
def_node_matcher :locals_key?, <<-PATTERN
|
20
|
-
(pair (sym :locals) $_)
|
21
|
-
PATTERN
|
22
|
-
|
23
|
-
def on_send(node)
|
24
|
-
return unless (option_pairs = render_with_options?(node))
|
25
|
-
|
26
|
-
partial_key = option_pairs.map { |pair| partial_key?(pair) }.compact.first
|
27
|
-
locals_key = option_pairs.map { |pair| locals_key?(pair) }.compact.first
|
28
|
-
|
29
|
-
if option_pairs.length == 1 && partial_key
|
30
|
-
add_offense(node, location: :expression, message: "Use `render #{partial_key.source}` instead")
|
31
|
-
elsif option_pairs.length == 2 && partial_key && locals_key
|
32
|
-
add_offense(node, location: :expression, message: "Use `render #{partial_key.source}, #{locals_key.source}` instead")
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|