alki 0.8.0 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.adoc +108 -6
- data/alki.gemspec +2 -2
- data/bin/alki +17 -0
- data/config/dsls.rb +2 -2
- data/doc/assembly_dsl.adoc +6 -6
- data/exe/alki +275 -0
- data/lib/alki/assembly/builder.rb +113 -0
- data/lib/alki/assembly/executor.rb +127 -0
- data/lib/alki/assembly/handler_base.rb +21 -0
- data/lib/alki/assembly/instance.rb +21 -0
- data/lib/alki/assembly/types/assembly.rb +92 -0
- data/lib/alki/assembly/types/factory.rb +29 -0
- data/lib/alki/assembly/types/func.rb +12 -0
- data/lib/alki/assembly/types/group.rb +39 -0
- data/lib/alki/assembly/types/override.rb +40 -0
- data/lib/alki/assembly/types/proc_value.rb +18 -0
- data/lib/alki/assembly/types/service.rb +27 -0
- data/lib/alki/assembly/types/value.rb +9 -0
- data/lib/alki/assembly.rb +21 -40
- data/lib/alki/dsls/assembly.rb +10 -12
- data/lib/alki/dsls/assembly_group.rb +92 -0
- data/lib/alki/dsls/assembly_type.rb +5 -15
- data/lib/alki/execution/cache_entry.rb +16 -0
- data/lib/alki/execution/context.rb +29 -0
- data/lib/alki/execution/context_class_builder.rb +36 -0
- data/lib/alki/execution/value_context.rb +14 -0
- data/lib/alki/overlay_delegator.rb +8 -20
- data/lib/alki/overlay_info.rb +3 -0
- data/lib/alki/override_builder.rb +6 -4
- data/lib/alki/service_delegator.rb +3 -3
- data/lib/alki/version.rb +1 -1
- data/lib/alki.rb +4 -4
- data/test/feature/alki_test.rb +1 -2
- data/test/feature/example_test.rb +2 -3
- data/test/feature/factories_test.rb +48 -0
- data/test/feature/overlays_test.rb +225 -0
- data/test/feature/overrides_test.rb +1 -2
- data/test/feature/pseudo_elements_test.rb +67 -0
- data/test/feature_test_helper.rb +1 -0
- data/test/fixtures/example/config/assembly.rb +11 -2
- data/test/fixtures/example/config/handlers.rb +2 -7
- data/test/fixtures/example/lib/log_overlay.rb +3 -3
- data/test/integration/dsls/assembly_test.rb +3 -8
- data/test/integration/dsls/assembly_type_test.rb +2 -2
- data/test/integration/dsls/service_dsl_test.rb +2 -2
- metadata +36 -18
- data/lib/alki/assembly_builder.rb +0 -109
- data/lib/alki/assembly_executor.rb +0 -129
- data/lib/alki/assembly_handler_base.rb +0 -19
- data/lib/alki/dsls/assembly_type_dsl.rb +0 -21
- data/lib/alki/dsls/assembly_types/assembly.rb +0 -101
- data/lib/alki/dsls/assembly_types/group.rb +0 -41
- data/lib/alki/dsls/assembly_types/load.rb +0 -31
- data/lib/alki/dsls/assembly_types/overlay.rb +0 -9
- data/lib/alki/dsls/assembly_types/value.rb +0 -100
- data/test/test_helper.rb +0 -1
@@ -0,0 +1,127 @@
|
|
1
|
+
require 'alki/execution/context_class_builder'
|
2
|
+
require 'alki/execution/cache_entry'
|
3
|
+
require 'thread'
|
4
|
+
|
5
|
+
module Alki
|
6
|
+
InvalidPathError = Class.new(StandardError)
|
7
|
+
module Assembly
|
8
|
+
class Executor
|
9
|
+
def initialize(assembly,overlays)
|
10
|
+
@assembly = assembly
|
11
|
+
@overlays = overlays
|
12
|
+
@data = {}
|
13
|
+
@semaphore = Monitor.new
|
14
|
+
clear
|
15
|
+
end
|
16
|
+
|
17
|
+
def clear
|
18
|
+
@lookup_cache = {}
|
19
|
+
@call_cache = {}
|
20
|
+
@context_cache = {}
|
21
|
+
@processed_overlays = false
|
22
|
+
end
|
23
|
+
|
24
|
+
def call(path,*args,&blk)
|
25
|
+
execute({},path,args,blk)
|
26
|
+
end
|
27
|
+
|
28
|
+
def execute(meta,path,args,blk)
|
29
|
+
cache_entry = @call_cache[path]
|
30
|
+
if cache_entry
|
31
|
+
if cache_entry.status == :building
|
32
|
+
raise "Circular element reference found"
|
33
|
+
end
|
34
|
+
else
|
35
|
+
@semaphore.synchronize do
|
36
|
+
cache_entry = @call_cache[path]
|
37
|
+
unless cache_entry
|
38
|
+
cache_entry = @call_cache[path] = Alki::Execution::CacheEntry.new
|
39
|
+
action = lookup(path)
|
40
|
+
if action[:build]
|
41
|
+
build_meta = meta.merge(building: path.join('.'))
|
42
|
+
build_action = action[:build].merge(scope: action[:scope],modules: action[:modules])
|
43
|
+
call_value(*process_action(build_action),build_meta,[action])
|
44
|
+
end
|
45
|
+
cache_entry.finish *process_action(action)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
call_value(cache_entry.type,cache_entry.value,meta,args,blk)
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def process_overlays
|
55
|
+
unless @processed_overlays
|
56
|
+
@processed_overlays = true
|
57
|
+
@data[:overlays] = {}
|
58
|
+
@overlays.each do |(from,info)|
|
59
|
+
target = canonical_path(from,info.target) or
|
60
|
+
raise InvalidPathError.new("Invalid overlay target #{info.target.join('.')}")
|
61
|
+
overlay = canonical_path(from,info.overlay) or
|
62
|
+
raise InvalidPathError.new("Invalid overlay path #{info.overlay.join('.')}")
|
63
|
+
(@data[:overlays][target]||=[]) << [overlay,info.args]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def lookup(path)
|
69
|
+
process_overlays
|
70
|
+
@lookup_cache[path] ||= lookup_elem(path).tap do |elem|
|
71
|
+
unless elem
|
72
|
+
raise InvalidPathError.new("Invalid path #{path.inspect}")
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def lookup_elem(path)
|
78
|
+
data = @data.dup
|
79
|
+
elem = @assembly
|
80
|
+
path.each do |key|
|
81
|
+
elem = elem.index data, key
|
82
|
+
return nil unless elem
|
83
|
+
end
|
84
|
+
elem.output data
|
85
|
+
end
|
86
|
+
|
87
|
+
|
88
|
+
def canonical_path(from,path)
|
89
|
+
scope = lookup(from)[:full_scope]
|
90
|
+
path.inject(nil) do |p,elem|
|
91
|
+
scope = lookup(p)[:scope] if p
|
92
|
+
scope[elem]
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def process_action(action)
|
97
|
+
if action.key?(:value)
|
98
|
+
[:value,action[:value]]
|
99
|
+
elsif action[:proc]
|
100
|
+
if action[:scope]
|
101
|
+
[:class,context_class(action)]
|
102
|
+
else
|
103
|
+
[:proc,action[:proc]]
|
104
|
+
end
|
105
|
+
end or raise "Invalid action"
|
106
|
+
end
|
107
|
+
|
108
|
+
def call_value(type,value,meta,args=[],blk=nil)
|
109
|
+
case type
|
110
|
+
when :value then value
|
111
|
+
when :proc then proc.call *args, &blk
|
112
|
+
when :class then value.new(self,meta).__call__ *args, &blk
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def context_class(action)
|
117
|
+
desc = {
|
118
|
+
scope: action[:scope],
|
119
|
+
body: action[:proc],
|
120
|
+
modules: action[:modules],
|
121
|
+
methods: action[:methods]
|
122
|
+
}
|
123
|
+
@context_cache[desc] ||= Alki::Execution::ContextClassBuilder.build(desc)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Alki
|
2
|
+
module Assembly
|
3
|
+
class HandlerBase
|
4
|
+
def initialize(elem,data,key=nil)
|
5
|
+
@elem = elem
|
6
|
+
@data = data
|
7
|
+
@key = key
|
8
|
+
end
|
9
|
+
|
10
|
+
attr_reader :elem, :data, :key
|
11
|
+
|
12
|
+
def index
|
13
|
+
raise NotImplementedError.new("Can't index into this element")
|
14
|
+
end
|
15
|
+
|
16
|
+
def output
|
17
|
+
raise NotImplementedError.new("Can't output this element")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Alki
|
2
|
+
module Assembly
|
3
|
+
class Instance
|
4
|
+
def initialize(executor)
|
5
|
+
@executor = executor
|
6
|
+
end
|
7
|
+
|
8
|
+
def root
|
9
|
+
@root ||= @executor.call []
|
10
|
+
end
|
11
|
+
|
12
|
+
def respond_to_missing?(name,include_all)
|
13
|
+
root.respond_to? name
|
14
|
+
end
|
15
|
+
|
16
|
+
def method_missing(name,*args,&blk)
|
17
|
+
root.send name, *args, &blk
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'alki/assembly/types/override'
|
2
|
+
|
3
|
+
Alki do
|
4
|
+
attr :root
|
5
|
+
attr(:overrides) { nil }
|
6
|
+
|
7
|
+
index do
|
8
|
+
data[:scope] ||= {}
|
9
|
+
data[:prefix] ||= []
|
10
|
+
data[:overlays] ||= {}
|
11
|
+
|
12
|
+
if key == :original
|
13
|
+
update_main data
|
14
|
+
if overrides
|
15
|
+
overrides.children.keys.each do |k|
|
16
|
+
data[:scope][k] = data[:prefix] + [k]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
root
|
20
|
+
else
|
21
|
+
if overrides
|
22
|
+
data.replace(
|
23
|
+
main: deep_copy(data),
|
24
|
+
override: data.dup,
|
25
|
+
)
|
26
|
+
update_main data[:main]
|
27
|
+
update_override data[:override]
|
28
|
+
override.index data, key
|
29
|
+
else
|
30
|
+
update_main data
|
31
|
+
root.index data, key
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
output do
|
37
|
+
data[:scope] ||= {}
|
38
|
+
data[:prefix] ||= []
|
39
|
+
data[:overlays] ||= {}
|
40
|
+
|
41
|
+
output = root.output(data)
|
42
|
+
add_parent_path output[:scope]
|
43
|
+
update_scope data, output[:full_scope]
|
44
|
+
output[:scope].merge! overrides.output(data)[:scope] if overrides
|
45
|
+
output[:full_scope].merge! overrides.output(data)[:full_scope] if overrides
|
46
|
+
output
|
47
|
+
end
|
48
|
+
|
49
|
+
def deep_copy(val)
|
50
|
+
if val.is_a?(Hash)
|
51
|
+
val.inject({}) do |h,(k,v)|
|
52
|
+
h[k] = deep_copy v
|
53
|
+
h
|
54
|
+
end
|
55
|
+
elsif val.is_a?(Array)
|
56
|
+
val.inject([]) do |a,v|
|
57
|
+
a.push deep_copy v
|
58
|
+
end
|
59
|
+
else
|
60
|
+
val
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def update_main(data)
|
65
|
+
data[:scope] = {assembly: data[:scope][:assembly], root: []}
|
66
|
+
update_scope data
|
67
|
+
data[:scope][:assembly] = data[:prefix].dup
|
68
|
+
end
|
69
|
+
|
70
|
+
def update_override(data)
|
71
|
+
data[:scope][:root] ||= []
|
72
|
+
add_original data[:scope], data
|
73
|
+
end
|
74
|
+
|
75
|
+
def update_scope(data,scope=data[:scope])
|
76
|
+
add_parent_path scope, data
|
77
|
+
add_original scope, data
|
78
|
+
end
|
79
|
+
|
80
|
+
def add_parent_path(scope,data=self.data)
|
81
|
+
parent_path = data[:scope][:assembly]||nil
|
82
|
+
scope[:parent] = parent_path if parent_path
|
83
|
+
end
|
84
|
+
|
85
|
+
def add_original(scope,data=self.data)
|
86
|
+
scope[:original] = data[:prefix] + [:original]
|
87
|
+
end
|
88
|
+
|
89
|
+
def override
|
90
|
+
Alki::Assembly::Types::Override.new root, overrides
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
Alki do
|
2
|
+
require 'alki/execution/value_context'
|
3
|
+
|
4
|
+
attr :block
|
5
|
+
|
6
|
+
output do
|
7
|
+
{
|
8
|
+
modules: [Alki::Execution::ValueContext],
|
9
|
+
scope: data[:scope],
|
10
|
+
build: {
|
11
|
+
methods: {
|
12
|
+
__build__: block
|
13
|
+
},
|
14
|
+
proc: ->(desc) {
|
15
|
+
desc[:methods] = {
|
16
|
+
__create__: __build__
|
17
|
+
}
|
18
|
+
desc[:proc] = ->(*args,&blk) {
|
19
|
+
if !args.empty? || blk
|
20
|
+
__create__ *args, &blk
|
21
|
+
else
|
22
|
+
method(:__create__)
|
23
|
+
end
|
24
|
+
}
|
25
|
+
}
|
26
|
+
}
|
27
|
+
}
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
Alki do
|
2
|
+
require 'alki/execution/context'
|
3
|
+
|
4
|
+
attr(:children){ {} }
|
5
|
+
|
6
|
+
index do
|
7
|
+
update_scope children, data[:prefix], data[:scope]
|
8
|
+
|
9
|
+
data[:overlays] = data[:overlays].inject({}) do |no,(target,overlays)|
|
10
|
+
target = target.dup
|
11
|
+
if target.empty? || target.shift == key.to_sym
|
12
|
+
(no[target]||=[]).push *overlays
|
13
|
+
end
|
14
|
+
no
|
15
|
+
end
|
16
|
+
|
17
|
+
data[:prefix] << key
|
18
|
+
|
19
|
+
children[key]
|
20
|
+
end
|
21
|
+
|
22
|
+
output do
|
23
|
+
{
|
24
|
+
full_scope: update_scope(children, data[:prefix], data[:scope]),
|
25
|
+
scope: update_scope(children,data[:prefix]),
|
26
|
+
modules: [Alki::Execution::Context],
|
27
|
+
proc: ->{self}
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
def update_scope(children, prefix, scope=nil)
|
32
|
+
scope ||= {}
|
33
|
+
prefix ||= []
|
34
|
+
children.keys.inject(scope) do |h,k|
|
35
|
+
h.merge! k => (prefix+[k])
|
36
|
+
end
|
37
|
+
scope
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'alki/assembly/types/override'
|
2
|
+
|
3
|
+
Alki do
|
4
|
+
attr :main
|
5
|
+
attr :override
|
6
|
+
|
7
|
+
index do
|
8
|
+
main_child = main.index data[:main], key
|
9
|
+
override_child = override.index data[:override], key
|
10
|
+
|
11
|
+
if main_child && override_child
|
12
|
+
(data[:main][:scope]||={}).merge! (data[:override][:scope]||{})
|
13
|
+
data[:main][:overlays]||={}
|
14
|
+
if data[:override][:overlays]
|
15
|
+
data[:override][:overlays].each do |target,overlays|
|
16
|
+
(data[:main][:overlays][target]||=[]).push *overlays
|
17
|
+
end
|
18
|
+
end
|
19
|
+
data[:override][:overlays]=data[:main][:overlays].dup
|
20
|
+
Alki::Assembly::Types::Override.new main_child, override_child
|
21
|
+
elsif main_child
|
22
|
+
data.replace data[:main]
|
23
|
+
main_child
|
24
|
+
elsif override_child
|
25
|
+
data.replace data[:override]
|
26
|
+
override_child
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
output do
|
31
|
+
result = override.output(data[:override])
|
32
|
+
if result[:type] == :group
|
33
|
+
main_result = main.output(data[:main])
|
34
|
+
if main_result[:type] == :group
|
35
|
+
result[:scope] = main_result[:scope].merge result[:scope]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
result
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
Alki do
|
2
|
+
require 'alki/execution/value_context'
|
3
|
+
|
4
|
+
attr :proc
|
5
|
+
|
6
|
+
output do
|
7
|
+
{
|
8
|
+
build: {
|
9
|
+
methods: {
|
10
|
+
__build__: proc
|
11
|
+
},
|
12
|
+
proc: ->(desc) {desc[:value] = __build__}
|
13
|
+
},
|
14
|
+
modules: [Alki::Execution::ValueContext],
|
15
|
+
scope: data[:scope]
|
16
|
+
}
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
Alki do
|
2
|
+
require 'alki/execution/value_context'
|
3
|
+
|
4
|
+
attr :block
|
5
|
+
|
6
|
+
output do
|
7
|
+
overlays = data[:overlays][[]]||[]
|
8
|
+
{
|
9
|
+
build: {
|
10
|
+
methods: {
|
11
|
+
__build__: block
|
12
|
+
},
|
13
|
+
proc: -> (elem) {
|
14
|
+
elem[:value] = overlays.inject(__build__) do |val,(overlay,args)|
|
15
|
+
overlay = root.lookup(overlay)
|
16
|
+
if !overlay.respond_to?(:call) && overlay.respond_to?(:new)
|
17
|
+
overlay = overlay.method(:new)
|
18
|
+
end
|
19
|
+
overlay.call val, *args
|
20
|
+
end
|
21
|
+
},
|
22
|
+
},
|
23
|
+
modules: [Alki::Execution::ValueContext],
|
24
|
+
scope: data[:scope],
|
25
|
+
}
|
26
|
+
end
|
27
|
+
end
|
data/lib/alki/assembly.rb
CHANGED
@@ -1,53 +1,34 @@
|
|
1
|
-
require 'alki/assembly_executor'
|
2
1
|
require 'alki/override_builder'
|
3
|
-
require 'alki/
|
2
|
+
require 'alki/assembly/types/assembly'
|
3
|
+
require 'alki/assembly/types/group'
|
4
|
+
require 'alki/assembly/instance'
|
5
|
+
require 'alki/assembly/executor'
|
4
6
|
|
5
7
|
module Alki
|
6
8
|
module Assembly
|
7
9
|
def new(overrides={},&blk)
|
8
|
-
|
9
|
-
|
10
|
+
overrides_info = OverrideBuilder.build(overrides,&blk)
|
11
|
+
override_root = overrides_info[:root] || build(:group)
|
10
12
|
|
11
|
-
|
12
|
-
|
13
|
-
end
|
13
|
+
assembly = build :assembly, root, override_root
|
14
|
+
executor = Executor.new(assembly, overlays+overrides_info[:overlays])
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
Alki::Support.load_class("alki/assembly_types/value").new assembly_options[:load_path]
|
20
|
-
else
|
21
|
-
nil
|
22
|
-
end
|
23
|
-
|
24
|
-
Alki::Support.load_class("alki/assembly_types/assembly").new root, config_dir, OverrideBuilder.build(overrides,&blk)
|
16
|
+
override_root.children[:assembly_instance] = build(:service,->{
|
17
|
+
Instance.new(executor)
|
18
|
+
})
|
19
|
+
executor.call [:assembly_instance]
|
25
20
|
end
|
26
21
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
@cache = {}
|
31
|
-
@opts = opts
|
32
|
-
end
|
33
|
-
|
34
|
-
def root
|
35
|
-
@root ||= __executor__.call @assembly, @cache, []
|
36
|
-
end
|
37
|
-
|
38
|
-
def respond_to_missing?(name,include_all)
|
39
|
-
root.respond_to? name
|
40
|
-
end
|
41
|
-
|
42
|
-
def method_missing(name,*args,&blk)
|
43
|
-
root.send name, *args, &blk
|
44
|
-
end
|
22
|
+
def build(type,*args)
|
23
|
+
Alki::Support.load_class("alki/assembly/types/#{type}").new *args
|
24
|
+
end
|
45
25
|
|
46
|
-
|
26
|
+
def root
|
27
|
+
self.definition.root
|
28
|
+
end
|
47
29
|
|
48
|
-
|
49
|
-
|
50
|
-
end
|
30
|
+
def overlays
|
31
|
+
self.definition.overlays
|
51
32
|
end
|
52
33
|
end
|
53
|
-
end
|
34
|
+
end
|
data/lib/alki/dsls/assembly.rb
CHANGED
@@ -1,20 +1,18 @@
|
|
1
1
|
Alki do
|
2
2
|
require_dsl 'alki/dsls/class'
|
3
|
-
require_dsl 'alki/dsls/
|
4
|
-
require_dsl 'alki/dsls/assembly_types/value'
|
5
|
-
require_dsl 'alki/dsls/assembly_types/assembly'
|
6
|
-
require_dsl 'alki/dsls/assembly_types/load'
|
7
|
-
require_dsl 'alki/dsls/assembly_types/overlay'
|
8
|
-
|
9
|
-
init do
|
10
|
-
ctx[:elems] = {}
|
11
|
-
ctx[:overlays] = []
|
12
|
-
end
|
3
|
+
require_dsl 'alki/dsls/assembly_group'
|
13
4
|
|
14
5
|
finish do
|
15
|
-
|
6
|
+
add :config_dir, build(:value, ctx[:config_dir])
|
7
|
+
prefix_overlays :original, ctx[:overlays]
|
8
|
+
|
9
|
+
root = ctx[:root]
|
10
|
+
overlays = ctx[:overlays]
|
16
11
|
add_class_method :root do
|
17
12
|
root
|
18
13
|
end
|
14
|
+
add_class_method :overlays do
|
15
|
+
overlays
|
16
|
+
end
|
19
17
|
end
|
20
|
-
end
|
18
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'alki/override_builder'
|
2
|
+
require 'alki/support'
|
3
|
+
require 'alki/overlay_info'
|
4
|
+
|
5
|
+
Alki do
|
6
|
+
require_dsl 'alki/dsls/dsl'
|
7
|
+
|
8
|
+
init do
|
9
|
+
ctx[:root] = build(:group,{})
|
10
|
+
ctx[:overlays] = []
|
11
|
+
end
|
12
|
+
|
13
|
+
helper :add do |name,elem|
|
14
|
+
ctx[:root].children[name.to_sym] = elem
|
15
|
+
nil
|
16
|
+
end
|
17
|
+
|
18
|
+
helper :build do |type,*args|
|
19
|
+
Alki::Support.load_class("alki/assembly/types/#{type}").new *args
|
20
|
+
end
|
21
|
+
|
22
|
+
helper :prefix_overlays do |*prefix,overlays|
|
23
|
+
overlays.each do |overlay|
|
24
|
+
overlay[0].unshift *prefix
|
25
|
+
end
|
26
|
+
overlays
|
27
|
+
end
|
28
|
+
|
29
|
+
helper :update_overlays do |*prefix,overlays|
|
30
|
+
ctx[:overlays].push *prefix_overlays(*prefix,overlays)
|
31
|
+
end
|
32
|
+
|
33
|
+
dsl_method :config_dir do
|
34
|
+
ctx[:config_dir]
|
35
|
+
end
|
36
|
+
|
37
|
+
dsl_method :set do |name,value=nil,&blk|
|
38
|
+
if blk
|
39
|
+
add name, build(:proc_value, blk)
|
40
|
+
else
|
41
|
+
add name, build(:value, value)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
dsl_method :service do |name,&blk|
|
46
|
+
add name, build(:service, blk)
|
47
|
+
end
|
48
|
+
|
49
|
+
dsl_method :factory do |name,&blk|
|
50
|
+
add name, build(:factory, blk)
|
51
|
+
end
|
52
|
+
|
53
|
+
dsl_method :func do |name,&blk|
|
54
|
+
add name, build(:func, blk)
|
55
|
+
end
|
56
|
+
|
57
|
+
dsl_method :group do |name,&blk|
|
58
|
+
grp = Alki::Dsls::AssemblyGroup.build(&blk)
|
59
|
+
add name, grp[:root]
|
60
|
+
update_overlays name, grp[:overlays]
|
61
|
+
end
|
62
|
+
|
63
|
+
dsl_method :load do |group_name,name=group_name.to_s|
|
64
|
+
grp = Alki::Dsl.load(File.expand_path(name+'.rb',ctx[:config_dir]))[:class]
|
65
|
+
add name, grp.root
|
66
|
+
update_overlays name, grp.overlays
|
67
|
+
end
|
68
|
+
|
69
|
+
dsl_method :mount do |name,pkg=name.to_s,**overrides,&blk|
|
70
|
+
klass = Alki::Support.load_class pkg
|
71
|
+
mounted_assemblies = klass.overlays.map do |(path,info)|
|
72
|
+
[path.dup,info]
|
73
|
+
end
|
74
|
+
update_overlays name, mounted_assemblies
|
75
|
+
|
76
|
+
overrides = Alki::OverrideBuilder.build overrides, &blk
|
77
|
+
update_overlays name, overrides[:overlays]
|
78
|
+
|
79
|
+
add name, build(:assembly, klass.root, overrides[:root])
|
80
|
+
end
|
81
|
+
|
82
|
+
dsl_method :overlay do |target,overlay,*args|
|
83
|
+
(ctx[:overlays]||=[]) << [
|
84
|
+
[],
|
85
|
+
Alki::OverlayInfo.new(
|
86
|
+
target.to_s.split('.').map(&:to_sym),
|
87
|
+
overlay.to_s.split('.').map(&:to_sym),
|
88
|
+
args
|
89
|
+
)
|
90
|
+
]
|
91
|
+
end
|
92
|
+
end
|
@@ -1,10 +1,10 @@
|
|
1
|
-
require 'alki/
|
1
|
+
require 'alki/assembly/handler_base'
|
2
2
|
|
3
3
|
Alki do
|
4
4
|
require_dsl 'alki/dsls/class'
|
5
5
|
|
6
6
|
init do
|
7
|
-
set_super_class Alki::
|
7
|
+
set_super_class Alki::Assembly::HandlerBase, subclass: 'Handler'
|
8
8
|
|
9
9
|
add_method :handler, private: true do |*args|
|
10
10
|
self.class::Handler.new(self,*args)
|
@@ -18,23 +18,13 @@ Alki do
|
|
18
18
|
handler(*args).output
|
19
19
|
end
|
20
20
|
|
21
|
-
add_method :lookup do |path,data={}|
|
22
|
-
data = data.dup
|
23
|
-
elem = self
|
24
|
-
path.each do |key|
|
25
|
-
elem = elem.index data, key
|
26
|
-
return nil unless elem
|
27
|
-
end
|
28
|
-
elem.output data
|
29
|
-
end
|
30
|
-
|
31
21
|
# Add defined methods to handler class
|
32
22
|
class_builder('Handler')[:module] = class_builder[:module]
|
33
23
|
end
|
34
24
|
|
35
|
-
dsl_method :attr do |name
|
25
|
+
dsl_method :attr do |name,&default|
|
36
26
|
add_delegator name, :@elem, subclass: 'Handler'
|
37
|
-
add_initialize_param name, default
|
27
|
+
add_initialize_param name, &default
|
38
28
|
add_accessor name
|
39
29
|
end
|
40
30
|
|
@@ -45,4 +35,4 @@ Alki do
|
|
45
35
|
dsl_method :output do |&blk|
|
46
36
|
add_method :output, subclass: 'Handler', &blk
|
47
37
|
end
|
48
|
-
end
|
38
|
+
end
|