trains 0.0.8 → 0.0.10

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
  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