rubocop-github 0.3.0 → 0.4.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 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