rubocop-rhino-project 0.21.0.beta.37 → 0.21.0.beta.39

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
  SHA256:
3
- metadata.gz: 59120d377f945685bd29d1bade7c79743640fd4327b0bdd3c8ca4654c4c1208c
4
- data.tar.gz: 5871e96f507643c715c6d4a9f786b069e56572bcd84365abede6967063fad797
3
+ metadata.gz: d36a5ece31362299777682a89706b49ad706f622c7cbcc55284c509e9c2354fa
4
+ data.tar.gz: 3111527595a88362daf801f0c65d727b4006cab53f669eaff65e59cc1abac8da
5
5
  SHA512:
6
- metadata.gz: 22af500ae0ef5d8ba3f02d1ab67a84c9ee3de235748a98f35f91d5fc5b2cd2cffb26fd7defe40d053af022688025abd4a922cc3fc4a53e21941411ab815bedcc
7
- data.tar.gz: ca97eb363b632a4fa0e744537d276644b02f0e635f3f11d04031dfc6342ea95e8d5c1c1a2e7d71851b2878e682144a3b7cc89175bc78914b8daa482432f8ba5a
6
+ metadata.gz: a2d18259b933ad6044c99a0de5cca607ce03de3423e50fa3d237fd23c075a4d4a760ec747fc6ed9e147ff9ae0fcafdf545ec82ebcad7c12c0cae1055fc28deb3
7
+ data.tar.gz: 7eff1bbb5924122e185ef819c399c21f7cb263582a578589a41d364f996b13f17041cf3a705b82eed74379b205e5a9fbf88b43882415d2cab685dd1dee5c1693
data/config/default.yml CHANGED
@@ -16,6 +16,11 @@ AllCops:
16
16
  - storage/**/*
17
17
 
18
18
  RhinoProject/DuplicateRhinoReferences:
19
- Description: ''
19
+ Description: 'Check for duplicate rhino_reference calls in the same file.'
20
+ Enabled: true
21
+ SafeAutoCorrect: false
22
+
23
+ RhinoProject/OwnerSpecified:
24
+ Description: 'Check for rhino_owner_global, rhino_owner_base or rhino_owner calls'
20
25
  Enabled: true
21
26
  SafeAutoCorrect: false
@@ -0,0 +1,145 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "parser/current"
4
+ module RuboCop
5
+ module Cop
6
+ module RhinoProject
7
+ # Call `rhino_owner`, `rhino_owner_base` or `rhino_owner_global` for the model class.
8
+ #
9
+ #
10
+ # @example
11
+ # # bad
12
+ # class Blog < ApplicationRecord
13
+ # belongs_to :user
14
+ # belongs_to :category
15
+ #
16
+ # rhino_references %i[user]
17
+ # end
18
+ #
19
+ # # good
20
+ # class Blog < ApplicationRecord
21
+ # belongs_to :user
22
+ # belongs_to :category
23
+ #
24
+ # rhino_owner :user
25
+ # rhino_references %i[user category]
26
+ # end
27
+ #
28
+ class OwnerSpecified < Cop
29
+ MSG = "ActiveRecord models listed in rhino.rb must specify exactly one ownership method (rhino_owner_global, rhino_owner_reference, or rhino_owner :symbol)."
30
+
31
+ REQUIRED_METHODS = [:rhino_owner_global, :rhino_owner_base, :rhino_owner].freeze
32
+
33
+ def investigate(processed_source)
34
+ return unless applicable_model?(processed_source)
35
+
36
+ class_node = find_class_node(processed_source.ast)
37
+ return unless class_node
38
+
39
+ method_calls = find_rhino_owner_calls(class_node)
40
+
41
+ if method_calls.size != 1
42
+ add_offense(class_node, message: MSG)
43
+ end
44
+ end
45
+
46
+ private
47
+ def applicable_model?(processed_source)
48
+ model_name = extract_class_name(processed_source)
49
+
50
+ return false if inherits_from_rhino?(processed_source)
51
+
52
+ rhino_resources.include?(model_name)
53
+ end
54
+
55
+ def extract_class_name(processed_source)
56
+ class_node = find_class_node(processed_source.ast)
57
+ return unless class_node
58
+
59
+ class_name_node = class_node.children[0]
60
+ class_name_node.const_name
61
+ end
62
+
63
+ def find_rhino_owner_calls(class_node)
64
+ # Search only within the class body for Rhino ownership method calls
65
+ body_node = class_node.children[2]
66
+ find_descendants(body_node).select do |send_node|
67
+ send_node.type == :send && REQUIRED_METHODS.include?(send_node.children[1])
68
+ end
69
+ end
70
+
71
+ def find_class_node(ast)
72
+ find_descendants(ast).find { |node| node.type == :class }
73
+ end
74
+
75
+ # Check if the class inherits from a Rhino:: class
76
+ def inherits_from_rhino?(processed_source)
77
+ class_node = find_class_node(processed_source.ast)
78
+ return false unless class_node
79
+
80
+ superclass_node = class_node.children[1]
81
+ return false unless superclass_node
82
+
83
+ superclass_name = superclass_node.const_name
84
+ superclass_name&.start_with?("Rhino::")
85
+ end
86
+
87
+ def rhino_resources
88
+ @rhino_resources ||= read_rhino_resources
89
+ end
90
+
91
+ def read_rhino_resources
92
+ rhino_initializer_path = File.join(Dir.pwd, "config", "initializers", "rhino.rb")
93
+ return [] unless File.exist?(rhino_initializer_path)
94
+
95
+ rhino_initializer_content = File.read(rhino_initializer_path)
96
+ ast = Parser::CurrentRuby.parse(rhino_initializer_content)
97
+ parse_rhino_resources(ast)
98
+ end
99
+
100
+ # Parse the rhino.rb AST and extract the resources added to config.resources
101
+ def parse_rhino_resources(ast)
102
+ resources = []
103
+
104
+ find_resources_assignments(ast).each do |assignment_node|
105
+ next unless assignment_node
106
+
107
+ # Looking for array elements in `config.resources += [...]`
108
+ array_node = assignment_node.children[2] # Accessing the right-hand side of `+=`
109
+ if array_node&.type == :array
110
+ resources.concat(array_node.children.map { |node| extract_string(node) })
111
+ end
112
+ end
113
+
114
+ resources.compact
115
+ end
116
+
117
+ # Now looking for `op_asgn` nodes that represent `config.resources += [...]`
118
+ def find_resources_assignments(ast)
119
+ find_descendants(ast).select do |node|
120
+ node.type == :op_asgn && node.children[1] == :+
121
+ end
122
+ end
123
+
124
+ def extract_string(node)
125
+ return unless node.type == :str
126
+
127
+ node.children[0]
128
+ end
129
+
130
+ # Custom method to recursively find descendants in a generic AST node (Parser or RuboCop)
131
+ def find_descendants(node, &block)
132
+ return [] unless node.is_a?(Parser::AST::Node)
133
+
134
+ results = [node]
135
+ node.children.each do |child|
136
+ next unless child.is_a?(Parser::AST::Node)
137
+
138
+ results.concat(find_descendants(child, &block))
139
+ end
140
+ results
141
+ end
142
+ end
143
+ end
144
+ end
145
+ end
@@ -1,3 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "rhino_project/duplicate_rhino_references"
4
+ require_relative "rhino_project/owner_specified"
@@ -10,7 +10,7 @@ module RubocopRhinoProject
10
10
  MAJOR = 0
11
11
  MINOR = 21
12
12
  TINY = 0
13
- PRE = "beta.37"
13
+ PRE = "beta.39"
14
14
 
15
15
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
16
16
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop-rhino-project
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.21.0.beta.37
4
+ version: 0.21.0.beta.39
5
5
  platform: ruby
6
6
  authors:
7
7
  - JP Rosevear
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-10-11 00:00:00.000000000 Z
11
+ date: 2024-10-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -24,20 +24,6 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 4.2.0
27
- - !ruby/object:Gem::Dependency
28
- name: rack
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: '1.1'
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ">="
39
- - !ruby/object:Gem::Version
40
- version: '1.1'
41
27
  - !ruby/object:Gem::Dependency
42
28
  name: rubocop
43
29
  requirement: !ruby/object:Gem::Requirement
@@ -78,6 +64,26 @@ dependencies:
78
64
  - - "<"
79
65
  - !ruby/object:Gem::Version
80
66
  version: '2.0'
67
+ - !ruby/object:Gem::Dependency
68
+ name: parser
69
+ requirement: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - "~>"
72
+ - !ruby/object:Gem::Version
73
+ version: 3.3.5.0
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: 3.3.5.0
77
+ type: :runtime
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - "~>"
82
+ - !ruby/object:Gem::Version
83
+ version: 3.3.5.0
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ version: 3.3.5.0
81
87
  description: ''
82
88
  email:
83
89
  - jp@codalio.com
@@ -88,6 +94,7 @@ files:
88
94
  - config/default.yml
89
95
  - lib/rubocop-rhino-project.rb
90
96
  - lib/rubocop/cop/rhino_project/duplicate_rhino_references.rb
97
+ - lib/rubocop/cop/rhino_project/owner_specified.rb
91
98
  - lib/rubocop/cop/rhino_project_cops.rb
92
99
  - lib/rubocop/rhino_project.rb
93
100
  - lib/rubocop/rhino_project/inject.rb