k_domain 0.0.20 → 0.0.23

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/.builders/config/_.rb +3 -0
  3. data/.builders/setup.rb +30 -0
  4. data/.gitignore +1 -0
  5. data/.rubocop.yml +1 -2
  6. data/Guardfile +1 -0
  7. data/README.md +15 -0
  8. data/lib/k_domain/domain_model/transform.rb +23 -13
  9. data/lib/k_domain/domain_model/transform_steps/_.rb +7 -5
  10. data/lib/k_domain/domain_model/transform_steps/step.rb +20 -0
  11. data/lib/k_domain/domain_model/transform_steps/{step1_attach_db_schema.rb → step1_db_schema.rb} +2 -1
  12. data/lib/k_domain/domain_model/transform_steps/{step6_attach_dictionary.rb → step20_dictionary.rb} +6 -6
  13. data/lib/k_domain/domain_model/transform_steps/step2_domain_models.rb +123 -0
  14. data/lib/k_domain/domain_model/transform_steps/step4_rails_resource_models.rb +3 -3
  15. data/lib/k_domain/domain_model/transform_steps/step5_rails_resource_routes.rb +36 -0
  16. data/lib/k_domain/domain_model/transform_steps/step6_rails_structure_models.rb +90 -0
  17. data/lib/k_domain/domain_model/transform_steps/step7_rails_structure_controllers.rb +109 -0
  18. data/lib/k_domain/domain_model/transform_steps/{step3_attach_columns.rb → step8_domain_columns.rb} +40 -73
  19. data/lib/k_domain/rails_code_extractor/_.rb +5 -0
  20. data/lib/k_domain/rails_code_extractor/extract_controller.rb +59 -0
  21. data/lib/k_domain/rails_code_extractor/extract_model.rb +19 -8
  22. data/lib/k_domain/rails_code_extractor/shim_loader.rb +1 -0
  23. data/lib/k_domain/raw_db_schema/load.rb +1 -1
  24. data/lib/k_domain/raw_db_schema/transform.rb +2 -1
  25. data/lib/k_domain/schemas/_.rb +2 -2
  26. data/lib/k_domain/schemas/database.rb +86 -0
  27. data/lib/k_domain/schemas/domain.rb +154 -0
  28. data/lib/k_domain/schemas/domain_model.rb +2 -2
  29. data/lib/k_domain/schemas/rails_resource.rb +43 -6
  30. data/lib/k_domain/schemas/rails_structure.rb +94 -14
  31. data/lib/k_domain/version.rb +1 -1
  32. data/lib/k_domain.rb +1 -2
  33. data/templates/custom/action_controller.rb +36 -0
  34. data/templates/custom/controller_interceptors.rb +78 -0
  35. data/templates/custom/model_interceptors.rb +71 -0
  36. data/templates/load_schema.rb +7 -0
  37. data/templates/old_printspeek_schema copy.rb +231 -0
  38. data/templates/old_printspeek_schema.rb +233 -0
  39. data/templates/rails/action_controller.rb +301 -0
  40. data/templates/{active_record_shims.rb → rails/active_record.rb} +21 -41
  41. data/templates/ruby_code_extractor/attach_class_info.rb +13 -0
  42. data/templates/ruby_code_extractor/behaviour_accessors.rb +39 -0
  43. data/templates/simple/controller_interceptors.rb +2 -0
  44. metadata +26 -18
  45. data/lib/k_domain/domain_model/transform_steps/step2_attach_models.rb +0 -62
  46. data/lib/k_domain/domain_model/transform_steps/step5_rails_models.rb +0 -71
  47. data/lib/k_domain/schemas/database/_.rb +0 -7
  48. data/lib/k_domain/schemas/database/foreign_key.rb +0 -14
  49. data/lib/k_domain/schemas/database/index.rb +0 -14
  50. data/lib/k_domain/schemas/database/schema.rb +0 -31
  51. data/lib/k_domain/schemas/database/table.rb +0 -32
  52. data/lib/k_domain/schemas/domain/domain.rb +0 -11
  53. data/lib/k_domain/schemas/domain/models/column.rb +0 -49
  54. data/lib/k_domain/schemas/domain/models/model.rb +0 -111
  55. data/templates/fake_module_shims.rb +0 -42
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: de5fc8f220781026dd327f40da53eb3a424ec23f38785be8fddc8f1856970dc1
4
- data.tar.gz: 5573e60dc8665ab146e0edeb291ebcd3db6b792180e05e24721df9d519038f86
3
+ metadata.gz: cbbddfe9857696b7a3a02fc370c51205d584fd08aaad5f8b8605dccebab02bc1
4
+ data.tar.gz: c37fee293561e73b3ed4b4e31f9def8c13848217ee9c4d14efdcfc67a46d42ea
5
5
  SHA512:
6
- metadata.gz: 4ecaa0fef7e6d622f18d2dfe53bdddf2c17fa91e1c2796ee7bdddf5044880f742003d8cb6f7bb4007eeab4bd2f0becba6f8f0fb329f58776f807cd200bd4ced9
7
- data.tar.gz: 76af19179f670d7e4b18121f031b77e18c366259526530b6623f988c5b3e2985ca3a993441e6caacfb7cb71da6afb05c99803234aa85045facdb2c8f09b1194b
6
+ metadata.gz: 12d58c761198fe6fa8336871ab5a3475c0a1caf358c09af2005e8bab3192c82b864663b867b3f2a39d8ba7c20e58258a8981ddd6339dbdb4edec73e37bca4652
7
+ data.tar.gz: 0bfd25819a3425f2932ba751d9e4413b41ae2c617416751855ced16a7fc74f68eff64d87a92138c73b85b0df175f38b8b299f5912f67f8a78970926ff83a4df8
@@ -0,0 +1,3 @@
1
+ puts '_'
2
+
3
+ #require 'config/_initialize'
@@ -0,0 +1,30 @@
1
+ require 'config/_'
2
+ require_relative "../lib/k_domain"
3
+
4
+ db_schema_ruby_file = '/Users/davidcruwys/dev/printspeak/printspeak-master/db/schema.rb'
5
+
6
+ # /Users/davidcruwys/dev/printspeak/printspeak/.builders/config/raw/schema_printspeak.rb
7
+ output_folder = File.expand_path('../.output')
8
+ db_schema_json_file = File.join(output_folder, 'db_schema.json')
9
+ schema_loader_file = File.join(output_folder, 'schema_printspeak.rb')
10
+
11
+ transformer = KDomain::RawDbSchema::Transform.new(db_schema_ruby_file)
12
+ transformer.template_file = '/Users/davidcruwys/dev/kgems/k_domain/templates/old_printspeek_schema.rb'
13
+ puts db_schema_ruby_file
14
+ puts transformer.template_file
15
+ transformer.call
16
+ transformer.write_json(db_schema_json_file)
17
+ transformer.write_schema_loader(schema_loader_file)
18
+ # transformer.schema
19
+
20
+
21
+ # transform = KDomain::DomainModel::Transform.new(
22
+ # db_schema: db_schema,
23
+ # target_file: target_file,
24
+ # target_step_file: target_step_file,
25
+ # model_path: model_path,
26
+ # controller_path: controller_path,
27
+ # route_path: route_path
28
+ # )
29
+
30
+ puts 'done'
data/.gitignore CHANGED
@@ -23,6 +23,7 @@ k_domain.yml
23
23
  /doc/
24
24
  /pkg/
25
25
  /spec/reports/
26
+ /spec/example_domain/advanced/
26
27
  /tmp/
27
28
  !/tmp/.keep
28
29
  *.bundle
data/.rubocop.yml CHANGED
@@ -6,8 +6,7 @@ AllCops:
6
6
  NewCops: enable
7
7
  Exclude:
8
8
  - "_/**/*"
9
- - "spec/sample_input/**/*"
10
- - "spec/sample_output/**/*"
9
+ - "spec/example_domain/**/*"
11
10
  - "templates/**/*"
12
11
  - "lib/k_domain/schemas/domain/old/**/*"
13
12
  - "spec/k_domain/ruby_loader/**/*"
data/Guardfile CHANGED
@@ -19,6 +19,7 @@ group :green_pass_then_cop, halt_on_fail: true do
19
19
  # Ruby files
20
20
  ruby = dsl.ruby
21
21
  dsl.watch_spec_files_for(ruby.lib_files)
22
+ watch(%r{^lib/k_domain/domain_model/transform_steps/(.+).rb}) { 'spec/k_domain/domain_model/transform_spec.rb' }
22
23
  watch(%r{^lib/k_domain/**/(.+)\.rb$}) { |m| "spec/unit/#{m[1]}_spec.rb" }
23
24
  watch(%r{^lib/k_domain/commands/(.+)\.rb$}) { |m| "spec/unit/commands/#{m[1]}_spec.rb" }
24
25
  end
data/README.md CHANGED
@@ -1,3 +1,18 @@
1
+ # JSON Schema
2
+
3
+ The following schemas were created using the following processes.
4
+
5
+ ```
6
+ quicktype -o json-schema/database.json -t database -l schema spec/sample_output/printspeak/schema.json
7
+ quicktype -o json-schema/database.rb -t database -l ruby json-schema/database-altered.json
8
+ spec/sample_output/printspeak/schema.json
9
+ json-schema/database-altered.json
10
+ ```
11
+
12
+ remove statistics
13
+ remove (or move rails structure)
14
+ drop erd_location
15
+
1
16
  # K Domain
2
17
 
3
18
  > K Domain builds complex domain schemas by combining the database schema with a rich entity relationship DSLs
@@ -11,24 +11,34 @@ module KDomain
11
11
  attr_reader :db_schema
12
12
  attr_reader :target_step_file
13
13
  attr_reader :target_file
14
- attr_reader :erd_path
14
+ attr_reader :model_path
15
+ attr_reader :controller_path
16
+ attr_reader :route_path
17
+ attr_reader :shim_loader
15
18
 
16
- def initialize(db_schema: , target_file: , target_step_file: , erd_path:)
19
+ # rubocop:disable Metrics/ParameterLists
20
+ def initialize(db_schema: , target_file: , target_step_file: , model_path:, route_path:, controller_path:, shim_loader: nil)
17
21
  @db_schema = db_schema
18
22
  @target_step_file = target_step_file
19
23
  @target_file = target_file
20
- @erd_path = erd_path
24
+ @model_path = model_path
25
+ @controller_path = controller_path
26
+ @route_path = route_path
27
+ @shim_loader = shim_loader
21
28
  end
29
+ # rubocop:enable Metrics/ParameterLists
22
30
 
23
31
  # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
24
32
  def call
25
33
  valid = true
26
- valid &&= Step1AttachDbSchema.run(domain_data, db_schema: db_schema, step_file: step_file('1-attach-db-schema'))
27
- valid &&= Step2AttachModels.run(domain_data, erd_path: erd_path, step_file: step_file('2-attach-model'))
28
- valid &&= Step3AttachColumns.run(domain_data, step_file: step_file('3-attach-columns'))
29
- valid &&= Step4RailsResourceModels.run(domain_data, erd_path: erd_path, step_file: step_file('4-rails-resource-models'))
30
- valid &&= Step5RailsModels.run(domain_data, erd_path: erd_path, step_file: step_file('5-rails-models'))
31
- valid &&= Step6AttachDictionary.run(domain_data, erd_path: erd_path, step_file: step_file('6-attach-dictionary'))
34
+ valid &&= Step1DbSchema.run(domain_data, db_schema: db_schema, step_file: step_file('01-db-schema'))
35
+ valid &&= Step2DomainModels.run(domain_data, model_path: model_path, step_file: step_file('02-domain-model'))
36
+ valid &&= Step4RailsResourceModels.run(domain_data, model_path: model_path, step_file: step_file('04-rails-resource-models'))
37
+ valid &&= Step5RailsResourceRoutes.run(domain_data, route_path: route_path, controller_path: controller_path, step_file: step_file('05-rails-resource-routes'))
38
+ valid &&= Step6RailsStructureModels.run(domain_data, model_path: model_path, step_file: step_file('06-rails-structure-models'), shim_loader: shim_loader)
39
+ valid &&= Step7RailsStructureControllers.run(domain_data, controller_path: controller_path, step_file: step_file('07-rails-structure-controllers'), shim_loader: shim_loader)
40
+ valid &&= Step8DomainColumns.run(domain_data, step_file: step_file('08-domain-columns'))
41
+ valid &&= Step20Dictionary.run(domain_data, step_file: step_file('20-dictionary'))
32
42
 
33
43
  raise 'DomainModal transform failed' unless valid
34
44
 
@@ -39,7 +49,7 @@ module KDomain
39
49
  # rubocop:enable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
40
50
 
41
51
  def step_file(step_name)
42
- target_step_file % { step: step_name }
52
+ format(target_step_file, step: step_name)
43
53
  end
44
54
 
45
55
  def write
@@ -52,11 +62,11 @@ module KDomain
52
62
  # The initial domain model structure is created here, but populated during the workflows.
53
63
  @domain_data ||= {
54
64
  domain: {
55
- models: [],
65
+ models: []
56
66
  },
57
67
  rails_resource: {
58
68
  models: [],
59
- controllers: []
69
+ routes: []
60
70
  },
61
71
  rails_structure: {
62
72
  models: [],
@@ -69,6 +79,7 @@ module KDomain
69
79
  tables: [],
70
80
  indexes: [],
71
81
  foreign_keys: [],
82
+ views: [],
72
83
  meta: {}
73
84
  },
74
85
  investigate: {
@@ -76,7 +87,6 @@ module KDomain
76
87
  }
77
88
  }
78
89
  end
79
-
80
90
  # rubocop:enable Metrics/MethodLength
81
91
  end
82
92
  end
@@ -2,9 +2,11 @@
2
2
 
3
3
  # The require order is important due to dependencies
4
4
  require_relative './step'
5
- require_relative './step1_attach_db_schema'
6
- require_relative './step2_attach_models'
7
- require_relative './step3_attach_columns'
5
+ require_relative './step1_db_schema'
6
+ require_relative './step2_domain_models'
8
7
  require_relative './step4_rails_resource_models'
9
- require_relative './step5_rails_models'
10
- require_relative './step6_attach_dictionary'
8
+ require_relative './step5_rails_resource_routes'
9
+ require_relative './step6_rails_structure_models'
10
+ require_relative './step7_rails_structure_controllers'
11
+ require_relative './step8_domain_columns'
12
+ require_relative './step20_dictionary'
@@ -33,6 +33,10 @@ module KDomain
33
33
  @valid = false
34
34
  end
35
35
 
36
+ def warning(message)
37
+ log.warn message
38
+ end
39
+
36
40
  def write(file)
37
41
  FileUtils.mkdir_p(File.dirname(file))
38
42
  File.write(file, JSON.pretty_generate(domain_data))
@@ -64,6 +68,14 @@ module KDomain
64
68
  rails_resource[:models] = value
65
69
  end
66
70
 
71
+ def rails_resource_routes
72
+ rails_resource[:routes]
73
+ end
74
+
75
+ def rails_resource_routes=(value)
76
+ rails_resource[:routes] = value
77
+ end
78
+
67
79
  def rails_resource_controllers
68
80
  rails_resource[:controllers]
69
81
  end
@@ -79,6 +91,10 @@ module KDomain
79
91
  rails_structure[:models]
80
92
  end
81
93
 
94
+ def find_rails_structure_models(model_name)
95
+ rails_structure_models.find { |model| model[:model_name] == model_name }
96
+ end
97
+
82
98
  def rails_structure_models=(value)
83
99
  rails_structure[:models] = value
84
100
  end
@@ -87,6 +103,10 @@ module KDomain
87
103
  rails_structure[:controllers]
88
104
  end
89
105
 
106
+ def rails_structure_controllers=(value)
107
+ rails_structure[:controllers] = value
108
+ end
109
+
90
110
  # Database Accessor/Helpers
91
111
  def database=(value)
92
112
  domain_data[:database] = value
@@ -2,12 +2,13 @@
2
2
 
3
3
  module KDomain
4
4
  module DomainModel
5
- class Step1AttachDbSchema < KDomain::DomainModel::Step
5
+ class Step1DbSchema < KDomain::DomainModel::Step
6
6
  # Map database schema to domain model
7
7
  def call
8
8
  raise 'Schema not supplied' if opts[:db_schema].nil?
9
9
 
10
10
  self.database = opts[:db_schema].clone
11
+ database[:tables] = database[:tables] # .slice(156, 1)
11
12
 
12
13
  guard('tables are missing') if database[:tables].nil?
13
14
  guard('indexes are missing') if database[:indexes].nil?
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Attach data dictionary
4
- class Step6AttachDictionary < KDomain::DomainModel::Step
3
+ # data dictionary
4
+ class Step20Dictionary < KDomain::DomainModel::Step
5
5
  attr_reader :dictionary
6
6
 
7
7
  def call
@@ -27,10 +27,10 @@ class Step6AttachDictionary < KDomain::DomainModel::Step
27
27
  entry[:model_count] = entry[:model_count] + 1
28
28
 
29
29
  unless entry[:types].include?(column_type)
30
- investigate(step: :step5_attach_dictionary,
31
- location: :process,
32
- key: "#{model_name},#{column_name},#{column_type}",
33
- message: "#{model_name} has a type mismatch for column name: #{column_name}")
30
+ investigate(step: :step5_dictionary,
31
+ location: :process,
32
+ key: "#{model_name},#{column_name},#{column_type}",
33
+ message: "#{model_name} has a type mismatch for column name: #{column_name}")
34
34
 
35
35
  entry[:types] << column_type
36
36
  entry[:type_count] = entry[:type_count] + 1
@@ -0,0 +1,123 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Schema is re-shaped into a format designed for domain modeling
4
+ class Step2DomainModels < KDomain::DomainModel::Step
5
+ # Map database schema to domain model
6
+ def call
7
+ raise 'Rails model path not supplied' if opts[:model_path].nil?
8
+
9
+ domain[:models] = database_tables.map { |table| model(table) }
10
+ end
11
+
12
+ def model(table)
13
+ table_name = table[:name].to_s
14
+ model_name = table_name.singularize
15
+
16
+ model = {
17
+ name: model_name,
18
+ name_plural: table_name, # need to check if this is correct as I know it is wrong for account_history_datum
19
+ table_name: table_name,
20
+ pk: primary_key(table),
21
+ file: nil
22
+ }
23
+
24
+ attach_columns(model)
25
+ end
26
+
27
+ def primary_key(table)
28
+ {
29
+ name: table[:primary_key],
30
+ type: table[:primary_key_type],
31
+ exist: !table[:primary_key].nil?
32
+ }
33
+ end
34
+
35
+ def attach_columns(model)
36
+ table = find_table_for_model(model)
37
+ columns = columns(table[:columns])
38
+ columns = insert_primary_key(model, columns)
39
+ model[:columns] = columns
40
+ model
41
+ end
42
+
43
+ def columns(db_columns)
44
+ db_columns.map do |db_column|
45
+ column_data(db_column[:name]).merge(
46
+ type: check_type(db_column[:type]),
47
+ precision: db_column[:precision],
48
+ scale: db_column[:scale],
49
+ default: db_column[:default],
50
+ null: db_column[:null],
51
+ limit: db_column[:limit],
52
+ array: db_column[:array]
53
+ )
54
+ end
55
+ end
56
+
57
+ def insert_primary_key(model, columns)
58
+ return columns unless model[:pk][:exist]
59
+
60
+ column = column_data('id').merge(
61
+ type: check_type(model[:pk][:type])
62
+ )
63
+
64
+ columns.unshift(column)
65
+ columns
66
+ end
67
+
68
+ def check_type(type)
69
+ type = type.to_sym if type.is_a?(String)
70
+
71
+ return type if %i[string integer bigint bigserial boolean float decimal datetime date hstore text jsonb].include?(type)
72
+
73
+ if type.nil?
74
+ guard('nil type detected for db_column[:type]')
75
+
76
+ return :string
77
+ end
78
+
79
+ guard("new type detected for db_column[:type] - #{type}")
80
+
81
+ camel.parse(type.to_s).downcase
82
+ end
83
+
84
+ def column_data(name)
85
+ {
86
+ name: name,
87
+ name_plural: name.pluralize,
88
+ type: nil,
89
+ precision: nil,
90
+ scale: nil,
91
+ default: nil,
92
+ null: nil,
93
+ limit: nil,
94
+ array: nil
95
+ }
96
+ end
97
+
98
+ # # Location of source code
99
+ # def location(table_name, model_name)
100
+ # file_normal = File.join(opts[:model_path], "#{model_name}.rb")
101
+ # file_custom = File.join(opts[:model_path], "#{table_name}.rb")
102
+ # file_exist = true
103
+ # state = []
104
+
105
+ # if File.exist?(file_normal)
106
+ # file = file_normal
107
+ # state.push(:has_ruby_model)
108
+ # elsif File.exist?(file_custom)
109
+ # file = file_custom
110
+ # state.push(:has_ruby_model)
111
+ # state.push(:nonconventional_name)
112
+ # else
113
+ # file = ''
114
+ # file_exist = false
115
+ # end
116
+
117
+ # {
118
+ # file: file,
119
+ # exist: file_exist,
120
+ # state: state
121
+ # }
122
+ # end
123
+ end
@@ -5,7 +5,7 @@ class Step4RailsResourceModels < KDomain::DomainModel::Step
5
5
  attr_accessor :ruby_code
6
6
 
7
7
  def call
8
- raise 'ERD path not supplied' if opts[:erd_path].nil?
8
+ raise 'Model path not supplied' if opts[:model_path].nil?
9
9
 
10
10
  self.rails_resource_models = domain_models.map do |model|
11
11
  locate_rails_model(model[:name], model[:table_name])
@@ -15,8 +15,8 @@ class Step4RailsResourceModels < KDomain::DomainModel::Step
15
15
  private
16
16
 
17
17
  def locate_rails_model(model_name, table_name)
18
- file_normal = File.join(opts[:erd_path], "#{model_name}.rb")
19
- file_custom = File.join(opts[:erd_path], "#{table_name}.rb")
18
+ file_normal = File.join(opts[:model_path], "#{model_name}.rb")
19
+ file_custom = File.join(opts[:model_path], "#{table_name}.rb")
20
20
  file_exist = true
21
21
  state = []
22
22
 
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Locate rails model files
4
+ class Step5RailsResourceRoutes < KDomain::DomainModel::Step
5
+ def call
6
+ return warning('Routes .json file not supplied') if opts[:route_path].nil?
7
+ return warning('Routes .json file not found') unless File.exist?(opts[:route_path])
8
+
9
+ warning('Controller path not supplied. Routes will be loaded but not paired with a controller') if opts[:controller_path].nil?
10
+
11
+ self.rails_resource_routes = load_routes(opts[:route_path], opts[:controller_path])
12
+ end
13
+
14
+ private
15
+
16
+ def load_routes(route_path, controller_path)
17
+ json = File.read(route_path)
18
+ root = JSON.parse(json, symbolize_names: true)
19
+ routes = root[:routes]
20
+
21
+ routes.map { |route| map_route(route, controller_path) }
22
+ end
23
+
24
+ def map_route(route, controller_path)
25
+ return route.merge({ file: '', exist: false }) if controller_path.nil?
26
+
27
+ controller_file = File.join(controller_path, route[:controller_file])
28
+
29
+ route.merge(
30
+ {
31
+ file: controller_file,
32
+ exist: File.exist?(controller_file)
33
+ }
34
+ )
35
+ end
36
+ end
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Locate rails model files
4
+ class Step6RailsStructureModels < KDomain::DomainModel::Step
5
+ def call
6
+ raise 'Rails model path not supplied' unless opts[:model_path]
7
+
8
+ # THIS IS NOT WORKING YET
9
+ self.rails_structure_models = rails_resource_models.map do |resource|
10
+ process_resource(OpenStruct.new(resource))
11
+ end
12
+
13
+ attach_behavior_and_functions
14
+ end
15
+
16
+ private
17
+
18
+ def process_resource(resource)
19
+ {
20
+ model_name: resource.model_name,
21
+ table_name: resource.table_name,
22
+ file: resource.file,
23
+ exist: resource.exist,
24
+ state: resource.state,
25
+ code: resource.exist ? File.read(resource.file) : '',
26
+ behaviours: {},
27
+ functions: {}
28
+ }
29
+
30
+ # return @model unless resource.exist
31
+
32
+ # @model[:behaviours] = extract_behavior(resource.file)
33
+ # @model[:functions] = extract_functions(resource.file)
34
+
35
+ # @model
36
+ end
37
+
38
+ def attach_behavior_and_functions
39
+ rails_structure_models.select { |model| model[:exist] }.each do |model|
40
+ model[:behaviours] = extract_behavior(model[:file])
41
+ klass_name = model[:behaviours][:class_name]
42
+ model[:functions] = extract_functions(klass_name)
43
+ end
44
+ end
45
+
46
+ def extract_behavior(file)
47
+ extractor.extract(file)
48
+ extractor.model
49
+ end
50
+
51
+ def extract_functions(klass_name)
52
+ klass = klass_type(klass_name)
53
+
54
+ return {} if klass.nil?
55
+
56
+ Peeky.api.build_class_info(klass.new).to_h
57
+ rescue StandardError => e
58
+ log.exception(e)
59
+ end
60
+
61
+ def klass_type(klass_name)
62
+ Module.const_get(klass_name.classify)
63
+ rescue NameError
64
+ puts ''
65
+ puts klass_name
66
+ puts klass_name.classify
67
+ puts klass_name.pluralize
68
+ puts 'Trying the pluralized version: '
69
+ Module.const_get(klass_name.pluralize)
70
+ end
71
+
72
+ def extractor
73
+ @extractor ||= KDomain::RailsCodeExtractor::ExtractModel.new(shim_loader)
74
+ end
75
+
76
+ def shim_loader
77
+ return opts[:shim_loader] if !opts[:shim_loader].nil? && opts[:shim_loader].is_a?(KDomain::RailsCodeExtractor::ShimLoader)
78
+
79
+ shim_loader = KDomain::RailsCodeExtractor::ShimLoader.new
80
+ # Shims to attach generic class_info writers
81
+ shim_loader.register(:attach_class_info , KDomain::Gem.resource('templates/ruby_code_extractor/attach_class_info.rb'))
82
+ shim_loader.register(:behaviour_accessors , KDomain::Gem.resource('templates/ruby_code_extractor/behaviour_accessors.rb'))
83
+
84
+ # Shims to support standard active_record DSL methods
85
+ shim_loader.register(:active_record , KDomain::Gem.resource('templates/rails/active_record.rb'))
86
+
87
+ # Shims to support application specific [module, class, method] implementations for suppression and exception avoidance
88
+ shim_loader
89
+ end
90
+ end
@@ -0,0 +1,109 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Locate rails controller files
4
+ class Step7RailsStructureControllers < KDomain::DomainModel::Step
5
+ attr_accessor :controllers
6
+
7
+ def call
8
+ raise 'Rails controller path not supplied' unless opts[:controller_path]
9
+
10
+ @controllers = {}
11
+
12
+ rails_resource_routes.map do |route|
13
+ process_route(OpenStruct.new(route))
14
+ end
15
+
16
+ self.rails_structure_controllers = controllers.keys.map { |key| controllers[key] }
17
+
18
+ attach_behavior_and_functions
19
+ end
20
+
21
+ private
22
+
23
+ def process_route(route)
24
+ if new_controller?(route)
25
+ new_controller(route)
26
+ else
27
+ controller = @controllers[route[:controller_file]]
28
+ controller[:actions] << new_action(route)
29
+ end
30
+ end
31
+
32
+ def new_controller?(route)
33
+ !controllers.key?(route[:controller_file])
34
+ end
35
+
36
+ def new_controller(route)
37
+ controllers[route[:controller_file]] = {
38
+ name: route[:controller_name],
39
+ path: route[:controller_path],
40
+ namespace: route[:controller_namespace],
41
+ file: route[:controller_file],
42
+ exist: route[:controller_exist],
43
+ full_file: route[:file],
44
+ behaviours: {},
45
+ functions: {},
46
+ actions: [new_action(route)]
47
+ }
48
+ end
49
+
50
+ def new_action(route)
51
+ {
52
+ route_name: route[:name],
53
+ action: route[:action],
54
+ uri_path: route[:uri_path],
55
+ mime_match: route[:mime_match],
56
+ verbs: route[:verbs]
57
+ }
58
+ end
59
+
60
+ def attach_behavior_and_functions
61
+ rails_structure_controllers.select { |controller| controller[:exist] }.each do |controller|
62
+ unless File.exist?(controller[:full_file])
63
+ log.error 'Controller apparently exists but no file found, this means that you need re-run rake routes'
64
+ puts controller[:full_file]
65
+ next
66
+ end
67
+ controller[:behaviours] = extract_behavior(controller[:full_file])
68
+ klass_name = controller[:behaviours][:class_name]
69
+ controller[:functions] = extract_functions(klass_name)
70
+ end
71
+ end
72
+
73
+ def extract_behavior(file)
74
+ # puts file
75
+ extractor.extract(file)
76
+ extractor.controller
77
+ end
78
+
79
+ def extractor
80
+ @extractor ||= KDomain::RailsCodeExtractor::ExtractController.new(shim_loader)
81
+ end
82
+
83
+ def shim_loader
84
+ return opts[:shim_loader] if !opts[:shim_loader].nil? && opts[:shim_loader].is_a?(KDomain::RailsCodeExtractor::ShimLoader)
85
+
86
+ shim_loader = KDomain::RailsCodeExtractor::ShimLoader.new
87
+ # Shims to attach generic class_info writers
88
+ shim_loader.register(:attach_class_info , KDomain::Gem.resource('templates/ruby_code_extractor/attach_class_info.rb'))
89
+ shim_loader.register(:behaviour_accessors , KDomain::Gem.resource('templates/ruby_code_extractor/behaviour_accessors.rb'))
90
+
91
+ # Shims to support stand rails controller DSL methods
92
+ shim_loader.register(:action_controller , KDomain::Gem.resource('templates/rails/action_controller.rb'))
93
+
94
+ # Shims to support application specific [module, class, method] implementations for suppression and exception avoidance
95
+ # shim_loader.register(:app_action_controller , KDomain::Gem.resource('templates/advanced/action_controller.rb'))
96
+ # shim_loader.register(:app_controller_interceptors , KDomain::Gem.resource('templates/advanced/controller_interceptors.rb'))
97
+ shim_loader
98
+ end
99
+
100
+ def extract_functions(klass_name)
101
+ klass = Module.const_get(klass_name.classify)
102
+
103
+ class_info = Peeky.api.build_class_info(klass.new)
104
+
105
+ class_info.to_h
106
+ rescue StandardError => e
107
+ log.exception(e)
108
+ end
109
+ end