hecks-domain 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +7 -0
  2. data/lib/adapters/adapters.rb +2 -0
  3. data/lib/adapters/resource_server/cli/cli.rb +1 -0
  4. data/lib/adapters/resource_server/cli/generate_resource_server.rb +25 -0
  5. data/lib/adapters/resource_server/cli/templates/resource_server/config.ru.tt +8 -0
  6. data/lib/adapters/resource_server/resource_server.rb +1 -0
  7. data/lib/adapters/sql_database/cli/cli.rb +3 -0
  8. data/lib/adapters/sql_database/cli/generate_domain_migrations.rb +33 -0
  9. data/lib/adapters/sql_database/cli/generate_sql_database.rb +35 -0
  10. data/lib/adapters/sql_database/cli/migration_builder.rb +51 -0
  11. data/lib/adapters/sql_database/cli/templates/migration.rb.tt +14 -0
  12. data/lib/adapters/sql_database/cli/templates/repository.rb.tt +24 -0
  13. data/lib/adapters/sql_database/cli/templates/sql_database/Gemfile +10 -0
  14. data/lib/adapters/sql_database/cli/templates/sql_database/Rakefile +15 -0
  15. data/lib/adapters/sql_database/commands/read/fetch_references.rb +58 -0
  16. data/lib/adapters/sql_database/commands/update/delete_references.rb +45 -0
  17. data/lib/adapters/sql_database/commands/update/link_to_references.rb +45 -0
  18. data/lib/adapters/sql_database/sql_database.rb +1 -0
  19. data/lib/cli/builder/aggregate_command_line_builder.rb +22 -0
  20. data/lib/cli/builder/builder.rb +3 -0
  21. data/lib/cli/builder/reference_command_line_builder.rb +23 -0
  22. data/lib/cli/builder/value_object_command_line_builder.rb +23 -0
  23. data/lib/cli/cli.rb +8 -0
  24. data/lib/cli/command_builder.rb +59 -0
  25. data/lib/cli/domain_object/assignment_template.rb +43 -0
  26. data/lib/cli/domain_object/option_formatter.rb +36 -0
  27. data/lib/cli/generate_domain_object.rb +71 -0
  28. data/lib/cli/new.rb +50 -0
  29. data/lib/cli/templates/aggregate/lib/domain/%name%/%head_name%.rb.tt +16 -0
  30. data/lib/cli/templates/aggregate/lib/domain/%name%/%name%.rb.tt +9 -0
  31. data/lib/cli/templates/aggregate/lib/domain/%name%/repository.rb.tt +41 -0
  32. data/lib/cli/templates/domain/%name%.gemspec.tt +12 -0
  33. data/lib/cli/templates/domain/Version +1 -0
  34. data/lib/cli/templates/domain/lib/%name%.rb.tt +21 -0
  35. data/lib/cli/templates/domain/spec/spec_helper.rb.tt +4 -0
  36. data/lib/cli/templates/reference/lib/domain/%module_name%/%file_name%.rb.tt +25 -0
  37. data/lib/cli/templates/value_object/lib/domain/%module_name%/%name%.rb.tt +24 -0
  38. data/lib/domain_builder/attribute.rb +60 -0
  39. data/lib/domain_builder/domain.rb +19 -0
  40. data/lib/domain_builder/domain_builder.rb +37 -0
  41. data/lib/domain_builder/domain_module.rb +28 -0
  42. data/lib/domain_builder/domain_object.rb +43 -0
  43. data/lib/domain_builder/head.rb +8 -0
  44. data/lib/domain_builder/reference.rb +19 -0
  45. data/lib/domain_builder/value.rb +8 -0
  46. data/lib/hecks-domain.rb +7 -0
  47. metadata +102 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0e407c46ded01180a5c47b3b779aa5f193509002
4
+ data.tar.gz: d36411b8e9533bc8a42d4e9c845ab61329fd05a7
5
+ SHA512:
6
+ metadata.gz: d89bcd8761dab08e36ca8cab1ea1d7e42cd63be5685d826bae3ca2b5d4e16ea007de15c00770111d900bf5bc69a9eb24c9e5517f77329a28c6b40588e1fd308f
7
+ data.tar.gz: 852174b857cdbd06b0f5d68ee75f54d756988250163052ce9247a12f41c2b3fe2016f985c8863422dac157405483ae010846a6bc8877b87875f4bf71d5c22265
@@ -0,0 +1,2 @@
1
+ require_relative 'sql_database/sql_database'
2
+ require_relative 'resource_server/resource_server'
@@ -0,0 +1 @@
1
+ require_relative 'generate_resource_server'
@@ -0,0 +1,25 @@
1
+ module Hecks
2
+ module Domain
3
+ module Adapters
4
+ module ResourceServer
5
+ module CLI
6
+ class GenerateResourceServer < Thor::Group
7
+ include Thor::Actions
8
+
9
+ def self.source_root
10
+ File.dirname(__FILE__) + '/templates/'
11
+ end
12
+
13
+ def create_aggregate_folder
14
+ directory('resource_server', '.')
15
+ end
16
+
17
+ def domain
18
+ File.basename(Dir.getwd)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,8 @@
1
+ require_relative "lib/<%= domain %>.rb"
2
+ require 'hecks'
3
+
4
+ run Hecks::Adapters::ResourceServer.new(
5
+ application_adapter: Hecks::Application.new(
6
+ domain: <%= domain.camelize %>
7
+ )
8
+ )
@@ -0,0 +1 @@
1
+ require_relative 'cli/cli'
@@ -0,0 +1,3 @@
1
+ require_relative 'generate_domain_migrations'
2
+ require_relative 'generate_sql_database'
3
+ require_relative 'migration_builder'
@@ -0,0 +1,33 @@
1
+ module Hecks
2
+ module Domain
3
+ module Adapters
4
+ class SQLDatabase
5
+ module CLI
6
+ class GenerateDomainMigrations < Thor::Group
7
+ include Thor::Actions
8
+ attr_writer :migration_builder
9
+
10
+ def load_domain_spec
11
+ load('../../Domain')
12
+ end
13
+
14
+ def self.source_root
15
+ File.dirname(__FILE__) + '/templates/'
16
+ end
17
+
18
+ def create_migration_file
19
+ @migration_builder = MigrationBuilder.new(self, DOMAIN)
20
+ @migration_builder.call
21
+ end
22
+
23
+ private
24
+
25
+ def migration_builder
26
+ @migration_builder
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,35 @@
1
+ module Hecks
2
+ module Domain
3
+ module Adapters
4
+ class SQLDatabase
5
+ module CLI
6
+ class GenerateSQLDatabase < Thor::Group
7
+ include Thor::Actions
8
+
9
+ def self.source_root
10
+ File.dirname(__FILE__) + '/templates/'
11
+ end
12
+
13
+ def create_sql_database_folder
14
+ directory('sql_database', './adapters/sql_database')
15
+ end
16
+
17
+ def bundle
18
+ run 'bundle'
19
+ end
20
+
21
+ private
22
+
23
+ def class_name
24
+ @class_name
25
+ end
26
+
27
+ def domain_module_name
28
+ DOMAIN.name.camelize
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,51 @@
1
+ module Hecks
2
+ module Domain
3
+ module Adapters
4
+ class SQLDatabase
5
+ module CLI
6
+ class MigrationBuilder
7
+ def initialize(generator, specification)
8
+ @generator = generator
9
+ @schema = Hecks::Adapters::SQLDatabase::Schema.factory(specification)
10
+ end
11
+
12
+ def call
13
+ generate_migrations
14
+ self
15
+ end
16
+
17
+ def table_name
18
+ @table.name
19
+ end
20
+
21
+ def columns
22
+ @table.columns
23
+ end
24
+
25
+ def tables
26
+ @schema.tables
27
+ end
28
+
29
+ private
30
+
31
+ attr_reader :generator
32
+
33
+ def file_name(index, object)
34
+ "#{index}_create_#{table_name}.rb"
35
+ end
36
+
37
+ def generate_migrations
38
+ tables.each.with_index(1) do |table, index|
39
+ @table = table
40
+ @generator.template(
41
+ "migration.rb.tt",
42
+ "db/migrate/" + file_name(index, table)
43
+ )
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,14 @@
1
+ Sequel.migration do
2
+ up do
3
+ create_table(:<%= migration_builder.table_name %>) do
4
+ primary_key :id
5
+ <%- migration_builder.columns.each do |column| -%>
6
+ <%= column.type.camelcase %> :<%= column.name.to_sym %>, :null=>false
7
+ <%- end -%>
8
+ end
9
+ end
10
+
11
+ down do
12
+ drop_table(:<%= migration_builder.table_name %>)
13
+ end
14
+ end
@@ -0,0 +1,24 @@
1
+ module <%= domain_module_name %>
2
+ module Adapters
3
+ class SQLDatabase
4
+ module Repositories
5
+ class <%= class_name %>
6
+ def self.create attributes = {}
7
+ end
8
+
9
+ def self.update id, attributes
10
+ end
11
+
12
+ def self.read id
13
+ end
14
+
15
+ def self.delete id
16
+ end
17
+
18
+ def self.delete_all
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,10 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'hecks', path: '../../../../..'
4
+ gem 'thor'
5
+ gem 'pry'
6
+ gem 'rspec'
7
+ gem 'mysql2'
8
+ gem 'sequel'
9
+ gem 'simplecov'
10
+ gem 'pizza_builder', path: '../../'
@@ -0,0 +1,15 @@
1
+ namespace :db do
2
+ desc "Run migrations"
3
+ task :migrate, [:version] do |t, args|
4
+ require "sequel"
5
+ Sequel.extension :migration
6
+ db = Sequel.connect(ENV.fetch("DATABASE_URL"))
7
+ if args[:version]
8
+ puts "Migrating to version #{args[:version]}"
9
+ Sequel::Migrator.run(db, "db/migrate", target: args[:version].to_i)
10
+ else
11
+ puts "Migrating to latest"
12
+ Sequel::Migrator.run(db, "db/migrate")
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,58 @@
1
+ module Hecks
2
+ module Domain
3
+ module Adapters
4
+ class SQLDatabase
5
+ module Commands
6
+ class Read
7
+ class FetchReferences
8
+ attr_reader :reference_map
9
+ def initialize(read_command)
10
+ @head = read_command.head
11
+ @reference_map = {}
12
+ @entity = read_command.entity
13
+ @table = read_command.table
14
+ @id = read_command.id
15
+ end
16
+
17
+ def call
18
+ @head.references.each do |reference|
19
+ fetch_reference(reference)
20
+ fetch_references(reference)
21
+ end
22
+ self
23
+ end
24
+
25
+ private
26
+
27
+ def fetch_reference(reference)
28
+ return if reference.list?
29
+ column = Column.factory(reference)
30
+ value = DB[column.to_table_name].first(id: @entity[column.to_foreign_key])
31
+
32
+ @entity.delete(column.to_foreign_key)
33
+ value.delete(:id)
34
+ @reference_map[column.name.to_sym] = value
35
+ end
36
+
37
+ def fetch_references(reference)
38
+ return unless reference.list?
39
+
40
+ where_clause = {}
41
+ where_clause[@table.to_foreign_key.to_sym] = @id
42
+ column = Column.factory(reference)
43
+
44
+ @reference_map[column.name.to_sym] ||= []
45
+
46
+ DB[JoinTable(@table, reference).name.to_sym].where(where_clause).map do |record|
47
+ value_object = DB[column.to_table_name].first(id: record[column.to_foreign_key])
48
+ value_object.delete(:id)
49
+ @reference_map[column.name.to_sym] << value_object
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,45 @@
1
+ module Hecks
2
+ module Domain
3
+ module Adapters
4
+ class SQLDatabase
5
+ module Commands
6
+ class Update
7
+ class DeleteReferences
8
+ attr_reader :attributes
9
+
10
+ def initialize(table:, attributes:, reference:)
11
+ @table = table
12
+ @attributes = attributes
13
+ @reference = reference
14
+ @where_clause = {}
15
+ @dataset = DB[JoinTable.new(@table, @reference).name.to_sym]
16
+ end
17
+
18
+ def call
19
+ build_where_clause
20
+ delete_references
21
+ remove_references_from_attributes
22
+ self
23
+ end
24
+
25
+ private
26
+
27
+ def build_where_clause
28
+ DB[JoinTable.new(@table, @reference).name.to_sym]
29
+ end
30
+
31
+ def remove_references_from_attributes
32
+ @attributes.delete(@reference.name.to_sym)
33
+ end
34
+
35
+ def delete_references
36
+ return unless @reference.list?
37
+ @dataset.where(@where_clause).delete
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,45 @@
1
+ module Hecks
2
+ module Domain
3
+ module Adapters
4
+ class SQLDatabase
5
+ module Commands
6
+ class Update
7
+ class LinkToReferences
8
+ attr_reader :reference_ids
9
+ def initialize(reference:, table:, reference_ids:, attributes:)
10
+ @reference = reference
11
+ @reference_ids = reference_ids
12
+ @table = table
13
+ @attributes = attributes
14
+ @column = Column.factory(@reference)
15
+ @record = {}
16
+ end
17
+
18
+ def call
19
+ make_linking_records
20
+ make_foreign_keys
21
+ self
22
+ end
23
+
24
+ private
25
+
26
+ def make_linking_records
27
+ return unless @reference.list?
28
+ @reference_ids[@reference.name.to_sym].each do |value|
29
+ @record[@column.to_foreign_key] = value
30
+ @record[@table.to_foreign_key] = @attributes[:id]
31
+ DB[JoinTable.new(@table, @reference).name.to_sym].insert(@record)
32
+ end
33
+ end
34
+
35
+ def make_foreign_keys
36
+ return if @reference.list?
37
+ @attributes[@column.to_foreign_key] = @reference_ids[@reference.name]
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1 @@
1
+ require_relative 'cli/cli'
@@ -0,0 +1,22 @@
1
+ module Hecks
2
+ module Domain
3
+ module CLI
4
+ class CommandBuilder
5
+ module AggregateCommandLineBuilder
6
+ def self.build(domain, runner)
7
+ domain.domain_modules.values.each do |domain_module|
8
+ runner.call(
9
+ [
10
+ 'generate domain_object',
11
+ '-t', 'aggregate',
12
+ '-n', domain_module.name,
13
+ '--head_name', domain_module.head.name,
14
+ '-a', domain_module.head.attribute_string
15
+ ])
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,3 @@
1
+ require_relative 'value_object_command_line_builder'
2
+ require_relative 'aggregate_command_line_builder'
3
+ require_relative 'reference_command_line_builder'
@@ -0,0 +1,23 @@
1
+ module Hecks
2
+ module Domain
3
+ module CLI
4
+ class CommandBuilder
5
+ module ReferenceCommandLineBuilder
6
+ def self.build(domain, runner)
7
+ domain.domain_modules.values.each do |domain_module|
8
+ domain_module.references.each do |reference|
9
+ runner.call([
10
+ 'generate domain_object',
11
+ '-t', 'reference',
12
+ '-n', reference.name,
13
+ '-m', domain_module.name,
14
+ '-r', reference.referenced_entity
15
+ ])
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ module Hecks
2
+ module Domain
3
+ module CLI
4
+ class CommandBuilder
5
+ module ValueObjectCommandLineBuilder
6
+ def self.build(domain, runner)
7
+ domain.domain_modules.values.each do |domain_module|
8
+ (domain_module.objects - [domain_module.head]).each do |value_object|
9
+ runner.call([
10
+ 'generate domain_object',
11
+ '-t', 'value_object',
12
+ '-n', value_object.name,
13
+ '-m', domain_module.name,
14
+ '-a', value_object.attribute_string
15
+ ])
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
data/lib/cli/cli.rb ADDED
@@ -0,0 +1,8 @@
1
+ require 'json'
2
+
3
+ require_relative 'generate_domain_object'
4
+ require_relative 'new'
5
+ require_relative 'builder/builder'
6
+ require_relative 'command_builder'
7
+ require_relative "domain_object/assignment_template"
8
+ require_relative "domain_object/option_formatter"
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hecks
4
+ module Domain
5
+ module CLI
6
+ class CommandBuilder
7
+ def initialize(name:, dry_run: false)
8
+ @name = name
9
+ @domain = DOMAIN
10
+ @dry_run = dry_run
11
+ @runner = CommandRunner.new(domain, name, dry_run)
12
+ end
13
+
14
+ def call
15
+ delete_tmpfile
16
+ puts "\n"
17
+ generate :domain
18
+ generate :modules
19
+ generate :value_objects
20
+ generate :references
21
+ execute_tmpfile && return unless @dry_run
22
+ print_tmpfile
23
+ end
24
+
25
+ private
26
+
27
+ attr_reader :runner, :name, :domain
28
+
29
+ def print_tmpfile
30
+ puts File.read('tmp/hecks')
31
+ end
32
+
33
+ def delete_tmpfile
34
+ return unless Pathname('tmp/hecks').exist?
35
+ FileUtils.rm('tmp/hecks')
36
+ end
37
+
38
+ def execute_tmpfile
39
+ exec('bash -x tmp/hecks')
40
+ end
41
+
42
+ def generate(command)
43
+ case command
44
+ when :references
45
+ ReferenceCommandLineBuilder.build(domain, runner)
46
+ when :domain
47
+ runner.call(['new', '-n', name])
48
+ when :modules
49
+ AggregateCommandLineBuilder.build(domain, runner)
50
+ when :value_objects
51
+ ValueObjectCommandLineBuilder.build(domain, runner)
52
+ else
53
+ raise "unrecognized command: #{command}"
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,43 @@
1
+ module Hecks
2
+ module Domain
3
+ module CLI
4
+ class GenerateDomainObject
5
+ class AssignmentTemplate
6
+ def initialize(attributes)
7
+ @attributes = attributes
8
+ end
9
+
10
+ def render
11
+ attributes.map do |attribute|
12
+ @attribute = Hecks::Domain::DomainBuilder::Attribute.new(attribute)
13
+ do_assignment
14
+ end.join("\n")
15
+ end
16
+
17
+ private
18
+
19
+ attr_reader :attributes, :attribute
20
+
21
+ def do_assignment
22
+ return value_assignment if Hecks::Domain::DomainBuilder::Types.values.include?(@attribute.type)
23
+ return value_assignment if @attribute.type == 'Value'
24
+ return reference_factory_assignment if attribute.domain_module
25
+ return factory_assignment
26
+ end
27
+
28
+ def reference_factory_assignment
29
+ "@#{attribute.name} = #{attribute.type}Reference.factory(#{attribute.name})"
30
+ end
31
+
32
+ def factory_assignment
33
+ "@#{attribute.name} = #{attribute.type}.factory(#{attribute.name})"
34
+ end
35
+
36
+ def value_assignment
37
+ "@#{attribute.name} = #{attribute.name}"
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,36 @@
1
+ module Hecks
2
+ module Domain
3
+ module CLI
4
+ class GenerateDomainObject
5
+ class OptionFormatter
6
+ def initialize(attributes)
7
+ @attributes = attributes.map do |attribute|
8
+ Hecks::Domain::DomainBuilder::Attribute.new(attribute)
9
+ end
10
+ end
11
+
12
+ def call(format, include_id: false)
13
+ case format
14
+ when 'keys_and_values'
15
+ attributes(include_id).map { |attribute| (attribute.name + ': ' + attribute.name) }.join(', ')
16
+ when 'attribute_string'
17
+ attributes(include_id).map { |attribute| ':' + attribute.name }.join ', '
18
+ when 'param_names'
19
+ attributes(include_id).map { |attribute| attribute.name + ':' }.join ', '
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ def attributes(include_id)
26
+ if include_id
27
+ @attributes + [Hecks::Domain::DomainBuilder::Attribute.new('id:value')]
28
+ else
29
+ @attributes
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+ module Hecks
3
+ module Domain
4
+ module CLI
5
+ class GenerateDomainObject < Thor::Group
6
+ include Thor::Actions
7
+
8
+ class_option :head_name, aliases: '-h', desc: 'the name of the aggregate head'
9
+ class_option :attributes, aliases: '-a', type: :array, desc: 'attributes for the aggregate head'
10
+ class_option :name, aliases: '-n', desc: 'attributes for the aggregate head'
11
+ class_option :type, aliases: '-t', desc: 'The type of domain object you want to create'
12
+ class_option :module_name, aliases: '-m', desc: 'Domain Module'
13
+ class_option :referenced_entity, aliases: '-r', desc: 'Referenced Entity'
14
+
15
+ def self.source_root
16
+ File.dirname(__FILE__) + '/templates'
17
+ end
18
+
19
+ def create_aggregate_folder
20
+ directory(options[:type].to_s, '.')
21
+ end
22
+
23
+ private
24
+
25
+ def assignment_template(attributes)
26
+ AssignmentTemplate.new(attributes).render
27
+ end
28
+
29
+ def option_format(format, include_id: false)
30
+ OptionFormatter.new(options[:attributes]).call(format, include_id: include_id)
31
+ end
32
+
33
+ def head_name
34
+ options[:head_name]
35
+ end
36
+
37
+ def name
38
+ options[:name]
39
+ end
40
+
41
+ def file_name
42
+ name.underscore
43
+ end
44
+
45
+ def attribute_names_without_id
46
+ attributes_without_id.map(&:name)
47
+ end
48
+
49
+ def module_name
50
+ options[:module_name]
51
+ end
52
+
53
+ def domain_name
54
+ Dir.pwd.split('/').last
55
+ end
56
+
57
+ def attributes_without_id_as_string
58
+ attributes_without_id.map { |attribute| ':' + Hecks::Domain::DomainBuilder::Attribute.new(attribute).name }.join ', '
59
+ end
60
+
61
+ def attributes
62
+ options[:attributes] + ['id:integer']
63
+ end
64
+
65
+ def attributes_without_id
66
+ options[:attributes]
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
data/lib/cli/new.rb ADDED
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+ load('Domain') if File.exist?('Domain')
3
+ module Hecks
4
+ module Domain
5
+ module CLI
6
+ class New < Thor::Group
7
+ namespace :hecks
8
+ include Thor::Actions
9
+
10
+ class_option :nobuilder, aliases: '-n', desc: 'load schema from builder'
11
+ class_option :dry_run, aliases: '-d', desc: 'Use when specifying a schema file to output the commands, without running them'
12
+
13
+ def self.source_root
14
+ File.dirname(__FILE__)
15
+ end
16
+
17
+ def load_from_builder
18
+ return if options[:nobuilder]
19
+ CommandBuilder.new(
20
+ name: File.basename(Dir.getwd),
21
+ dry_run: !options[:dry_run].nil?
22
+ ).call
23
+ end
24
+
25
+ def create_hexagon_folder
26
+ return unless options[:nobuilder]
27
+ directory('templates/domain', ".")
28
+ end
29
+
30
+ private
31
+
32
+ def name
33
+ File.basename(Dir.getwd)
34
+ end
35
+
36
+ def module_name
37
+ name.camelize
38
+ end
39
+
40
+ def domain_module_name
41
+ domain_name.camelize
42
+ end
43
+
44
+ def condensed_module_name
45
+ name.delete('_')
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,16 @@
1
+ module <%= domain_name.camelize %>
2
+ module Domain
3
+ module <%= name.camelize %>
4
+ class <%= options[:head_name].camelize %>
5
+ attr_accessor <%= option_format('attribute_string', include_id: true) %>
6
+ def initialize(<%= option_format('param_names', include_id: true) %>)
7
+ <%= assignment_template(attributes) %>
8
+ end
9
+
10
+ def to_json
11
+ JSON.generate(<%= option_format('keys_and_values', include_id: true) %>)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,9 @@
1
+ module <%= domain_name.camelize %>
2
+ module Domain
3
+ module <%= name.camelize %>
4
+ def self.head
5
+ <%= options[:head_name].camelize %>
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,41 @@
1
+ module <%= domain_name.camelize %>
2
+ module Domain
3
+ module <%= name.camelize %>
4
+ class Repository
5
+ @collection = {}
6
+ @last_id = 0
7
+
8
+ def self.create attributes={}
9
+ id = @last_id + 1
10
+ @collection[id] = <%= options[:head_name].camelize %>.new(attributes.merge(id: id))
11
+ @last_id = id
12
+ Struct.new(:id).new(id)
13
+ end
14
+
15
+ def self.update id, attributes
16
+ entity = read id
17
+
18
+ return unless entity
19
+ attributes.each do |field, value|
20
+ entity.send("#{field}=", value)
21
+ end
22
+
23
+ entity
24
+ end
25
+
26
+ def self.read id
27
+ @collection[id]
28
+ end
29
+
30
+ def self.delete(id)
31
+ @collection.delete(id)
32
+ end
33
+
34
+ def self.delete_all
35
+ @collection = {}
36
+ @last_id = 0
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,12 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = '<%= name %>'
3
+ s.homepage = ""
4
+ s.version = File.read('Version').gsub("\n", '')
5
+ s.date = '2016-09-12'
6
+ s.summary = "Summary"
7
+ s.description = "Description"
8
+ s.authors = ["Author"]
9
+ s.email = 'email@example.com'
10
+ s.files = Dir["lib/**/*"]
11
+ s.license = 'MIT'
12
+ end
@@ -0,0 +1 @@
1
+ 0.0.0
@@ -0,0 +1,21 @@
1
+ module <%= module_name %>
2
+ Dir[File.dirname(__FILE__) + "/domain/**/*.rb"].each {|file| require file}
3
+
4
+ def self.domain_modules
5
+ Domain.constants.map { |name| Domain.const_get(name)}
6
+ end
7
+
8
+ def self.repositories
9
+ domain_modules.map do |domain_module|
10
+ [module_name(domain_module), domain_module.const_get(:Repository)]
11
+ end.to_h
12
+ end
13
+
14
+ def self.module_name(domain_module)
15
+ domain_module.to_s.downcase.split("::").last.to_sym
16
+ end
17
+
18
+ def self.spec_path
19
+ File.dirname(__FILE__) + '/../Domain'
20
+ end
21
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+ require 'simplecov'
3
+ SimpleCov.start
4
+ require_relative '../lib/<%= name %>'
@@ -0,0 +1,25 @@
1
+ module <%= domain_name.camelize %>
2
+ module Domain
3
+ module <%= module_name.camelize %>
4
+ class <%= name.camelize %>
5
+ attr_accessor :id, :referenced_entity
6
+
7
+ def self.factory(group_attributes)
8
+ return <%= name.camelize %>.new(group_attributes) unless group_attributes.is_a?(Array)
9
+ group_attributes.map do |attributes|
10
+ <%= name.camelize %>.new(attributes)
11
+ end
12
+ end
13
+
14
+ def initialize(id:)
15
+ @id = id
16
+ @referenced_entity = <%= options[:referenced_entity] %>
17
+ end
18
+
19
+ def to_json(config)
20
+ JSON.generate({id: @id, referenced_entity: @referenced_entity})
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,24 @@
1
+ module <%= domain_name.camelize %>
2
+ module Domain
3
+ module <%= module_name.camelize %>
4
+ class <%= name.camelize %>
5
+ attr_accessor <%= attributes_without_id_as_string %>
6
+
7
+ def self.factory(group_attributes)
8
+ return <%= name.camelize %>.new(group_attributes) unless group_attributes.is_a?(Array)
9
+ group_attributes.map do |attributes|
10
+ <%= name.camelize %>.new(attributes)
11
+ end
12
+ end
13
+
14
+ def initialize(<%= option_format('param_names') %>)
15
+ <%= assignment_template(attributes_without_id) %>
16
+ end
17
+
18
+ def to_json(config)
19
+ JSON.generate(<%= option_format('keys_and_values') %>)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,60 @@
1
+ module Hecks
2
+ module Domain
3
+ class DomainBuilder
4
+ class Attribute
5
+ attr_writer :type
6
+ attr_reader :object_name
7
+
8
+ def initialize(string)
9
+ @string = string
10
+ @object_name = object_name
11
+ end
12
+
13
+ def list?
14
+ @string.include?("[")
15
+ end
16
+
17
+ def name
18
+ @string.split(":").first
19
+ end
20
+
21
+ def type
22
+ return @type if @type
23
+ @string.split(":").last.delete("[").delete("]").camelize
24
+ end
25
+
26
+ def domain_module
27
+ return unless @string.include?("::")
28
+ @string.split("::").first.split(":").last.camelize
29
+ end
30
+
31
+ def copy(new_values={})
32
+ result = self.class.new(@string)
33
+ result.type = new_values[:type] if new_values[:type]
34
+ result
35
+ end
36
+
37
+ def reference?
38
+ !primitive? && !list?
39
+ end
40
+
41
+ def referenced_object
42
+ return unless reference?
43
+ return @string.split("::").last if @string.include?("::")
44
+ @string.split(":").last
45
+ end
46
+
47
+ def primitive?
48
+ ['String', 'Integer', 'Currency'].include?(type)
49
+ end
50
+
51
+ def ==(other)
52
+ return false if other.name != name
53
+ return false if other.type != type
54
+ return false if other.domain_module != domain_module
55
+ return true
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,19 @@
1
+ module Hecks
2
+ module Domain
3
+ class DomainBuilder
4
+ class Domain
5
+ attr_reader :domain_modules, :name
6
+ def initialize(name:)
7
+ @name = name
8
+ @domain_modules = {}
9
+ end
10
+
11
+ def module(name, &block)
12
+ result = DomainModule.new(name: name)
13
+ @domain_modules[name.to_sym] = result
14
+ yield(result)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,37 @@
1
+ require_relative 'attribute'
2
+ require_relative 'domain'
3
+ require_relative 'domain_module'
4
+ require_relative 'domain_object'
5
+ require_relative 'value'
6
+ require_relative 'head'
7
+ require_relative 'reference'
8
+
9
+ module Hecks
10
+ module Domain
11
+ class DomainBuilder
12
+ Types = { string: 'String', integer: 'Integer', currency: 'Currency'}
13
+
14
+ attr_accessor :domain, :specification, :name
15
+
16
+ def initialize(domain_name:, &block)
17
+ @name = domain_name
18
+ @domain = Domain.new(name: domain_name)
19
+ block.yield(@domain)
20
+ self
21
+ end
22
+
23
+ def domain_modules
24
+ @domain.domain_modules
25
+ end
26
+
27
+ def [](module_name)
28
+ domain_modules[module_name]
29
+ end
30
+
31
+
32
+ def self.build(domain_name, &block)
33
+ new(domain_name: domain_name, &block)
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,28 @@
1
+ module Hecks
2
+ module Domain
3
+ class DomainBuilder
4
+ class DomainModule
5
+ attr_reader :objects, :name, :references
6
+
7
+ def initialize(name:)
8
+ @name = name
9
+ @objects = []
10
+ @references = []
11
+ end
12
+
13
+ def head(name=nil)
14
+ return (@objects << Head.new(name: name)).last if name
15
+ objects.find{ |o| o.is_a?(Head) }
16
+ end
17
+
18
+ def value(name)
19
+ (@objects << Value.new(name: name)).last
20
+ end
21
+
22
+ def reference(name)
23
+ (@references << Reference.new(name)).last
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,43 @@
1
+ module Hecks
2
+ module Domain
3
+ class DomainBuilder
4
+ class DomainObject
5
+ attr_reader :name, :attributes
6
+
7
+ def initialize(name:)
8
+ @name = name
9
+ end
10
+
11
+ def attributes(*values)
12
+ return @attributes if @attributes
13
+ @attributes = values.map { |value| Hecks::Domain::DomainBuilder::Attribute.new(value) }
14
+ end
15
+
16
+ def attribute_hash
17
+ attributes.map do |attribute|
18
+ [attribute.name.to_sym, type_with_domain_module(attribute)]
19
+ end.to_h
20
+ end
21
+
22
+ def attribute_string
23
+ attributes.map do |attribute|
24
+ [attribute.name, type_with_domain_module(attribute)].join(':')
25
+ end
26
+ end
27
+
28
+ def references
29
+ @attributes.reject(&:primitive?)
30
+ end
31
+
32
+ private
33
+
34
+ def type_with_domain_module(attribute)
35
+ type = DomainBuilder::Types.values.include?(attribute.type) ? "Value" : attribute.type
36
+ type = '[' + type + ']' if attribute.list?
37
+ return type unless attribute.domain_module
38
+ [attribute.domain_module, type].join("::")
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,8 @@
1
+ module Hecks
2
+ module Domain
3
+ class DomainBuilder
4
+ class Head < DomainObject
5
+ end
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,19 @@
1
+ module Hecks
2
+ module Domain
3
+ class DomainBuilder
4
+ class Reference
5
+ def initialize(reference)
6
+ @reference = reference
7
+ end
8
+
9
+ def referenced_entity
10
+ @reference.split("::").map(&:camelcase).join("::")
11
+ end
12
+
13
+ def name
14
+ @reference.split("::").last.camelcase + "Reference"
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,8 @@
1
+ module Hecks
2
+ module Domain
3
+ class DomainBuilder
4
+ class Value < DomainObject
5
+ end
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,7 @@
1
+ require 'thor'
2
+ require 'hecks-adapters-sql-database'
3
+
4
+ require_relative 'adapters/adapters'
5
+ require_relative 'domain_builder/domain_builder'
6
+ require_relative 'cli/cli'
7
+ require 'active_support/inflector'
metadata ADDED
@@ -0,0 +1,102 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hecks-domain
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Chris Young
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-03-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: hecks-adatpers-sql-database
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description: Make the Domain the center of your programming world
28
+ email: chris@example.com
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - lib/adapters/adapters.rb
34
+ - lib/adapters/resource_server/cli/cli.rb
35
+ - lib/adapters/resource_server/cli/generate_resource_server.rb
36
+ - lib/adapters/resource_server/cli/templates/resource_server/config.ru.tt
37
+ - lib/adapters/resource_server/resource_server.rb
38
+ - lib/adapters/sql_database/cli/cli.rb
39
+ - lib/adapters/sql_database/cli/generate_domain_migrations.rb
40
+ - lib/adapters/sql_database/cli/generate_sql_database.rb
41
+ - lib/adapters/sql_database/cli/migration_builder.rb
42
+ - lib/adapters/sql_database/cli/templates/migration.rb.tt
43
+ - lib/adapters/sql_database/cli/templates/repository.rb.tt
44
+ - lib/adapters/sql_database/cli/templates/sql_database/Gemfile
45
+ - lib/adapters/sql_database/cli/templates/sql_database/Rakefile
46
+ - lib/adapters/sql_database/commands/read/fetch_references.rb
47
+ - lib/adapters/sql_database/commands/update/delete_references.rb
48
+ - lib/adapters/sql_database/commands/update/link_to_references.rb
49
+ - lib/adapters/sql_database/sql_database.rb
50
+ - lib/cli/builder/aggregate_command_line_builder.rb
51
+ - lib/cli/builder/builder.rb
52
+ - lib/cli/builder/reference_command_line_builder.rb
53
+ - lib/cli/builder/value_object_command_line_builder.rb
54
+ - lib/cli/cli.rb
55
+ - lib/cli/command_builder.rb
56
+ - lib/cli/domain_object/assignment_template.rb
57
+ - lib/cli/domain_object/option_formatter.rb
58
+ - lib/cli/generate_domain_object.rb
59
+ - lib/cli/new.rb
60
+ - lib/cli/templates/aggregate/lib/domain/%name%/%head_name%.rb.tt
61
+ - lib/cli/templates/aggregate/lib/domain/%name%/%name%.rb.tt
62
+ - lib/cli/templates/aggregate/lib/domain/%name%/repository.rb.tt
63
+ - lib/cli/templates/domain/%name%.gemspec.tt
64
+ - lib/cli/templates/domain/Version
65
+ - lib/cli/templates/domain/lib/%name%.rb.tt
66
+ - lib/cli/templates/domain/spec/spec_helper.rb.tt
67
+ - lib/cli/templates/reference/lib/domain/%module_name%/%file_name%.rb.tt
68
+ - lib/cli/templates/value_object/lib/domain/%module_name%/%name%.rb.tt
69
+ - lib/domain_builder/attribute.rb
70
+ - lib/domain_builder/domain.rb
71
+ - lib/domain_builder/domain_builder.rb
72
+ - lib/domain_builder/domain_module.rb
73
+ - lib/domain_builder/domain_object.rb
74
+ - lib/domain_builder/head.rb
75
+ - lib/domain_builder/reference.rb
76
+ - lib/domain_builder/value.rb
77
+ - lib/hecks-domain.rb
78
+ homepage: https://github.com/chrisyoung/hecks-domain
79
+ licenses:
80
+ - MIT
81
+ metadata: {}
82
+ post_install_message:
83
+ rdoc_options: []
84
+ require_paths:
85
+ - lib
86
+ required_ruby_version: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ required_rubygems_version: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ requirements: []
97
+ rubyforge_project:
98
+ rubygems_version: 2.6.10
99
+ signing_key:
100
+ specification_version: 4
101
+ summary: DDD and Hexagonal Code Generators
102
+ test_files: []