rubocop-github 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 601fcd9953677e8b83264571ab930fb673ce9308
4
- data.tar.gz: 7cb82de90efa33ab5bd9f2123938f49a131cb448
3
+ metadata.gz: ab0b671ded0342a09ab6abaed49ead04d5e8d998
4
+ data.tar.gz: 3f7fba786bcab859beab172f8cd873b31053a816
5
5
  SHA512:
6
- metadata.gz: 0ac31931fe1edf63b4ecb4bf2f1177ea2b7a68a7db69e3ffdb802aaac8be2c4f122c88ac755a9d197d8fa4676b1d3ec2a4717e615b66e1afb07d385f96ed99e8
7
- data.tar.gz: a7da9a85c62522bfdee8e3f9a97b4c303ae49af3baf97ab1a647e9b4e3d44042f53a3c646f3b47f5689ce844fee212bda37bc1fae27e574da7eca52834f6af51
6
+ metadata.gz: 64db71077a7663685feaeb399caf49fce7b190471f1df6a17b5f40623134bf3edf1aded0bd10bcdb913a57c85e32c43d966232cf6ff42adbb58b0fa76a471950
7
+ data.tar.gz: 823c96ff8f71694450d79de94cb5479a92c7d734646b18023f2e6044c940a8e1f1a7bf28af8e45b074b5ce80410b2985aba2a244ff7fd0144562553e8f3fc5c0
data/config/default.yml CHANGED
@@ -3,6 +3,12 @@ require: rubocop/cop/github
3
3
  AllCops:
4
4
  DisabledByDefault: true
5
5
 
6
+ Bundler/DuplicatedGem:
7
+ Enabled: true
8
+
9
+ Bundler/OrderedGems:
10
+ Enabled: true
11
+
6
12
  Lint/BlockAlignment:
7
13
  Enabled: true
8
14
 
data/config/rails.yml CHANGED
@@ -23,6 +23,62 @@ Rails/UniqBeforePluck:
23
23
  GitHub/RailsApplicationRecord:
24
24
  Enabled: true
25
25
 
26
+ GitHub/RailsControllerRenderActionSymbol:
27
+ Enabled: true
28
+ Include:
29
+ - 'app/controllers/**/*.rb'
30
+
31
+ GitHub/RailsControllerRenderInline:
32
+ Enabled: true
33
+ StyleGuide: https://github.com/github/rubocop-github/blob/master/guides/rails-controller-render-inline.md
34
+ Include:
35
+ - 'app/controllers/**/*.rb'
36
+
37
+ GitHub/RailsControllerRenderLiteral:
38
+ Enabled: true
39
+ StyleGuide: https://github.com/github/rubocop-github/blob/master/guides/rails-render-literal.md
40
+ Include:
41
+ - 'app/controllers/**/*.rb'
42
+
43
+ GitHub/RailsControllerRenderPathsExist:
44
+ Enabled: true
45
+ ViewPath:
46
+ - 'app/views'
47
+ Include:
48
+ - 'app/controllers/**/*.rb'
49
+
50
+ GitHub/RailsControllerRenderShorthand:
51
+ Enabled: true
52
+ StyleGuide: https://github.com/github/rubocop-github/blob/master/guides/rails-controller-render-shorthand.md
53
+ Include:
54
+ - 'app/controllers/**/*.rb'
55
+
56
+ GitHub/RailsRenderObjectCollection:
57
+ Enabled: false
58
+
59
+ GitHub/RailsViewRenderLiteral:
60
+ Enabled: true
61
+ StyleGuide: https://github.com/github/rubocop-github/blob/master/guides/rails-render-literal.md
62
+ Include:
63
+ - 'app/helpers/**/*.rb'
64
+ - 'app/view_models/**/*.rb'
65
+ - 'app/views/**/*.erb'
66
+
67
+ GitHub/RailsViewRenderPathsExist:
68
+ Enabled: true
69
+ ViewPath:
70
+ - 'app/views'
71
+ Include:
72
+ - 'app/helpers/**/*.rb'
73
+ - 'app/view_models/**/*.rb'
74
+ - 'app/views/**/*.erb'
75
+
76
+ GitHub/RailsViewRenderShorthand:
77
+ Enabled: true
78
+ Include:
79
+ - 'app/helpers/**/*.rb'
80
+ - 'app/view_models/**/*.rb'
81
+ - 'app/views/**/*.erb'
26
82
 
27
83
  # Exclude Rails ERB files from incompatible cops
28
84
 
@@ -1 +1,10 @@
1
1
  require "rubocop/cop/github/rails_application_record"
2
+ require "rubocop/cop/github/rails_controller_render_action_symbol"
3
+ require "rubocop/cop/github/rails_controller_render_inline"
4
+ require "rubocop/cop/github/rails_controller_render_literal"
5
+ require "rubocop/cop/github/rails_controller_render_paths_exist"
6
+ require "rubocop/cop/github/rails_controller_render_shorthand"
7
+ require "rubocop/cop/github/rails_render_object_collection"
8
+ require "rubocop/cop/github/rails_view_render_literal"
9
+ require "rubocop/cop/github/rails_view_render_paths_exist"
10
+ require "rubocop/cop/github/rails_view_render_shorthand"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "rubocop"
2
4
 
3
5
  module RuboCop
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rubocop"
4
+
5
+ module RuboCop
6
+ module Cop
7
+ module GitHub
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, :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, :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
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rubocop"
4
+
5
+ module RuboCop
6
+ module Cop
7
+ module GitHub
8
+ class RailsControllerRenderInline < 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
+ if option_pairs = render_with_options?(node)
21
+ if option_pairs.detect { |pair| inline_key?(pair) }
22
+ add_offense(node, :expression)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,93 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rubocop"
4
+
5
+ module RuboCop
6
+ module Cop
7
+ module GitHub
8
+ class RailsControllerRenderLiteral < Cop
9
+ MSG = "render must be used with a string literal"
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
22
+
23
+ def_node_matcher :render_with_options?, <<-PATTERN
24
+ (send nil :render (hash $...))
25
+ PATTERN
26
+
27
+ def_node_matcher :ignore_key?, <<-PATTERN
28
+ (pair (sym {
29
+ :body
30
+ :file
31
+ :html
32
+ :js
33
+ :json
34
+ :nothing
35
+ :plain
36
+ :text
37
+ :xml
38
+ }) $_)
39
+ PATTERN
40
+
41
+ def_node_matcher :template_key?, <<-PATTERN
42
+ (pair (sym {
43
+ :action
44
+ :partial
45
+ :template
46
+ }) $_)
47
+ PATTERN
48
+
49
+ def_node_matcher :layout_key?, <<-PATTERN
50
+ (pair (sym :layout) $_)
51
+ PATTERN
52
+
53
+ def_node_matcher :options_key?, <<-PATTERN
54
+ (pair (sym {
55
+ :content_type
56
+ :location
57
+ :status
58
+ :formats
59
+ }) ...)
60
+ PATTERN
61
+
62
+ def on_send(node)
63
+ return unless render?(node)
64
+
65
+ if render_literal?(node)
66
+ elsif option_pairs = render_with_options?(node)
67
+ option_pairs = option_pairs.reject { |pair| options_key?(pair) }
68
+
69
+ if option_pairs.any? { |pair| ignore_key?(pair) }
70
+ return
71
+ end
72
+
73
+ if template_node = option_pairs.map { |pair| template_key?(pair) }.compact.first
74
+ if !literal?(template_node)
75
+ add_offense(node, :expression)
76
+ end
77
+ else
78
+ add_offense(node, :expression)
79
+ end
80
+
81
+ if layout_node = option_pairs.map { |pair| layout_key?(pair) }.compact.first
82
+ if !literal?(layout_node)
83
+ add_offense(node, :expression)
84
+ end
85
+ end
86
+ else
87
+ add_offense(node, :expression)
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rubocop"
4
+
5
+ module RuboCop
6
+ module Cop
7
+ module GitHub
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
+ unless resolve_template(path.to_s)
31
+ add_offense(node, :expression, "Template could not be found")
32
+ end
33
+ elsif pairs = render_options?(node)
34
+ if pair = pairs.detect { |p| render_key?(p) }
35
+ key, node, path = render_key?(pair)
36
+
37
+ case key
38
+ when :action, :template
39
+ unless resolve_template(path.to_s)
40
+ add_offense(node, :expression, "Template could not be found")
41
+ end
42
+ when :partial
43
+ unless resolve_partial(path.to_s)
44
+ add_offense(node, :expression, "Partial template could not be found")
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+
51
+ def resolve_template(path)
52
+ cop_config["ViewPath"].each do |view_path|
53
+ if m = Dir[File.join(config.path_relative_to_config(view_path), path) + "*"].first
54
+ return m
55
+ end
56
+ end
57
+ nil
58
+ end
59
+
60
+ def resolve_partial(path)
61
+ parts = path.split(File::SEPARATOR)
62
+ parts << "_#{parts.pop}"
63
+ path = parts.join(File::SEPARATOR)
64
+ resolve_template(path)
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rubocop"
4
+
5
+ module RuboCop
6
+ module Cop
7
+ module GitHub
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
+ if option_pairs = render_with_options?(node)
33
+ option_pairs.each do |pair|
34
+ if value_node = action_key?(pair)
35
+ comma = option_pairs.length > 1 ? ", " : ""
36
+ corrected_source = node.source
37
+ .sub(/#{pair.source}(,\s*)?/, "")
38
+ .sub("render ", "render \"#{str(value_node)}\"#{comma}")
39
+
40
+ @autocorrect[node] = lambda do |corrector|
41
+ corrector.replace(node.source_range, corrected_source)
42
+ end
43
+ add_offense(node, :expression, "Use `#{corrected_source}` instead")
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rubocop"
4
+
5
+ module RuboCop
6
+ module Cop
7
+ module GitHub
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
+ if option_pairs = render_with_options?(node)
25
+ partial_pair = option_pairs.detect { |pair| partial_key?(pair) }
26
+ object_pair = option_pairs.detect { |pair| object_key?(pair) }
27
+
28
+ if partial_pair && object_pair
29
+ partial_name = partial_key?(partial_pair)
30
+ object_sym, object_node = object_key?(object_pair)
31
+
32
+ case object_sym
33
+ when :object
34
+ if partial_name.children[0].is_a?(String)
35
+ suggestion = ", instead `render partial: #{partial_name.source}, locals: { #{File.basename(partial_name.children[0], '.html.erb')}: #{object_node.source} }`"
36
+ end
37
+ add_offense(node, :expression, "Avoid `render object:`#{suggestion}")
38
+ when :collection, :spacer_template
39
+ add_offense(node, :expression, "Avoid `render collection:`")
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rubocop"
4
+
5
+ module RuboCop
6
+ module Cop
7
+ module GitHub
8
+ class RailsViewRenderLiteral < Cop
9
+ MSG = "render must be used with a string literal"
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
22
+
23
+ def_node_matcher :render_with_options?, <<-PATTERN
24
+ (send nil :render (hash $...))
25
+ PATTERN
26
+
27
+ def_node_matcher :partial_key?, <<-PATTERN
28
+ (pair (sym {
29
+ :file
30
+ :layout
31
+ :partial
32
+ }) $_)
33
+ PATTERN
34
+
35
+ def on_send(node)
36
+ return unless render?(node)
37
+
38
+ if render_literal?(node)
39
+ elsif option_pairs = render_with_options?(node)
40
+ if partial_node = option_pairs.map { |pair| partial_key?(pair) }.compact.first
41
+ if !literal?(partial_node)
42
+ add_offense(node, :expression)
43
+ end
44
+ else
45
+ add_offense(node, :expression)
46
+ end
47
+ else
48
+ add_offense(node, :expression)
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rubocop"
4
+
5
+ module RuboCop
6
+ module Cop
7
+ module GitHub
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
+ unless resolve_partial(path.to_s)
31
+ add_offense(node, :expression, "Partial template could not be found")
32
+ end
33
+ elsif pairs = render_options?(node)
34
+ if pair = pairs.detect { |p| partial_key?(p) }
35
+ node, path = partial_key?(pair)
36
+
37
+ unless resolve_partial(path.to_s)
38
+ add_offense(node, :expression, "Partial template could not be found")
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ def resolve_partial(path)
45
+ parts = path.split(File::SEPARATOR)
46
+ parts << "_#{parts.pop}"
47
+ path = parts.join(File::SEPARATOR)
48
+
49
+ cop_config["ViewPath"].each do |view_path|
50
+ if m = Dir[File.join(config.path_relative_to_config(view_path), path) + "*"].first
51
+ return m
52
+ end
53
+ end
54
+ nil
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rubocop"
4
+
5
+ module RuboCop
6
+ module Cop
7
+ module GitHub
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
+ if option_pairs = render_with_options?(node)
25
+ partial_key = option_pairs.map { |pair| partial_key?(pair) }.compact.first
26
+ locals_key = option_pairs.map { |pair| locals_key?(pair) }.compact.first
27
+
28
+ if option_pairs.length == 1 && partial_key
29
+ add_offense(node, :expression, "Use `render #{partial_key.source}` instead")
30
+ elsif option_pairs.length == 2 && partial_key && locals_key
31
+ add_offense(node, :expression, "Use `render #{partial_key.source}, #{locals_key.source}` instead")
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
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.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - GitHub
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-01-25 00:00:00.000000000 Z
11
+ date: 2017-03-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rubocop
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0.47'
27
+ - !ruby/object:Gem::Dependency
28
+ name: actionview
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '5.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '5.0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: minitest
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -65,6 +79,15 @@ files:
65
79
  - config/rails.yml
66
80
  - lib/rubocop/cop/github.rb
67
81
  - lib/rubocop/cop/github/rails_application_record.rb
82
+ - lib/rubocop/cop/github/rails_controller_render_action_symbol.rb
83
+ - lib/rubocop/cop/github/rails_controller_render_inline.rb
84
+ - lib/rubocop/cop/github/rails_controller_render_literal.rb
85
+ - lib/rubocop/cop/github/rails_controller_render_paths_exist.rb
86
+ - lib/rubocop/cop/github/rails_controller_render_shorthand.rb
87
+ - lib/rubocop/cop/github/rails_render_object_collection.rb
88
+ - lib/rubocop/cop/github/rails_view_render_literal.rb
89
+ - lib/rubocop/cop/github/rails_view_render_paths_exist.rb
90
+ - lib/rubocop/cop/github/rails_view_render_shorthand.rb
68
91
  homepage: https://github.com/github/rubocop-github
69
92
  licenses:
70
93
  - MIT