alki 0.8.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/README.adoc +108 -6
  3. data/alki.gemspec +2 -2
  4. data/bin/alki +17 -0
  5. data/config/dsls.rb +2 -2
  6. data/doc/assembly_dsl.adoc +6 -6
  7. data/exe/alki +275 -0
  8. data/lib/alki/assembly/builder.rb +113 -0
  9. data/lib/alki/assembly/executor.rb +127 -0
  10. data/lib/alki/assembly/handler_base.rb +21 -0
  11. data/lib/alki/assembly/instance.rb +21 -0
  12. data/lib/alki/assembly/types/assembly.rb +92 -0
  13. data/lib/alki/assembly/types/factory.rb +29 -0
  14. data/lib/alki/assembly/types/func.rb +12 -0
  15. data/lib/alki/assembly/types/group.rb +39 -0
  16. data/lib/alki/assembly/types/override.rb +40 -0
  17. data/lib/alki/assembly/types/proc_value.rb +18 -0
  18. data/lib/alki/assembly/types/service.rb +27 -0
  19. data/lib/alki/assembly/types/value.rb +9 -0
  20. data/lib/alki/assembly.rb +21 -40
  21. data/lib/alki/dsls/assembly.rb +10 -12
  22. data/lib/alki/dsls/assembly_group.rb +92 -0
  23. data/lib/alki/dsls/assembly_type.rb +5 -15
  24. data/lib/alki/execution/cache_entry.rb +16 -0
  25. data/lib/alki/execution/context.rb +29 -0
  26. data/lib/alki/execution/context_class_builder.rb +36 -0
  27. data/lib/alki/execution/value_context.rb +14 -0
  28. data/lib/alki/overlay_delegator.rb +8 -20
  29. data/lib/alki/overlay_info.rb +3 -0
  30. data/lib/alki/override_builder.rb +6 -4
  31. data/lib/alki/service_delegator.rb +3 -3
  32. data/lib/alki/version.rb +1 -1
  33. data/lib/alki.rb +4 -4
  34. data/test/feature/alki_test.rb +1 -2
  35. data/test/feature/example_test.rb +2 -3
  36. data/test/feature/factories_test.rb +48 -0
  37. data/test/feature/overlays_test.rb +225 -0
  38. data/test/feature/overrides_test.rb +1 -2
  39. data/test/feature/pseudo_elements_test.rb +67 -0
  40. data/test/feature_test_helper.rb +1 -0
  41. data/test/fixtures/example/config/assembly.rb +11 -2
  42. data/test/fixtures/example/config/handlers.rb +2 -7
  43. data/test/fixtures/example/lib/log_overlay.rb +3 -3
  44. data/test/integration/dsls/assembly_test.rb +3 -8
  45. data/test/integration/dsls/assembly_type_test.rb +2 -2
  46. data/test/integration/dsls/service_dsl_test.rb +2 -2
  47. metadata +36 -18
  48. data/lib/alki/assembly_builder.rb +0 -109
  49. data/lib/alki/assembly_executor.rb +0 -129
  50. data/lib/alki/assembly_handler_base.rb +0 -19
  51. data/lib/alki/dsls/assembly_type_dsl.rb +0 -21
  52. data/lib/alki/dsls/assembly_types/assembly.rb +0 -101
  53. data/lib/alki/dsls/assembly_types/group.rb +0 -41
  54. data/lib/alki/dsls/assembly_types/load.rb +0 -31
  55. data/lib/alki/dsls/assembly_types/overlay.rb +0 -9
  56. data/lib/alki/dsls/assembly_types/value.rb +0 -100
  57. data/test/test_helper.rb +0 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 91b0f6c880177b0e4be1c5228c92b0295db5742a
4
- data.tar.gz: 6c781108545400031137040024b040c3a67d9b16
3
+ metadata.gz: 30b3e6d184beebdc00446b13b4930d47d32151df
4
+ data.tar.gz: 98249b15e58962ab44737b9e54199f8690938407
5
5
  SHA512:
6
- metadata.gz: cc46916b429be7d64b76b2e9e93d086493699d8303607d248471a55fed9da1ab13e7c01bc7b2b700a44c71180943c53fb766b72d50b3dd10dd75ec700e6816cc
7
- data.tar.gz: e17b68e68390ea600d2d5f2dabe48029696537d2d8ded480eec57cb1a6bf6601dc4035aaf666311ab63f3a28684dac9f571b2e8746e11885b204cfd5c2ccbe09
6
+ metadata.gz: df40acd78708b8a0371f5191f1b5160c4d09e9348e92c237791761528a22552f3212c7dd14759c555b20d5364def4cd1976eaa12ad90690d3d9b81a7c5e27670
7
+ data.tar.gz: 24bc23ef4c32c0b16a6e63a0386c3a767bcc9fc0a2393b8197c9d942e4f9ebad6bc97b394d1d142c060cc39371e42d6fc2edeb6d72a51035fd12dad836babc8c
data/README.adoc CHANGED
@@ -1,12 +1,114 @@
1
1
  # What is Alki?
2
+ :toc:
2
3
 
3
- Alki is a framework for creating projects that are modular, testable, and well organized.
4
+ Alki is a small framework for writing Ruby projects, providing a powerful dependency injection system with
5
+ helpers for testing, creating executables, and easy to use libraries.
4
6
 
5
- It's goal is to remove uncertainty and friction when building Ruby projects, allowing developers to focus on implementing business logic.
7
+ It's goal is to remove uncertainty and friction when building Ruby projects, allowing developers to focus on
8
+ implementing business logic. It can be used alongside other frameworks such as Ruby on Rails.
6
9
 
7
- Best place to start would be to check out some examples:
10
+ Alki tries to combine the time tested software engineering concepts such as
11
+ https://en.wikipedia.org/wiki/SOLID_(object-oriented_design)[SOLID],
12
+ and https://en.wikipedia.org/wiki/Inversion_of_control[Inversion of Control], with
13
+ Ruby style ease of use, DSLs, and
14
+ https://en.wikipedia.org/wiki/Convention_over_configuration[Convention over Configuration].
8
15
 
9
- * https://github.com/alki-project/alki-example
10
- * https://github.com/alki-project/alki/tree/master/test/fixtures/example
16
+ Documentation can be found at https://github.com/alki-project/alki/blob/master/doc/index.adoc
17
+
18
+ ## Getting Started
19
+
20
+ Install from rubygems
21
+
22
+ gem install alki
23
+
24
+ Setting up Alki in your project requires only created a couple of files, but the
25
+ `alki` command line tool can also be used to automate the process. Project names
26
+ should be given in lowercase using underscores and forward slashes as separators.
27
+
28
+ .Example project
29
+ ```
30
+ $ cd <project dir>
31
+ $ alki init --console <project name>
32
+ ```
33
+ ## Example
34
+
35
+ To demonstrate the basic features of Alki, this will go through the creation of
36
+ a simple example project.
37
+
38
+ To get started, a new project should be created.
39
+
40
+ ```
41
+ $ mkdir example
42
+ $ cd example
43
+ $ alki init --console example
44
+ ```
45
+
46
+ ### First Service
47
+
48
+ Open up `config/assembly.rb` in your favorite text editor and add a simple log
49
+ service as an example. The service definition should require the files it needs and
50
+ then construct an object.
51
+
52
+ .config/assembly.rb
53
+ ```ruby
54
+ Alki do
55
+ mount :console, 'alki/console', name: 'example'
56
+
57
+ service :log do
58
+ require 'logger'
59
+ Logger.new STDERR
60
+ end
61
+ end
62
+ ```
63
+
64
+ To test, we can open up the console and interact with our new service.
65
+
66
+ ```bash
67
+ $ bin/console
68
+ example> log.info "test message"
69
+ I, [<timestamp>] INFO -- : test message
70
+ => true
71
+ test> exit
72
+ ```
73
+
74
+ ### Adding Settings
75
+
76
+ Many times in a project there will end with a lot of configuration settings or magic
77
+ numbers sprinkled throughout your code, maybe pulled from `ENV` or just set directly
78
+ as constants. Alki provides a simple way to centralize them. By convention this is done
79
+ by creating a `config/settings.rb` and loading it into your Assembly.
80
+
81
+ To demonstrate we can pull the log io (`STDERR`) out of our main assembly and add it
82
+ to our settings.
83
+
84
+ .config/settings.rb
85
+ ```ruby
86
+ Alki do
87
+ set :log_io, STDERR
88
+ end
89
+ ```
90
+ Now we can load our settings file in our assembly config (`load :settings`) and use
91
+ the setting in our log service.
92
+
93
+ .config/assembly.rb
94
+ ```ruby
95
+ Alki do
96
+ load :settings
97
+ mount :console, 'alki/console', name: 'example'
98
+
99
+ service :log do
100
+ require 'logger'
101
+ Logger.new settings.log_io
102
+ end
103
+ end
104
+ ```
105
+
106
+ ### Adding your own Classes
107
+
108
+ Generally, you're not just going to be using other people's classes. Alki doesn't have any requirements as to
109
+ where your classes need to go, but conventionally they can be placed under `lib/<project-name>/`.
110
+
111
+ The Alki style of writing a Class is to only `require` external libraries, or utility files in your class files.
112
+ All of the "glue" that ties your code together can instead be put in your assembly definition. This allows you
113
+ to modularize and loosely couple your programs.
11
114
 
12
- Docs can be found at https://github.com/alki-project/alki/blob/master/doc/index.adoc
data/alki.gemspec CHANGED
@@ -21,6 +21,6 @@ Gem::Specification.new do |spec|
21
21
  spec.add_development_dependency "bundler", "~> 1.6"
22
22
  spec.add_development_dependency "rake", '~> 10.0'
23
23
  spec.add_dependency "minitest", "~> 5.9", '>= 5.9.1'
24
- spec.add_dependency "alki-dsl", "~> 0.3", '>= 0.3.1'
25
- spec.add_dependency "alki-support", "~> 0.5"
24
+ spec.add_dependency "alki-dsl", "~> 0.3", '>= 0.3.3'
25
+ spec.add_dependency "alki-support", "~> 0.6"
26
26
  end
data/bin/alki ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+ #
4
+ # This file was generated by Bundler.
5
+ #
6
+ # The application 'alki' is installed as part of a gem, and
7
+ # this file is here to facilitate running it.
8
+ #
9
+
10
+ require "pathname"
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
12
+ Pathname.new(__FILE__).realpath)
13
+
14
+ require "rubygems"
15
+ require "bundler/setup"
16
+
17
+ load Gem.bin_path("alki", "alki")
data/config/dsls.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  Alki do
2
- register_lib_dir 'alki/dsls/assembly_types', 'alki/dsls/assembly_type_dsl'
2
+ register_lib_dir 'alki/assembly/types', 'alki/dsls/assembly_type'
3
3
  register_lib_dir 'alki/dsls', 'alki/dsls/dsl'
4
- end
4
+ end
@@ -227,7 +227,7 @@ assembly = Alki.create_assembly do
227
227
  Logger.new STDOUT
228
228
  end
229
229
  end
230
- assembly.new.logger << "hello"
230
+ assembly.new.logger << "hello\n"
231
231
 
232
232
  #output: hello
233
233
  ```
@@ -251,7 +251,7 @@ assembly = Alki.create_assembly do
251
251
  logger STDOUT
252
252
  end
253
253
  end
254
- assembly.new.main_logger << "hello"
254
+ assembly.new.main_logger << "hello\n"
255
255
 
256
256
  #output: hello
257
257
  ```
@@ -265,9 +265,9 @@ Overlays are often most useful in groups where all services adhere to a common i
265
265
  can be used to perform aspect oriented programming like logging, validation, or access controls.
266
266
 
267
267
 
268
- ## Assemblies (assembly)
268
+ ## Mounting Assemblies (mount)
269
269
 
270
- Other assemblies can be mounted into your Assembly using the `assembly` command.
270
+ Other assemblies can be mounted into your Assembly using the `mount` command.
271
271
 
272
272
  The first argument is what the element should be named in the parent assembly. The optional second argument
273
273
  is the name of the assembly to be mounted. This should be formatted like a require string (relative path but
@@ -296,7 +296,7 @@ end
296
296
  Alki.create_assembly name: 'main_assembly' do
297
297
  set :val2, "two"
298
298
  # Mounts OtherAssembly as 'other'
299
- assembly :other, 'other_assembly'
299
+ mount :other, 'other_assembly'
300
300
  end
301
301
  instance = MainAssembly.new
302
302
  puts instance.other.val
@@ -331,7 +331,7 @@ end
331
331
 
332
332
  Alki.create_assembly name: 'main_assembly' do
333
333
  set :val, "hello"
334
- assembly :other, 'other_assembly' do
334
+ mount :other, 'other_assembly' do
335
335
  set :msg do
336
336
  val
337
337
  end
data/exe/alki ADDED
@@ -0,0 +1,275 @@
1
+ #!/usr/bin/env ruby
2
+ require 'fileutils'
3
+ require 'optparse'
4
+ require 'alki/support'
5
+
6
+ valid_addons = ["console"]
7
+
8
+ options = {
9
+ config_dir: nil,
10
+ primary_config: nil,
11
+ addons: [],
12
+ project_dir: Dir.pwd,
13
+ }
14
+ parser = OptionParser.new do |opts|
15
+ opts.banner = "Usage: alki init PROJECT_NAME [options]"
16
+
17
+ opts.on("-a", "--add[=ADDON]", "Add addon to project. Valid addons: #{valid_addons.join(', ')}") do |v|
18
+ unless valid_addons.include? v
19
+ puts "Invalid addon: #{v}"
20
+ exit 1
21
+ end
22
+ options[:addon] |= [v]
23
+ end
24
+
25
+ opts.on('-d','--directory=DIRECTORY', 'Project root, defaults to the current working directory') do |v|
26
+ options[:project_dir] = v
27
+ end
28
+
29
+ opts.on("-c", "--config=DIECTORY", "Override config dir (default \"config\")") do |v|
30
+ options[:config_dir] = v
31
+ end
32
+
33
+ opts.on("-p", "--primary=PRIMARY_CONFIG", "Override primary config (default \"assembly\")") do |v|
34
+ options[:primary_config] = v
35
+ end
36
+ end
37
+
38
+ parser.parse!
39
+
40
+ if ARGV.size != 2 || ARGV[0] != "init"
41
+ puts parser.banner
42
+ exit 1
43
+ end
44
+
45
+ unless ARGV[1] =~ %r{^[a-z0-9_]+(/[a-z0-9_]+)*$}
46
+ puts "Invalid project name. May only consist of lowercase letters, numbers, underscores, and forward slashes"
47
+ exit 1
48
+ end
49
+
50
+
51
+
52
+ class AlkiFileWriter
53
+ def initialize(root_dir)
54
+ @root_dir = root_dir
55
+ @changes = []
56
+ @triggers = []
57
+ end
58
+
59
+ def create(file,contents)
60
+ @changes << [:create,file: file,contents: contents,opts: {}]
61
+ end
62
+
63
+ def create_exec(file,contents)
64
+ @changes << [:create,file: file,contents: contents,opts: {exec: true}]
65
+ end
66
+
67
+ def check_create(file:, contents:, opts:)
68
+ path = abs_path( file)
69
+ if File.exists? path
70
+ if File.read(path) == contents
71
+ :skip
72
+ end
73
+ end
74
+ end
75
+
76
+ def desc_create(file:, contents:, opts: {})
77
+ path = abs_path( file)
78
+ if opts[:exec]
79
+ adj = "executable "
80
+ end
81
+ if File.exists? path
82
+ "Overwriting #{adj}#{file}!"
83
+ else
84
+ "Create #{adj}#{file}"
85
+ end
86
+ end
87
+
88
+ def do_create(file:, contents:, opts: {})
89
+ path = abs_path( file)
90
+ FileUtils.mkdir_p File.dirname(path)
91
+ File.write path, contents
92
+ FileUtils.chmod '+x', path if opts[:exec]
93
+ end
94
+
95
+ def opt_create(file,contents)
96
+ @changes << [:opt_create,file: file,contents: contents]
97
+ end
98
+
99
+ def check_opt_create(file:, contents:)
100
+ if File.exists? abs_path( file)
101
+ :skip
102
+ end
103
+ end
104
+
105
+ def desc_opt_create(opts)
106
+ desc_create opts
107
+ end
108
+
109
+ def do_opt_create(opts)
110
+ do_create opts
111
+ end
112
+
113
+ def add_line(file,line,opts={})
114
+ @changes << [:add_line,file: file,line: line,opts: opts]
115
+ end
116
+
117
+ def check_add_line(file:,line:,opts:)
118
+ if File.exists? abs_path(file)
119
+ File.open(file) do |f|
120
+ if opts[:after]
121
+ found = until f.eof?
122
+ break true if f.readline.chomp == opts[:after]
123
+ end
124
+ unless found
125
+ puts "File \"#{file}\" doesn't contain required line #{opts[:after]}"
126
+ return :abort
127
+ end
128
+ end
129
+ until f.eof?
130
+ l = f.readline
131
+ if opts[:match] ? l.chomp.match(opts[:match]) : (l.chomp == line)
132
+ return :skip
133
+ end
134
+ end
135
+ end
136
+ else
137
+ unless @changes.find {|c| [:create,:opt_create].include?(c[0]) && c[1][:file] == file}
138
+ puts "File \"#{file}\" doesn't exist!"
139
+ return :abort
140
+ end
141
+ end
142
+ end
143
+
144
+ def desc_add_line(file:,line:,opts:)
145
+ "Add line \"#{line}\" to #{file}"
146
+ end
147
+
148
+ def do_add_line(file:,line:,opts:)
149
+ if opts[:after]
150
+ File.write file, File.read(file).sub(/^#{Regexp.quote(opts[:after])}\n/){|m| m + line + "\n"}
151
+ else
152
+ File.open(file,'a') do |f|
153
+ f.puts line
154
+ end
155
+ end
156
+ end
157
+
158
+ def trigger(file,cmd)
159
+ @triggers << [file, cmd]
160
+ end
161
+
162
+ def check_trigger(changes,file)
163
+ changes.find {|c| c[1][:file] == file}
164
+ end
165
+
166
+ def desc_trigger(cmd:)
167
+ "Run \"#{cmd}\""
168
+ end
169
+
170
+ def do_trigger(cmd:)
171
+ system cmd
172
+ end
173
+
174
+ def check_changes
175
+ puts "Checking preconditions..."
176
+ abort = false
177
+ unless Dir.exists?(@root_dir)
178
+ puts "Root dir doesn't exist"
179
+ exit 1
180
+ end
181
+ do_changes = []
182
+ @changes.each do |(type,args)|
183
+ res = send "check_#{type}", args
184
+ abort = true if res == :abort
185
+ do_changes << [type,args] unless res == :skip
186
+ end
187
+ @triggers.each do |(file,cmd)|
188
+ if check_trigger do_changes, file
189
+ do_changes << [:trigger,cmd: cmd]
190
+ end
191
+ end
192
+ exit 1 if abort
193
+ do_changes
194
+ end
195
+
196
+ def print_overview(changes)
197
+ puts "Overview of changes to be made:"
198
+
199
+ changes.each do |(type,args)|
200
+ desc = send "desc_#{type}", args
201
+ puts " #{desc}" if desc
202
+ end
203
+ print "Proceed? "
204
+ resp = STDIN.gets.chomp
205
+ unless resp =~ /^y(es?)?/i
206
+ puts "Aborting"
207
+ exit
208
+ end
209
+ end
210
+
211
+ def write
212
+ puts "Using project root: #{@root_dir}\n"
213
+ do_changes = check_changes
214
+ print_overview do_changes
215
+
216
+ puts "Writing changes..."
217
+ do_changes.each do |(type,args)|
218
+ send "do_#{type}", args
219
+ end
220
+ puts "Done"
221
+ end
222
+
223
+ def abs_path(p)
224
+ File.expand_path(p,@root_dir)
225
+ end
226
+ end
227
+
228
+ project_name = ARGV[1]
229
+
230
+ fw = AlkiFileWriter.new config[:project_dir]
231
+
232
+ config_dir = options[:config_dir] || 'config'
233
+ primary_config = options[:primary_config] || 'assembly'
234
+ primary_config_path = File.join(config_dir,primary_config+'.rb')
235
+ fw.opt_create primary_config_path, <<END
236
+ Alki do
237
+ # Assembly config goes here
238
+ end
239
+ END
240
+
241
+ opts = []
242
+ opts << "config_dir: '#{options[:config_dir]}'" if options[:config_dir]
243
+ opts << "primary_config: '#{options[:primary_config]}'" if options[:primary_config]
244
+ unless opts.empty?
245
+ opt_str = " #{opts.join(', ')}"
246
+ end
247
+ fw.create "lib/#{project_name}.rb", <<END
248
+ require 'alki'
249
+ Alki.project_assembly!#{opt_str}
250
+ END
251
+
252
+ fw.opt_create "Gemfile", <<END
253
+ source "https://rubygems.org"
254
+ END
255
+
256
+ fw.trigger 'Gemfile', 'bundle install'
257
+
258
+ fw.add_line "Gemfile", "gem 'alki'", match: /^gem ['"]alki['"]/
259
+
260
+ if options[:addons].include? "console"
261
+ fw.add_line "Gemfile", "gem 'alki-console'", match: /^gem ['"]alki-console['"]/
262
+
263
+ name = project_name.tr('/','-')
264
+ fw.add_line primary_config_path, " mount :console, 'alki/console', name: '#{name}'", match: /^\s*assembly :console/, after: 'Alki do'
265
+
266
+ fw.create_exec 'bin/console', <<END
267
+ #!/usr/bin/env ruby
268
+ require 'bundler/setup'
269
+ require 'alki/bin'
270
+ require '#{project_name}'
271
+ #{Alki::Support.classify(project_name)}.new.console.run
272
+ END
273
+ end
274
+
275
+ fw.write
@@ -0,0 +1,113 @@
1
+ require 'alki/assembly'
2
+ require 'alki/class_builder'
3
+ require 'alki/dsl'
4
+ require 'alki/support'
5
+
6
+ module Alki
7
+ module Assembly
8
+ class Builder
9
+ def initialize
10
+ @config_dir = nil
11
+ @assembly_name = nil
12
+ @definition = nil
13
+ end
14
+
15
+ attr_reader :config_dir, :assembly_name, :definition
16
+
17
+ def self.build(opts={},&blk)
18
+ new.build(opts,&blk)
19
+ end
20
+
21
+ def build(opts={},&blk)
22
+ build_assembly blk if blk
23
+ if opts[:config_dir]
24
+ context = if opts[:project_assembly]
25
+ File.dirname opts[:project_assembly]
26
+ else
27
+ Dir.pwd
28
+ end
29
+ @config_dir = File.expand_path opts[:config_dir], context
30
+ end
31
+ set_assembly_name opts[:name] if opts[:name]
32
+ setup_project_assembly opts[:project_assembly] if opts[:project_assembly]
33
+ register_config_directory if @config_dir
34
+ if blk
35
+ build_assembly blk
36
+ else
37
+ load_assembly_file opts[:primary_config]
38
+ end
39
+ build_empty_assembly unless definition
40
+ build_class
41
+ end
42
+
43
+ def setup_project_assembly(path)
44
+ root = Alki::Support.find_root(path) do |dir|
45
+ File.exists?(File.join(dir,'config','assembly.rb')) ||
46
+ File.exists?(File.join(dir,'Gemfile')) ||
47
+ !Dir.glob(File.join(dir,'*.gemspec')).empty?
48
+ end
49
+ if root
50
+ unless @config_dir
51
+ config_dir = File.join(root,'config')
52
+ @config_dir = config_dir if File.exists? config_dir
53
+ end
54
+
55
+ unless @assembly_name
56
+ lib_dir = File.join(root,'lib')
57
+ name = Alki::Support.path_name path, lib_dir
58
+ unless name
59
+ raise "Can't auto-detect name of assembly"
60
+ end
61
+ set_assembly_name name
62
+ end
63
+ end
64
+ end
65
+
66
+ def set_assembly_name(name)
67
+ @assembly_name = name
68
+ end
69
+
70
+ def register_config_directory
71
+ opts = {config_dir: @config_dir}
72
+ opts[:prefix] = File.join(@assembly_name,'alki_config') if @assembly_name
73
+ Alki::Dsl.register_dir @config_dir, 'alki/dsls/assembly', opts
74
+ end
75
+
76
+ def load_assembly_file(name = nil)
77
+ name ||= 'assembly'
78
+ if @config_dir
79
+ assembly_config_path = File.join(@config_dir,"#{name}.rb")
80
+ if File.exists? assembly_config_path
81
+ @definition = Alki::Dsl.load(assembly_config_path)[:class]
82
+ true
83
+ end
84
+ end
85
+ end
86
+
87
+ def build_empty_assembly
88
+ build_assembly ->{}
89
+ end
90
+
91
+ def build_assembly(blk)
92
+ @definition = Alki::Dsl.build('alki/dsls/assembly', config_dir: @config_dir, &blk)[:class]
93
+ end
94
+
95
+ def build_class
96
+ definition = @definition
97
+ Alki::ClassBuilder.build(
98
+ prefix: '',
99
+ name: @assembly_name,
100
+ class_modules: [Alki::Assembly],
101
+ type: :module,
102
+ class_methods: {
103
+ definition: {
104
+ body: ->{
105
+ definition
106
+ }
107
+ },
108
+ }
109
+ )
110
+ end
111
+ end
112
+ end
113
+ end