momocop 0.1.4 → 0.1.6

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: d7bbeea4b66a57e0dd2768cd593c653501cc745e73439d254dfa6ff56d26ad7a
4
- data.tar.gz: 3181561d6c590050106bcf13a1c6b6cec2f22179e2b1c8bcbb5b126630fd27d5
3
+ metadata.gz: 583e60d7747c3d18b2e39a5fe6d2f4cb4a02d9484ee21d49c3b6e06381c7db1a
4
+ data.tar.gz: 72139ae77375a441a56925c906be69d34993c867a3a23337dde3f7e47e257b31
5
5
  SHA512:
6
- metadata.gz: 19113cb5c6945b125d1688553deb24933b111ebe9d43521212fad4b38ca495676635c3047250e07a8a4b784c68f4d9b51a76ae8b0f56a167f5dc60d60939a78d
7
- data.tar.gz: c9841b2375bdd3e81682e73da8dd42f45174de77c27c265b10e7a7f7750bd8424c804bb2bea1e3f02f287d52926cd4895670988dac7d19f6d3b5d72c6a3a7314
6
+ metadata.gz: e0fb80f1fa23509e2ace6883efd371d3aeffac8f8472f484b8e797ba2ce1347518e2b124da72116fffe86ad82610a1d7e9af557da0cc04666bc214e4228d7248
7
+ data.tar.gz: 125d23305c4a085e35a0f3785f5b5f3f6cb00c4cfbeb44063e838ea5138b755e3d8b183a813c2776ddd56bf566cf682081bde359fc4e5c713d28459494b124e1
data/.rubocop.yml CHANGED
@@ -41,6 +41,10 @@ Security:
41
41
  Style:
42
42
  Enabled: true
43
43
 
44
+ Style/BlockDelimiters:
45
+ EnforcedStyle: semantic
46
+ AllowBracesOnProceduralOneLiners: false
47
+
44
48
  Style/Documentation:
45
49
  Enabled: false
46
50
 
@@ -49,6 +53,9 @@ Style/FrozenStringLiteralComment:
49
53
  EnforcedStyle: always_true
50
54
  SafeAutoCorrect: true
51
55
 
56
+ Style/IfUnlessModifier:
57
+ Enabled: false
58
+
52
59
  Style/RequireOrder:
53
60
  Enabled: true
54
61
  SafeAutoCorrect: true
@@ -22,9 +22,23 @@ module Momocop
22
22
  end
23
23
 
24
24
  private def extract_associations(node, associations = [])
25
- if node.type == :send && ASSOCIATION_METHODS.include?(node.children[1])
26
- association_name = node.children[2].type == :sym ? node.children[2].children[0] : node.children[2]
27
- associations << { type: node.children[1], name: association_name }
25
+ association_type = node.children[1]
26
+ options = {}
27
+ if node.type == :send && ASSOCIATION_METHODS.include?(association_type)
28
+ association_name = node.children[2].children[0].to_sym
29
+
30
+ # Extract some options
31
+ if association_type == :belongs_to
32
+ option_hash = node.children[3]
33
+ option_hash&.children&.each do |option|
34
+ key_node, value_node = option.children
35
+ if value_node.type == :sym || value_node.type == :str
36
+ options[key_node.children[0]] = value_node.children[0]
37
+ end
38
+ end
39
+ end
40
+
41
+ associations << { type: association_type, name: association_name, options: }
28
42
  elsif node.children.is_a? Array
29
43
  node.children.each do |child|
30
44
  extract_associations(child, associations) if child.is_a? Parser::AST::Node
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Momocop
4
- VERSION = '0.1.4'
4
+ VERSION = '0.1.6'
5
5
  end
@@ -49,11 +49,24 @@ module RuboCop
49
49
  block_node = node.block_node
50
50
 
51
51
  # Check missing associations
52
+
53
+ # Exclude defined sequences
52
54
  defined_sequences = get_defined_sequence_names(block_node)
55
+ # Exclude defined properties
53
56
  defined_properties = get_defined_property_names(block_node)
57
+ # Exclude foreign keys
58
+ model_foreign_keys = get_model_foreign_key_column_names(class_name)
59
+ # All available properties
54
60
  model_properties = get_model_property_names(class_name)
61
+ # Calc missing properties
62
+ missing_properties = (
63
+ model_properties -
64
+ (defined_sequences + defined_properties) -
65
+ model_foreign_keys
66
+ ).sort
67
+
68
+ # for definition block generation
55
69
  model_enum_properties = get_model_enum_property_names(class_name)
56
- missing_properties = (model_properties - (defined_sequences + defined_properties)).sort
57
70
 
58
71
  # Add offense for missing properties
59
72
  return unless missing_properties.any?
@@ -101,8 +114,31 @@ module RuboCop
101
114
  return [] unless source
102
115
 
103
116
  extractor = ::Momocop::EnumExtractor.new
117
+ enums = extractor.extract(source)
118
+ return enums.map(&:to_sym)
119
+ end
120
+
121
+ private def get_model_foreign_key_column_names(class_name)
122
+ source = model_file_source(class_name)
123
+ return [] unless source
124
+
125
+ extractor = ::Momocop::AssociationExtractor.new
104
126
  associations = extractor.extract(source)
105
- return associations.map(&:to_sym)
127
+ foreign_key_names =
128
+ associations
129
+ .select { _1[:type] == :belongs_to }
130
+ .map { |association|
131
+ options = association[:options]
132
+ if options[:foreign_key]
133
+ options[:foreign_key]
134
+ elsif options[:class_name]
135
+ foreign_key_name(options[:class_name])
136
+ else
137
+ "#{association[:name]}_id"
138
+ end
139
+ }
140
+ .compact
141
+ return foreign_key_names.map(&:to_sym)
106
142
  end
107
143
 
108
144
  RESTRICTED_COLUMNS = %w[created_at updated_at].freeze
@@ -123,6 +159,14 @@ module RuboCop
123
159
  class_name.tableize.gsub('/', '_')
124
160
  end
125
161
 
162
+ # e.g.)
163
+ # 'User' -> ['users']
164
+ # 'Admin::User' -> ['admin_users', 'users']
165
+ private def foreign_key_name(class_name)
166
+ # TODO: parse model class file and try to get table_name_prefix and table_name_suffix
167
+ "#{class_name.underscore.gsub('/', '_')}_id"
168
+ end
169
+
126
170
  private def get_defined_sequence_names(block_node)
127
171
  body_node = block_node&.children&.last
128
172
  return [] unless body_node
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: momocop
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - supermomonga