trains 0.0.8 → 0.0.10

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: be756e07f687c79e259385beb680f5749c54a880273be056ba83a717aa821887
4
- data.tar.gz: da3fc5403f7844919f9bfd3ac49ef37479e7f4149328e851d1b1e654353398af
3
+ metadata.gz: 706372a84f876f65aec9c638d6ad2c17dd6255f6dbc942bccbe1f0f81b86e069
4
+ data.tar.gz: 431b9033167ed91a657dd00ca806c16c1c3df454f74ec276eb7e79baf8407adf
5
5
  SHA512:
6
- metadata.gz: 3a389ed84aedba71b13061c4233389d3008bd895a532f506a9f492a6d6aaa54ae96708d27f0e4cba9269f1666ef8f614c5ebf467a8bbf70c63595b449e2bcc0f
7
- data.tar.gz: be28d384e28be094161bcdb28105a4bef9dd2d7f86978936f554bf699a205c1953a88bd1de071c1005f2ec4d5c54e91bf6ace9e20f7f917bc8204b46ced1a431
6
+ metadata.gz: a9b1de71a3735c43afee1f793ad0af94e9d8d7d0fced82023c3927d52e2821cf730b997ae7eeab53816208c11320ed4168c381d3d5fa18d0c1c8c8cb3f008006
7
+ data.tar.gz: c3eac1a413ece2f2ff937f642843aefb7188b63cd25c03d6f394a223b63a1ebb8c25c0a05e7d63c6c903d94687b2f59beb2eebed7b196c7f2e2405573a363075
@@ -49,7 +49,7 @@ module Trains
49
49
  def generate_models
50
50
  return get_models if File.exist?(File.join(@dir, 'db', 'schema.rb'))
51
51
 
52
- migrations = get_migrations
52
+ migrations = get_migrations.flatten.reject(&:nil?)
53
53
  Utils::MigrationTailor.stitch(migrations)
54
54
  end
55
55
 
@@ -5,6 +5,8 @@ module Trains
5
5
  # utility module to deal with parsing of arguments
6
6
  module Args
7
7
  def parse_args(node)
8
+ return if node.nil?
9
+
8
10
  case node.type
9
11
  when :hash
10
12
  parse_hash(node)
@@ -19,6 +21,8 @@ module Trains
19
21
 
20
22
  node.each_pair { |key, value| options[key.value] = parse_value(value) }
21
23
  rescue StandardError => e
24
+ puts 'Error boi'
25
+ puts e
22
26
  puts node.parent
23
27
  ensure
24
28
  return options
@@ -34,7 +38,13 @@ module Trains
34
38
  if node.method_name == :redirect
35
39
  { redirect: node.arguments.first.value }
36
40
  end
37
- else
41
+ # skipcq: RB-LI1006
42
+ when :true
43
+ true
44
+ # skipcq: RB-LI1006
45
+ when :false
46
+ false
47
+ when :sym, :str, :integer
38
48
  node.value
39
49
  end
40
50
  end
@@ -1,6 +1,14 @@
1
- module Logger
2
- def debug(log)
3
- puts '[DEBUG]:'.bold.blue
4
- pp log
1
+ # frozen_string_literal: true
2
+
3
+ module Trains
4
+ module Utils
5
+ # Module with logging basics
6
+ module Logger
7
+ def self.debug(log)
8
+ puts '[DEBUG]:'
9
+ # skipcq: RB-RB-LI1008
10
+ pp log
11
+ end
12
+ end
5
13
  end
6
14
  end
@@ -6,14 +6,14 @@ module Trains
6
6
 
7
7
  migrations.each do |mig|
8
8
  case mig.modifier
9
- when :create_table
9
+ when :create_table, :create_join_table
10
10
  models[mig.table_name] = {}
11
11
  models[mig.table_name] = Trains::DTO::Model.new(
12
12
  name: mig.table_name,
13
13
  fields: mig.fields,
14
14
  version: mig.version
15
15
  )
16
- when :add_column
16
+ when :add_column, :add_reference
17
17
  models[mig.table_name].fields.push(*mig.fields)
18
18
  when :remove_column
19
19
  column =
@@ -34,6 +34,9 @@ module Trains
34
34
 
35
35
  models[mig.table_name].fields << mig.fields.first
36
36
  end
37
+
38
+ rescue NoMethodError
39
+ next
37
40
  end
38
41
 
39
42
  models
@@ -1,3 +1,3 @@
1
1
  module Trains
2
- VERSION = '0.0.8'
2
+ VERSION = '0.0.10'.freeze
3
3
  end
@@ -4,19 +4,31 @@ module Trains
4
4
  module Visitor
5
5
  # Visitor that parses DB migration and associates them with Rails models
6
6
  class Migration < Base
7
- def_node_matcher :send_node?, '(send nil? ...)'
8
- attr_reader :is_migration, :model
7
+ include Utils::Args
9
8
 
9
+ def_node_matcher :send_node?, '(send nil? ...)'
10
+ attr_reader :is_migration, :model, :result
11
+
12
+ ALLOWED_METHOD_NAMES = %i[change up].freeze
13
+ ALLOWED_TABLE_MODIFIERS = %i[
14
+ create_table
15
+ create_join_table
16
+ change_table
17
+ safety_assured
18
+ update_column
19
+ ].freeze
20
+ COLUMN_MODIFIERS = %i[
21
+ add_column
22
+ change_column
23
+ add_reference
24
+ remove_column
25
+ ].freeze
26
+
27
+ # skipcq: RB-LI1087
10
28
  def initialize
11
- @model = nil
12
- @table_modifier = nil
13
- @table_name = nil
14
- @is_class = false
15
- @is_migration = false
16
- @class_name = nil
17
- @fields = []
18
-
19
- @scope = { class: nil, method: nil, send: nil }
29
+ @result = []
30
+ @migration_class = nil
31
+ @migration_version = nil
20
32
  end
21
33
 
22
34
  def on_class(node)
@@ -27,16 +39,12 @@ module Trains
27
39
  @migration_class = node.children.first.source
28
40
  @migration_version = extract_version(node.parent_class.source)
29
41
 
30
- process_node(node.body)
31
- end
42
+ node.each_descendant(:def) do |child_node|
43
+ next if child_node.body.nil?
44
+ next unless ALLOWED_METHOD_NAMES.include?(child_node.method_name)
32
45
 
33
- def result
34
- DTO::Migration.new(
35
- table_name: @table_name,
36
- modifier: @table_modifier,
37
- fields: @fields,
38
- version: @migration_version
39
- )
46
+ process_migration(child_node)
47
+ end
40
48
  end
41
49
 
42
50
  private
@@ -48,75 +56,140 @@ module Trains
48
56
  match.to_s.to_f
49
57
  end
50
58
 
51
- def process_node(node)
52
- return unless node.def_type?
59
+ def process_migration(node)
60
+ case node.body.type
61
+ when :send
62
+ @result << parse_one_liner_migration(node.body)
63
+ when :begin
64
+ if node.body.children.map(&:type).include?(:block)
65
+ migration = parse_block_migration(node.body)
66
+ @result = [*@result, *migration] if migration
67
+ else
68
+ node.body.each_descendant(:send) do |send_node|
69
+ migration = parse_one_liner_migration(send_node)
70
+ @result << migration if migration
71
+ end
72
+ end
73
+ when :block
74
+ @result = [*@result, *parse_block_migration(node)]
75
+ when :if, :until
76
+ puts "Using unsupported logic within Rails migration: #{node.body.type}"
77
+ else
78
+ puts "[process_migration]: Unable to parse the following node:"
79
+ # skipcq: RB-RB-LI1008
80
+ pp node
81
+ end
82
+ end
83
+
84
+ def parse_one_liner_migration(node)
85
+ return unless COLUMN_MODIFIERS.include?(node.method_name)
86
+
87
+ arguments = node.arguments
88
+ table_name = arguments[0].value.to_s.singularize.camelize
89
+ column_name = arguments[1].value
90
+
91
+ if node.method_name == :add_reference
92
+ type = :bigint
93
+ column_name = "#{arguments[1].value}_id".to_sym
94
+ else
95
+ type = arguments[2].value unless node.method_name == :remove_column
96
+ end
53
97
 
54
- process_def_node(node)
98
+ DTO::Migration.new(
99
+ table_name,
100
+ node.method_name,
101
+ [DTO::Field.new(column_name, type)],
102
+ @migration_version
103
+ )
55
104
  end
56
105
 
57
- def process_def_node(node)
58
- allowed_method_names = %i[change up down]
59
- allowed_table_modifiers = %i[
60
- create_table
61
- change_table
62
- update_column
63
- add_column
64
- remove_column
65
- change_column
66
- add_index
67
- ]
68
- column_modifiers = %i[
69
- add_column
70
- change_column
71
- remove_column
72
- ]
73
-
74
- method_name = node.method_name
75
- return unless allowed_method_names.include? method_name
76
- return if node.body.nil?
77
-
78
- table_modifier =
79
- # if table modifier is a one-liner method call
80
- if node.body.children[0].nil?
81
- node.body.children[1]
82
- elsif node.body.children[0].block_type?
83
- # if table modifier is in a block
84
- node.body.children[0].method_name
85
- elsif node.body.children[0].send_type?
86
- node.body.children[0].method_name
87
- end
88
- return unless allowed_table_modifiers.include? table_modifier
106
+ def parse_block_migration(node)
107
+ migrations = []
108
+ # Visit every send_node that performs DDL tasks
109
+ node.children.each do |ddl_node|
110
+ next if ddl_node.is_a?(Symbol)
111
+
112
+ fields = []
113
+ if ddl_node.is_a?(RuboCop::AST::BlockNode)
114
+ next unless ALLOWED_TABLE_MODIFIERS.include?(ddl_node.method_name)
89
115
 
90
- @table_modifier = table_modifier
116
+ if ddl_node.method_name == :safety_assured
117
+ ddl_node.each_descendant(:send) do |send_node|
118
+ migrations = [*migrations,
119
+ *parse_one_liner_migration(send_node)]
120
+ end
91
121
 
92
- node.each_descendant(:send) do |send_node|
93
- if allowed_table_modifiers.include?(send_node.method_name)
94
- raw_table_name = send_node.arguments[0]
95
- @table_name = raw_table_name.value.to_s.singularize.camelize
96
- if column_modifiers.include?(send_node.method_name)
97
- @fields.append(DTO::Field.new(send_node.arguments[1].value,
98
- send_node.arguments[2]&.value))
122
+ next
99
123
  end
100
124
 
101
- next
102
- end
125
+ table_name = ddl_node.send_node.arguments[0].value.to_s.singularize.camelize
126
+ case ddl_node.method_name
127
+ when :create_join_table
128
+ field_one = ddl_node.send_node.arguments[0].value.to_s
129
+ field_two = ddl_node.send_node.arguments[1].value.to_s
130
+
131
+ table_name = field_one.camelize + field_two.camelize
132
+
133
+ fields << DTO::Field.new("#{field_one.singularize}_id".to_sym,
134
+ :bigint)
135
+ fields << DTO::Field.new("#{field_two.singularize}_id".to_sym,
136
+ :bigint)
137
+ when :create_table
138
+ fields << DTO::Field.new(:id, :bigint)
139
+ end
103
140
 
104
- next if allowed_table_modifiers.include?(send_node.method_name)
141
+ ddl_node.body.each_descendant(:send) do |send_node|
142
+ fields = [*fields, *parse_migration_field(send_node)]
143
+ end
105
144
 
106
- parse_migration_field(send_node)
145
+ migrations << DTO::Migration.new(
146
+ table_name,
147
+ ddl_node.method_name,
148
+ fields,
149
+ @migration_version
150
+ )
151
+ elsif ddl_node.is_a?(RuboCop::AST::SendNode)
152
+ migrations = [*migrations, *parse_one_liner_migration(ddl_node)]
153
+ end
107
154
  end
155
+
156
+ migrations
108
157
  end
109
158
 
110
159
  def parse_migration_field(node)
160
+ fields = []
161
+ # t.timestamps
111
162
  if node.children[1] == :timestamps
112
- @fields.append(DTO::Field.new(:created_at, :datetime))
113
- @fields.append(DTO::Field.new(:updated_at, :datetime))
114
- return
163
+ fields << DTO::Field.new(:created_at, :datetime)
164
+ fields << DTO::Field.new(:updated_at, :datetime)
165
+ return fields
166
+ end
167
+
168
+ return [] if node.arguments.nil? || node.arguments.empty?
169
+
170
+ # method used to create the column
171
+ # string is the col_method in t.string
172
+ col_method = node.children[1]
173
+ case col_method
174
+ when :column
175
+ # t.column col_name, col_type
176
+ type = node.children[3].value
177
+ value = node.children[2].value
178
+ fields << DTO::Field.new(value, type)
179
+ when :references, :belongs_to
180
+ # t.references
181
+ type = :bigint
182
+ value = "#{node.children[2].value}_id".to_sym
183
+ fields << DTO::Field.new(value, type)
184
+ when :index
185
+ else
186
+ # t.string, t.integer etc.
187
+ type = node.children[1]
188
+ value = parse_args(node.children[2])
189
+ fields << DTO::Field.new(value, type)
115
190
  end
116
191
 
117
- type = node.children[1]
118
- value = node.children[2].value unless node.children[2].hash_type?
119
- @fields.append(DTO::Field.new(value, type))
192
+ fields
120
193
  end
121
194
  end
122
195
  end
@@ -36,7 +36,6 @@ module Trains
36
36
  end
37
37
  end
38
38
  end
39
-
40
39
  end
41
40
 
42
41
  private
@@ -48,7 +47,7 @@ module Trains
48
47
  when :sym, :str
49
48
  node.arguments[0].value
50
49
  end
51
- options = parse_hash(node.arguments[1])
50
+ options = parse_args(node.arguments[1]) || {}
52
51
  DTO::Route.new(method:, param:, options:)
53
52
  end
54
53
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: trains
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.8
4
+ version: 0.0.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Syed Faraaz Ahmad
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-05-23 00:00:00.000000000 Z
11
+ date: 2023-06-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport