ead 0.2.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
  SHA256:
3
- metadata.gz: d3b8b4dac74bd298fe1030da9c00bd04c1badb639de8ae1777f2ca8b98895381
4
- data.tar.gz: bad574c55817b25d32b11307a7d867e3c503a7b768bf02e8f75ec5d4ec2a15b7
3
+ metadata.gz: b0246f506ee0396b4da7f7dfd2cd58b856893a05148b593f999b7f0a704cb0f5
4
+ data.tar.gz: dd5e95c1b53959a0762c667d66913a60c3b222ec237d9a40c1931371a13e65bf
5
5
  SHA512:
6
- metadata.gz: a9cbd8d53a5fef880146af795e76efae5505b26649d7138cd846f169f6f4cdfbac6542f053335f87cbeb5bc67e443b859b783f4b7accf9f2d876b7267955bd07
7
- data.tar.gz: 3156c9c4990b013217e9d365d8f65bc80c6da3923bbab06c345bebcbd6dde5f2afd2841e050be3d6f82caa996ff002aec425e7f3670101a69ba24e6f8787770b
6
+ metadata.gz: fa2bb67008c2de407ce152432cfee9a0ea5f8cdb222d2e89a8f28ca79d690970ca4200d9ae52f6150a5f7df7ec14ae7b2169abd83d8a6e6388058862c0bb3b6d
7
+ data.tar.gz: e269830ca88205dc5f2fe681574d7fe9b634c1fb76519651a6344083ca48003dd1ae79384b2e06d4313c77762d14e5e52ed52954aef8871f47e665c594bdc115
data/lib/association.rb CHANGED
@@ -1,27 +1,114 @@
1
- require 'item'
1
+ require 'table'
2
2
 
3
3
  class Association
4
- attr_accessor :first_item, :second_items, :name
5
-
6
- def initialize(first_item, association_block)
7
- @first_item = first_item
8
- @second_items = []
9
- add_second_items(association_block)
10
- @name = association_block.content
11
- end
12
-
13
- def add_second_items(block)
14
- block.sub_blocks.each do |sub_block|
15
- if sub_block.entity
16
- second_items << Item.new(sub_block, first_item, self)
17
- elsif sub_block.entity_clone
18
- second_items << ItemClone.new(sub_block, first_item, self)
19
- elsif sub_block.entity_container
20
- add_second_items(sub_block)
4
+ attr_accessor :first_entity, :second_entity, :name, :middle_entities_has_one, :middle_entities_has_many,
5
+ :through_entity
6
+
7
+ # first_entity, association_block)
8
+ def initialize(edge)
9
+ @first_entity = Entity.find(edge['source'])
10
+ @second_entity = Entity.find(edge['target'])
11
+ @through_entity = nil
12
+
13
+ @middle_entities_has_one = []
14
+ @middle_entities_has_many = []
15
+
16
+ @first_entity.associations << self
17
+ @second_entity.parent_associations << self
18
+
19
+ @name = nil
20
+ case edge['type']
21
+ when 'hasMany'
22
+ @first_entity.children_has_many << @second_entity
23
+ @second_entity.parents_has_many << @first_entity
24
+
25
+ @name = 'has_many'
26
+ when 'hasOne'
27
+ @first_entity.children_has_one << @second_entity
28
+ @second_entity.parents_has_one << @first_entity
29
+
30
+ @name = 'has_one'
31
+ when 'through'
32
+ @first_entity.children_through << @second_entity
33
+ @second_entity.parents_through << @first_entity
34
+
35
+ @through_entity = Entity.find(edge['data']['throughNodeId'])
36
+
37
+ @name = ':through'
38
+ end
39
+ end
40
+
41
+ def self.check_middle_entities_include(entity)
42
+ associations = Association.all.select { |association| association.through_entity == entity }
43
+ associations.each do |association|
44
+ unless (association.middle_entities_has_many.include? entity) || (association.middle_entities_has_one.include? entity)
45
+ association.set_middle_entity
21
46
  end
22
47
  end
23
48
  end
24
49
 
50
+ def set_middle_entity
51
+ source = first_entity
52
+ target = second_entity
53
+
54
+ if (
55
+ source.parents_has_many +
56
+ source.parents_has_many_through +
57
+ source.parents_has_one +
58
+ source.parents_has_one_through +
59
+ source.children_has_many +
60
+ source.children_has_many_through +
61
+ source.children_has_one +
62
+ source.children_has_one_through
63
+ ).include?(through_entity) &&
64
+ (
65
+ (
66
+ target.parents_has_many +
67
+ target.parents_has_many_through +
68
+ target.parents_has_one +
69
+ target.parents_has_one_through +
70
+ target.children_has_many +
71
+ target.children_has_many_through +
72
+ target.children_has_one +
73
+ target.children_has_one_through
74
+ ).include?(through_entity) || (
75
+ through_entity.parents_has_many.map(&:clone_parent).include?(target.clone_parent) ||
76
+ through_entity.parents_has_one.map(&:clone_parent).include?(target.clone_parent)
77
+ )
78
+ )
79
+
80
+ if (
81
+ source.children_has_many.include?(through_entity) ||
82
+ source.children_has_many_through.include?(through_entity)
83
+ ) || (
84
+ target.parents_has_many.include?(through_entity) ||
85
+ target.parents_has_many_through.include?(through_entity)
86
+ )
87
+
88
+ unless middle_entities_has_many.include? through_entity
89
+ middle_entities_has_many << through_entity
90
+ source.children_has_many_through << target
91
+ target.parents_has_many_through << source
92
+ Association.check_middle_entities_include(target)
93
+ end
94
+ else
95
+ unless middle_entities_has_one.include? through_entity
96
+ middle_entities_has_one << through_entity
97
+ source.children_has_one_through << target
98
+ target.parents_has_one_through << source
99
+ Association.check_middle_entities_include(target)
100
+ end
101
+ end
102
+
103
+ end
104
+ end
105
+
106
+ def self.set_middle_entities
107
+ associations = all.select(&:through?)
108
+
109
+ associations.each(&:set_middle_entity)
110
+ end
111
+
25
112
  def has_many?
26
113
  name == 'has_many'
27
114
  end
data/lib/attribute.rb CHANGED
@@ -1,9 +1,9 @@
1
1
  class Attribute
2
2
  attr_accessor :name, :type
3
3
 
4
- def initialize(name, type)
5
- @name = name
6
- @type = type
4
+ def initialize(attribute)
5
+ @name = attribute['name']
6
+ @type = attribute['type']
7
7
  end
8
8
 
9
9
  def add_to(command)
data/lib/ead.rb CHANGED
@@ -1,61 +1,92 @@
1
1
  require 'json'
2
- require 'item'
3
- require 'item_clone'
4
- require 'block'
2
+ require 'table'
3
+ require 'entity'
4
+ require 'rest-client'
5
5
 
6
6
  class EAD
7
7
  def import_JSON(user_arguments)
8
8
  file = File.read(user_arguments[0] || './EAD.json')
9
- items = JSON.parse(file)
10
- ead_id = '9'
11
- Block.new(ead_id, items)
12
- Block.all.each do |block|
13
- next unless block.cloneable
14
-
15
- block.clone_blocks.map! do |id|
16
- Block.find(id.to_s)
17
- end
9
+
10
+ unless ['0.4.0'].include? JSON.parse(file)['version']
11
+ puts "\n\n----------------"
12
+ puts "\e[31m#{
13
+ 'Versions of your EAD file and the gem are not compatible.'\
14
+ ' So, you may have some unexpected results.'\
15
+ 'To run your EAD file correctly, please run'
16
+ }\e[0m"
17
+
18
+ puts "\e[31m#{
19
+ "\ngem install ead -v #{JSON.parse(file)['version']}"
20
+ }\e[0m"
21
+ puts "----------------\n\n"
22
+
23
+ raise StandardError, msg = 'Incompatible version'
18
24
  end
25
+
26
+ file
19
27
  end
20
28
 
21
- def create_items(block)
22
- block.sub_blocks.each do |sub_block|
23
- if sub_block.entity
24
- Item.new(sub_block)
25
- elsif sub_block.entity_clone
26
- ItemClone.new(sub_block)
27
- elsif sub_block.entity_container
28
- create_items(sub_block)
29
- end
29
+ def create_objects(file)
30
+ @nodes = JSON.parse(file)['nodes']
31
+ @edges = JSON.parse(file)['edges']
32
+ @tables = JSON.parse(file)['tables']
33
+
34
+ @tables = @tables.map do |(id)|
35
+ Table.new(id, @tables)
30
36
  end
31
- end
32
37
 
33
- def check_implement_items
34
- ead_id = '9'
35
- block = Block.find(ead_id)
36
- create_items(block)
38
+ @nodes.map! do |node|
39
+ Entity.new(node)
40
+ end
37
41
 
38
- ItemClone.all.each do |item_clone|
39
- parent = Item.find(item_clone.clone_parent)
40
- item_clone.clone_parent = Item.find(item_clone.clone_parent)
41
- parent.clones << item_clone
42
+ @edges.map! do |edge|
43
+ Association.new(edge)
42
44
  end
45
+ end
43
46
 
44
- Item.all.reverse.each do |item|
45
- item.create_migration
47
+ def check_implement_objects(file)
48
+ create_objects(file)
49
+
50
+ Entity.all.each do |entity|
51
+ entity.clone_parent.entities << entity
46
52
  end
47
53
 
48
- Item.all.reverse.each do |item|
49
- item.add_associations
54
+ Table.all.each(&:create_model)
55
+
56
+ Table.all.each(&:add_reference_migration)
57
+
58
+ Association.set_middle_entities
59
+
60
+ Association.all.each do |association|
61
+ association.first_entity.update_model(association.second_entity, association)
50
62
  end
63
+ end
64
+
65
+ def check_latest_version
66
+ response = JSON.parse RestClient.get 'https://api.github.com/repos/ozovalihasan/ead/tags'
51
67
 
52
- ItemClone.all.reverse.each do |item_clone|
53
- item_clone.add_associations
68
+ unless response.first['name'] == 'v0.4.0'
69
+ puts "\n\n----------------"
70
+ puts "\n\e[33m#{
71
+ 'A new version of this gem has been released.'\
72
+ ' Please check it. https://github.com/ozovalihasan/ead-g/releases'
73
+ }\e[0m"
74
+
75
+ puts "\n----------------\n\n"
54
76
  end
77
+ rescue StandardError
78
+ puts "\n\n----------------"
79
+ puts "\n\e[31m#{
80
+ 'If you want to check the latest version of this gem,'\
81
+ ' you need to have a stable internet connection.'
82
+ }\e[0m"
83
+
84
+ puts "\n----------------\n\n"
55
85
  end
56
86
 
57
87
  def start(user_arguments)
58
- import_JSON(user_arguments)
59
- check_implement_items
88
+ check_latest_version
89
+ file = import_JSON(user_arguments)
90
+ check_implement_objects(file)
60
91
  end
61
92
  end
data/lib/entity.rb ADDED
@@ -0,0 +1,145 @@
1
+ require 'table_entity_base'
2
+ require 'association'
3
+ require 'project_file'
4
+
5
+ class Entity < TableEntityBase
6
+ attr_accessor(:name, :id, :twin_name, :clone_parent, :parent, :parent_association, :associations, :parent_associations,
7
+ :parents_has_one, :parents_has_many, :parents_through, :children_has_one, :children_has_many, :children_through,
8
+ :children_has_one_through, :children_has_many_through, :parents_has_one_through, :parents_has_many_through)
9
+
10
+ def initialize(node)
11
+ @id = node['id']
12
+ @name = node['data']['name'].split(' || ')[0].underscore.singularize
13
+ @twin_name = node['data']['name'].split(' || ')[1]&.underscore&.singularize
14
+ @clone_parent = Table.find(node['data']['tableId'])
15
+
16
+ @parent_associations = []
17
+ @associations = []
18
+
19
+ @parents_has_one = []
20
+ @parents_has_many = []
21
+ @parents_has_one_through = []
22
+ @parents_has_many_through = []
23
+ @parents_through = []
24
+
25
+ @children_has_one = []
26
+ @children_has_many = []
27
+ @children_has_one_through = []
28
+ @children_has_many_through = []
29
+ @children_through = []
30
+ end
31
+
32
+ def model_name
33
+ clone_parent.name.camelize
34
+ end
35
+
36
+ def tables_same?(entity)
37
+ table == entity.table
38
+ end
39
+
40
+ def self.find_by_name(name)
41
+ all.find { |entity| entity.name == name }
42
+ end
43
+
44
+ def clone_name_different?
45
+ clone_parent.name != name
46
+ end
47
+
48
+ def one_polymorphic_names?(entity)
49
+ table.polymorphic && table.polymorphic_names.include?(entity.name)
50
+ end
51
+
52
+ def table
53
+ clone_parent
54
+ end
55
+
56
+ def update_end_model_migration_files(start_entity, association)
57
+ polymorphic_end = one_polymorphic_names?(start_entity)
58
+
59
+ return if polymorphic_end
60
+
61
+ end_model_line = {}
62
+ end_migration_line = {}
63
+
64
+ if association.has_any?
65
+ end_model_line['belongs_to'] = ":#{start_entity.name}"
66
+
67
+ if tables_same?(start_entity)
68
+ end_model_line['optional'] = 'true'
69
+ end_migration_line['null'] = 'true'
70
+ else
71
+ end_migration_line['null'] = 'false'
72
+ end
73
+
74
+ if !polymorphic_end && start_entity.clone_name_different?
75
+ end_model_line['class_name'] = "\"#{start_entity.clone_parent.name.camelize}\""
76
+ end_migration_line['foreign_key'] = "{ to_table: :#{start_entity.clone_parent.name.pluralize} }"
77
+ end
78
+ end
79
+
80
+ ProjectFile.add_belong_line(clone_parent.name, end_model_line) unless end_model_line.empty?
81
+
82
+ unless end_migration_line.empty?
83
+ migration_name = "Add#{start_entity.name.camelize}RefTo#{clone_parent.name.camelize}".underscore
84
+
85
+ ProjectFile.update_line(migration_name, 'reference_migration', /add_reference :#{clone_parent.name.pluralize}/,
86
+ end_migration_line)
87
+ end
88
+ end
89
+
90
+ def update_start_model_file(end_entity, association)
91
+ start_model = table.name
92
+
93
+ end_model = end_entity.name
94
+ intermediate_entity = association.through_entity
95
+
96
+ intermediate_model = intermediate_entity.name if intermediate_entity
97
+
98
+ if association.has_many? || (children_has_many_through.include? end_entity)
99
+ end_model = end_model.pluralize
100
+ intermediate_model = intermediate_model.pluralize if intermediate_model
101
+ end
102
+
103
+ line_content = {}
104
+
105
+ if association.has_many? || (children_has_many_through.include? end_entity)
106
+ line_content['has_many'] = if intermediate_entity&.one_polymorphic_names?(end_entity) && (association.has_many? || (children_has_many_through.include? end_entity))
107
+ ":#{end_entity.table.name.pluralize}"
108
+ else
109
+ ":#{end_model}"
110
+ end
111
+ end
112
+
113
+ if association.has_one? || (children_has_one_through.include? end_entity)
114
+ line_content['has_one'] = if intermediate_entity&.one_polymorphic_names?(end_entity) && (association.has_one? || (children_has_one_through.include? end_entity))
115
+ ":#{end_entity.table.name}"
116
+ else
117
+ ":#{end_model}"
118
+ end
119
+ end
120
+
121
+ if intermediate_entity
122
+ line_content['through'] = ":#{intermediate_model}"
123
+ if intermediate_entity.one_polymorphic_names?(end_entity)
124
+ line_content['source'] = ":#{end_entity.name}"
125
+ line_content['source_type'] = "\"#{end_entity.table.name.camelize}\" "
126
+ end
127
+ elsif !intermediate_entity
128
+ line_content['class_name'] = "\"#{end_entity.table.name.camelize}\"" if end_entity.clone_name_different?
129
+
130
+ if end_entity.one_polymorphic_names?(self)
131
+ line_content['as'] = ":#{name}"
132
+ elsif clone_name_different?
133
+ line_content['foreign_key'] = "\"#{name.singularize}_id\""
134
+ end
135
+ end
136
+
137
+ ProjectFile.add_line(start_model, end_model, line_content)
138
+ end
139
+
140
+ def update_model(end_entity, association)
141
+ end_entity.update_end_model_migration_files(self, association) if association.has_any?
142
+
143
+ update_start_model_file(end_entity, association)
144
+ end
145
+ end
data/lib/project_file.rb CHANGED
@@ -1,3 +1,5 @@
1
+ require 'fileutils'
2
+
1
3
  class ProjectFile
2
4
  def self.open_close(name, type, &block)
3
5
  case type
@@ -7,8 +9,10 @@ class ProjectFile
7
9
  when 'model'
8
10
  tempfile_name = './app/models/model_update.rb'
9
11
  file_name = "./app/models/#{name}.rb"
12
+ when 'reference_migration'
13
+ tempfile_name = './db/migrate/migration_update.rb'
14
+ file_name = Dir.glob("./db/migrate/*_#{name}.rb").first
10
15
  end
11
-
12
16
  tempfile = File.open(tempfile_name, 'w')
13
17
  file = File.new(file_name)
14
18
 
@@ -27,10 +31,10 @@ class ProjectFile
27
31
  open_close(name, type) do |file, tempfile|
28
32
  file.each do |line|
29
33
  if line.match(keywords)
30
- line.gsub!("\n", ' ')
34
+ line.gsub!(/ *\n/, '')
31
35
  line_content.each do |key, value|
32
36
  if line.include? key
33
- line.gsub!(/#{key}: .*([, ])/, "#{key}: #{value}#{Regexp.last_match(1)}")
37
+ line.gsub!(/#{key}: [^(\s,)]*/, "#{key}: #{value}#{Regexp.last_match(1)}")
34
38
  else
35
39
  line << ", #{key}: #{value}"
36
40
  end
@@ -65,4 +69,27 @@ class ProjectFile
65
69
  end
66
70
  end
67
71
  end
72
+
73
+ def self.add_belong_line(name, line_content)
74
+ open_close(name, 'model') do |file, tempfile|
75
+ line_found = false
76
+ file.each do |line|
77
+ tempfile << line
78
+ next unless line.include?('class') && !line_found
79
+
80
+ line_found = true
81
+ line_association = ''
82
+ line_content.each do |key, value|
83
+ line_association << if %w[belongs_to].include?(key)
84
+ " #{key} #{value}"
85
+ else
86
+ ", #{key}: #{value}"
87
+ end
88
+ end
89
+
90
+ line_association << "\n"
91
+ tempfile << line_association
92
+ end
93
+ end
94
+ end
68
95
  end
data/lib/table.rb ADDED
@@ -0,0 +1,88 @@
1
+ require 'table_entity_base'
2
+ require 'attribute'
3
+ require 'association'
4
+ require 'active_support/core_ext/string'
5
+
6
+ class Table < TableEntityBase
7
+ attr_accessor :name, :id, :twin_name, :attributes, :entities, :polymorphic, :polymorphic_names
8
+
9
+ def initialize(table_id, tables)
10
+ @id = table_id
11
+ @name = tables[table_id]['name'].split(' || ')[0].underscore.singularize
12
+ @entities = []
13
+ @polymorphic = false
14
+ @polymorphic_names = []
15
+ @attributes = []
16
+ tables[table_id]['attributes'].each do |(_attribute_id, attribute)|
17
+ @attributes << Attribute.new(attribute)
18
+ end
19
+ end
20
+
21
+ def model_name
22
+ name.camelize
23
+ end
24
+
25
+ def add_references(entity)
26
+ command = "bundle exec rails generate migration Add#{entity.name.camelize}RefTo#{name.camelize} #{entity.name}:references"
27
+
28
+ system(command)
29
+ end
30
+
31
+ def add_polymorphic_reference(command, poly_name)
32
+ command << " #{poly_name}:references{polymorphic}"
33
+ end
34
+
35
+ def update_polymorphic_names
36
+ return if entities.size.zero?
37
+
38
+ belong_parents = []
39
+ entities.each do |entity|
40
+ entity.parent_associations.each do |association|
41
+ belong_parents << association.first_entity
42
+ end
43
+ end
44
+
45
+ belong_parent_names = belong_parents.map(&:name)
46
+
47
+ filtered_parent_names = belong_parent_names.find_all do |parent_name|
48
+ belong_parent_names.count(parent_name) > 1
49
+ end.uniq
50
+
51
+ @polymorphic_names = filtered_parent_names.find_all do |parent_name|
52
+ belong_parents.find_all do |entity|
53
+ entity.name == parent_name
54
+ end.map(&:clone_parent).map(&:name).uniq.size > 1
55
+ end
56
+ end
57
+
58
+ def check_polymorphic(command)
59
+ update_polymorphic_names
60
+ @polymorphic_names.each do |poly_name|
61
+ add_polymorphic_reference(command, poly_name)
62
+ end
63
+
64
+ @polymorphic = true if @polymorphic_names.size.positive?
65
+ end
66
+
67
+ def create_model
68
+ return if File.exist?("./app/models/#{name}.rb")
69
+
70
+ command = 'bundle exec rails generate model '
71
+ command << model_name
72
+ attributes.each { |attribute| attribute.add_to(command) }
73
+
74
+ check_polymorphic(command)
75
+
76
+ system(command)
77
+ end
78
+
79
+ def add_reference_migration
80
+ entities.each do |entity|
81
+ (entity.parents_has_many + entity.parents_has_one).each do |parent|
82
+ next if entity.one_polymorphic_names?(parent)
83
+
84
+ add_references(parent)
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,9 @@
1
+ class TableEntityBase
2
+ def self.all
3
+ ObjectSpace.each_object(self).to_a
4
+ end
5
+
6
+ def self.find(id)
7
+ all.find { |base| base.id == id }
8
+ end
9
+ end
metadata CHANGED
@@ -1,15 +1,35 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ead
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hasan Ozovali
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-05-25 00:00:00.000000000 Z
11
+ date: 2022-09-05 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rest-client
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 2.0.2
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '2.0'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 2.0.2
13
33
  - !ruby/object:Gem::Dependency
14
34
  name: activesupport
15
35
  requirement: !ruby/object:Gem::Requirement
@@ -38,6 +58,20 @@ dependencies:
38
58
  - - "~>"
39
59
  - !ruby/object:Gem::Version
40
60
  version: '2.2'
61
+ - !ruby/object:Gem::Dependency
62
+ name: pry
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: 0.14.1
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: 0.14.1
41
75
  - !ruby/object:Gem::Dependency
42
76
  name: rspec
43
77
  requirement: !ruby/object:Gem::Requirement
@@ -77,16 +111,16 @@ files:
77
111
  - bin/ead
78
112
  - lib/association.rb
79
113
  - lib/attribute.rb
80
- - lib/block.rb
81
114
  - lib/ead.rb
82
- - lib/item.rb
83
- - lib/item_base.rb
84
- - lib/item_clone.rb
115
+ - lib/entity.rb
85
116
  - lib/project_file.rb
117
+ - lib/table.rb
118
+ - lib/table_entity_base.rb
86
119
  homepage: https://rubygems.org/gems/ead
87
120
  licenses:
88
121
  - MIT
89
- metadata: {}
122
+ metadata:
123
+ rubygems_mfa_required: 'true'
90
124
  post_install_message:
91
125
  rdoc_options: []
92
126
  require_paths:
@@ -102,7 +136,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
102
136
  - !ruby/object:Gem::Version
103
137
  version: '0'
104
138
  requirements: []
105
- rubygems_version: 3.1.4
139
+ rubygems_version: 3.3.7
106
140
  signing_key:
107
141
  specification_version: 4
108
142
  summary: Compiler for JSON files created by EAD
data/lib/block.rb DELETED
@@ -1,34 +0,0 @@
1
- class Block
2
- attr_accessor :id, :content, :category, :attribute_container, :attribute, :type, :association, :sub_blocks,
3
- :clone_blocks, :cloneable, :entity, :entity_clone, :clone_parent, :entity_container
4
-
5
- def initialize(id, items)
6
- item = items[id]
7
- @id = id
8
- @content = item['content']
9
- @category = item['category']
10
- @attribute_container = item['attributeContainer']
11
- @entity = item['entity']
12
- @entity_container = item['entityContainer']
13
- @attribute = item['attribute']
14
- @type = item['type']
15
- @association = item['association']
16
- @entity_clone = item['entityClone']
17
- @cloneable = item['cloneable']
18
- @clone_blocks = item['cloneChildren']
19
- @clone_parent = item['cloneParent'].to_s
20
- @sub_blocks = []
21
- item['subItemIds'].each do |sub_item_id|
22
- sub_item_id = sub_item_id.to_s
23
- @sub_blocks << Block.new(sub_item_id, items)
24
- end
25
- end
26
-
27
- def self.all
28
- ObjectSpace.each_object(self).to_a
29
- end
30
-
31
- def self.find(id)
32
- all.find { |block| block.id == id }
33
- end
34
- end
data/lib/item.rb DELETED
@@ -1,70 +0,0 @@
1
- require 'item_base'
2
- require 'attribute'
3
- require 'association'
4
- require 'active_support/core_ext/string'
5
-
6
- class Item < ItemBase
7
- attr_accessor :clones, :polymorphic, :polymorphic_names
8
-
9
- def initialize(block, parent = nil, parent_association = nil)
10
- super(block, parent, parent_association)
11
- @clones = []
12
- @polymorphic = false
13
- @polymorphic_names = []
14
- end
15
-
16
- def model_name
17
- name.camelize
18
- end
19
-
20
- def add_references(command, item)
21
- return if command.include? " #{item.name}:references"
22
-
23
- command << " #{item.name}:references"
24
- end
25
-
26
- def add_polymorphic(command, poly_name)
27
- command << " #{poly_name}:references{polymorphic}"
28
- end
29
-
30
- def update_polymorphic_names
31
- all_parents_name = [self, *clones].map do |item|
32
- [item.parent&.name, item.through_association && item.through_child.name]
33
- end
34
- all_parents_name.flatten!.compact!
35
- @polymorphic_names = all_parents_name.find_all { |name| all_parents_name.count(name) > 1 }.uniq
36
- end
37
-
38
- def check_polymorphic(command)
39
- update_polymorphic_names
40
- @polymorphic_names.each do |poly_name|
41
- add_polymorphic(command, poly_name)
42
- end
43
-
44
- @polymorphic = true if @polymorphic_names.size.positive?
45
- end
46
-
47
- def create_migration
48
- return if File.exist?("./app/models/#{name}.rb")
49
-
50
- command = 'bundle exec rails generate model '
51
- command << model_name
52
- attributes.each { |attribute| attribute.add_to(command) }
53
-
54
- check_polymorphic(command)
55
-
56
- [self, *clones].each do |item|
57
- if item.parent_has_many? && item.through_association
58
- item.through_child.create_migration if item.through_child.not_clone?
59
- add_references(command, item.through_child)
60
- end
61
-
62
- next unless item.parent && !item.one_polymorphic_names?(item.parent) && (
63
- item.parent_has_any? || item.parent_through_has_one?
64
- )
65
-
66
- add_references(command, item.parent)
67
- end
68
- system(command)
69
- end
70
- end
data/lib/item_base.rb DELETED
@@ -1,239 +0,0 @@
1
- require 'project_file'
2
-
3
- class ItemBase
4
- attr_accessor :name, :parent, :parent_association, :associations, :attributes, :id, :twin_name
5
-
6
- def initialize(block, parent = nil, parent_association = nil)
7
- @id = block.id
8
- @name = block.content.split(' || ')[0].underscore.singularize
9
- @twin_name = block.content.split(' || ')[1]&.underscore&.singularize
10
- @parent = parent
11
- @parent_association = parent_association
12
- @attributes = []
13
- @associations = []
14
- block.sub_blocks.each do |sub_block|
15
- if sub_block.attribute
16
- add_to_attributes(sub_block)
17
- elsif sub_block.attribute_container
18
- add_attribute_container(sub_block)
19
- elsif sub_block.association
20
- add_to_associations(sub_block)
21
- end
22
- end
23
- end
24
-
25
- def add_attribute_container(block)
26
- block.sub_blocks.each do |attribute|
27
- add_to_attributes(attribute)
28
- end
29
- end
30
-
31
- def add_to_attributes(block)
32
- @attributes << Attribute.new(block.content, block.type)
33
- end
34
-
35
- def add_to_associations(block)
36
- @associations << Association.new(self, block)
37
- end
38
-
39
- def grand
40
- parent.parent
41
- end
42
-
43
- def grand_association
44
- parent.parent_association
45
- end
46
-
47
- def grand_has_many?
48
- grand_association&.has_many?
49
- end
50
-
51
- def grand_has_one?
52
- grand_association&.has_one?
53
- end
54
-
55
- def grand_real_self_real?
56
- reals_same? grand
57
- end
58
-
59
- def reals_same?(item)
60
- real_item == item.real_item
61
- end
62
-
63
- def parent_through?
64
- parent_association&.through?
65
- end
66
-
67
- def parent_has_many?
68
- parent_association&.has_many?
69
- end
70
-
71
- def parent_has_one?
72
- parent_association&.has_one?
73
- end
74
-
75
- def parent_has_any?
76
- parent_has_one? || parent_has_many?
77
- end
78
-
79
- def parent_through_has_one?
80
- parent_through? && grand_has_one?
81
- end
82
-
83
- def parent_through_has_many?
84
- parent_through? && grand_has_many?
85
- end
86
-
87
- def through_association
88
- associations.find(&:through?)
89
- end
90
-
91
- def through_child
92
- through_association&.second_items&.first
93
- end
94
-
95
- def through?(item)
96
- item.present?
97
- end
98
-
99
- def clone_name_different?
100
- clone? && (clone_parent.name != name)
101
- end
102
-
103
- def one_polymorphic_names?(item)
104
- real_item.polymorphic && real_item.polymorphic_names.include?(item.name)
105
- end
106
-
107
- def clone?
108
- instance_of?(ItemClone)
109
- end
110
-
111
- def not_clone?
112
- !clone?
113
- end
114
-
115
- def real_item
116
- clone? ? clone_parent : self
117
- end
118
-
119
- def grand_many_through_reals_same?(item)
120
- parent_through_has_many? && (grand == item) && reals_same?(item)
121
- end
122
-
123
- def parent_has_many_reals_same_through_child?(item)
124
- item.parent_through_has_many? && (through_child == item) && item.reals_same?(parent)
125
- end
126
-
127
- def update_end_model_migration_files(start_item, association)
128
- polymorphic_end = one_polymorphic_names?(start_item)
129
-
130
- end_model_line = {}
131
- end_migration_line = {}
132
- if association.has_one? && start_item.parent&.reals_same?(self)
133
- end_model_line['optional'] = 'true'
134
- end_migration_line['null'] = 'true'
135
- end
136
-
137
- if association.has_any?
138
- if reals_same?(start_item)
139
- end_model_line['optional'] = 'true'
140
- end_migration_line['null'] = 'true'
141
- end
142
-
143
- if start_item.clone? && !polymorphic_end && start_item.clone_name_different?
144
- end_model_line['class_name'] = "\"#{start_item.clone_parent.name.camelize}\""
145
- end_migration_line['foreign_key'] = "{ to_table: :#{start_item.clone_parent.name.pluralize} }"
146
- end
147
- end
148
-
149
- ProjectFile.update_line(real_item.name, 'model', /belongs_to :#{start_item.name}/, end_model_line)
150
-
151
- migration_name = real_item.name
152
- ProjectFile.update_line(migration_name, 'migration', /t.references :#{start_item.name}/, end_migration_line)
153
- end
154
-
155
- def update_start_model_file(end_item, association, intermediate_item = nil)
156
- start_model = real_item.name
157
-
158
- end_model = if end_item.parent_has_many_reals_same_through_child?(self)
159
- end_item.twin_name
160
- else
161
- end_item.name
162
- end
163
-
164
- intermediate_model = if grand_many_through_reals_same?(end_item)
165
- intermediate_item.twin_name
166
- elsif intermediate_item
167
- intermediate_item.name
168
- end
169
-
170
- if association.has_many?
171
- end_model = end_model.pluralize
172
- intermediate_model = intermediate_model.pluralize if intermediate_model
173
- end
174
-
175
- line_content = {}
176
- line_content[association.name] = if intermediate_item&.one_polymorphic_names?(end_item) && association.has_many?
177
- ":#{end_item.real_item.name.pluralize}"
178
- else
179
- ":#{end_model}"
180
- end
181
-
182
- if intermediate_item
183
- line_content['through'] = ":#{intermediate_model}"
184
- if intermediate_item.one_polymorphic_names?(end_item)
185
- line_content['source'] = ":#{end_item.name}"
186
- line_content['source_type'] = "\"#{end_item.real_item.name.camelize}\" "
187
- end
188
- elsif !intermediate_item
189
- line_content['class_name'] = "\"#{end_item.real_item.name.camelize}\"" if end_item.clone_name_different?
190
-
191
- if end_item.one_polymorphic_names?(self)
192
- line_content['as'] = ":#{name}"
193
- elsif clone_name_different?
194
- line_content['foreign_key'] = "\"#{name.singularize}_id\""
195
- end
196
- end
197
-
198
- ProjectFile.add_line(start_model, end_model, line_content)
199
- end
200
-
201
- def update_model(end_item, association, intermediate_item = nil)
202
- return unless association.has_one? || association.has_many?
203
-
204
- end_item.update_end_model_migration_files(self, association) unless intermediate_item
205
- update_start_model_file(end_item, association, intermediate_item)
206
- end
207
-
208
- def parent_through_add_associations
209
- if parent_through_has_many?
210
- update_model(parent, grand_association)
211
- update_model(grand, grand_association, parent)
212
-
213
- elsif parent_through_has_one?
214
- parent.update_model(self, grand_association)
215
- end
216
-
217
- grand.update_model(self, grand_association, parent)
218
- end
219
-
220
- def add_associations
221
- parent_through_add_associations if parent_through?
222
-
223
- associations.each do |association|
224
- next unless association.has_any?
225
-
226
- association.second_items.each do |second_item|
227
- update_model(second_item, association)
228
- end
229
- end
230
- end
231
-
232
- def self.all
233
- ObjectSpace.each_object(self).to_a
234
- end
235
-
236
- def self.find(id)
237
- all.find { |item| item.id == id }
238
- end
239
- end
data/lib/item_clone.rb DELETED
@@ -1,14 +0,0 @@
1
- require 'item_base'
2
-
3
- class ItemClone < ItemBase
4
- attr_accessor :clone_parent
5
-
6
- def initialize(block, parent = nil, parent_association = nil)
7
- super(block, parent, parent_association)
8
- @clone_parent = block.clone_parent
9
- end
10
-
11
- def model_name
12
- clone_parent.name.camelize
13
- end
14
- end