alki 0.9.1 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.adoc +8 -88
- data/alki.gemspec +2 -2
- data/exe/alki +2 -1
- data/lib/alki/assembly/builder.rb +29 -23
- data/lib/alki/assembly/executor.rb +57 -31
- data/lib/alki/assembly/{handler_base.rb → handler.rb} +1 -1
- data/lib/alki/assembly/instance.rb +9 -2
- data/lib/alki/assembly/type.rb +19 -0
- data/lib/alki/assembly/types/assembly.rb +1 -0
- data/lib/alki/assembly/types/factory.rb +2 -2
- data/lib/alki/assembly/types/func.rb +2 -2
- data/lib/alki/assembly/types/group.rb +19 -3
- data/lib/alki/assembly/types/override.rb +0 -7
- data/lib/alki/assembly/types/proc_value.rb +2 -2
- data/lib/alki/assembly/types/service.rb +24 -13
- data/lib/alki/assembly.rb +7 -6
- data/lib/alki/dsls/assembly.rb +3 -4
- data/lib/alki/dsls/assembly_group.rb +47 -26
- data/lib/alki/dsls/assembly_type.rb +4 -14
- data/lib/alki/execution/context.rb +17 -20
- data/lib/alki/execution/context_class_builder.rb +16 -2
- data/lib/alki/execution/helpers.rb +29 -0
- data/lib/alki/execution/reference.rb +18 -0
- data/lib/alki/execution/value_helpers.rb +14 -0
- data/lib/alki/overlay_info.rb +1 -1
- data/lib/alki/override_builder.rb +3 -3
- data/lib/alki/version.rb +1 -1
- data/lib/alki_loader.rb +2 -0
- data/test/feature/alki_test.rb +3 -5
- data/test/feature/example_test.rb +1 -4
- data/test/feature/overlays_test.rb +34 -0
- data/test/feature/pseudo_elements_test.rb +1 -1
- data/test/feature/reference_overlays_test.rb +24 -0
- data/test/feature/tags_test.rb +77 -0
- data/test/feature_test_helper.rb +34 -0
- data/test/integration/dsls/assembly_test.rb +2 -2
- data/test/integration/dsls/assembly_type_test.rb +1 -1
- data/test/integration/dsls/service_dsl_test.rb +1 -1
- metadata +16 -16
- data/config/dsls.rb +0 -4
- data/lib/alki/execution/value_context.rb +0 -23
- data/lib/alki/reloadable_delegator.rb +0 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bc042cd47800b613d12e02456c24d25afc170f7b
|
4
|
+
data.tar.gz: 1ab703cbc5c5458d181f3b8d2a4c357d4d9c4056
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b85b7153906906aaabb7d3dfc18e6060765f68bcf3a2885972acbbbd1c3d6a01a15b5c112205dc8fa0f64cf8403f056dd9091fadc2849e3051806cb4fe3fb183
|
7
|
+
data.tar.gz: b4dabbf9b1b3514ae65e189334848768670839d4e086bb6160158154ece8b7041def60184036e819c15df41de971ebb126849c1db62cb52917014615995f0abd
|
data/README.adoc
CHANGED
@@ -1,19 +1,20 @@
|
|
1
1
|
# What is Alki?
|
2
|
-
:toc:
|
3
2
|
|
4
|
-
Alki is a small framework for
|
5
|
-
helpers for testing, creating executables, and
|
3
|
+
Alki is a small framework for Ruby that provides a powerful dependency injection and program
|
4
|
+
management system with helpers for testing, creating executables, and writing DSLs.
|
6
5
|
|
7
6
|
It's goal is to remove uncertainty and friction when building Ruby projects, allowing developers to focus on
|
8
7
|
implementing business logic. It can be used alongside other frameworks such as Ruby on Rails.
|
9
8
|
|
10
|
-
Alki tries to combine
|
9
|
+
Alki tries to combine time tested software engineering concepts such as
|
11
10
|
https://en.wikipedia.org/wiki/SOLID_(object-oriented_design)[SOLID],
|
12
11
|
and https://en.wikipedia.org/wiki/Inversion_of_control[Inversion of Control], with
|
13
12
|
Ruby style ease of use, DSLs, and
|
14
13
|
https://en.wikipedia.org/wiki/Convention_over_configuration[Convention over Configuration].
|
15
14
|
|
16
|
-
|
15
|
+
Further documentation can be found at https://github.com/alki-project/alki/blob/master/doc/index.adoc
|
16
|
+
|
17
|
+
Example projects can be found at https://github.com/alki-project/alki-examples
|
17
18
|
|
18
19
|
## Getting Started
|
19
20
|
|
@@ -21,94 +22,13 @@ Install from rubygems
|
|
21
22
|
|
22
23
|
gem install alki
|
23
24
|
|
24
|
-
Setting up Alki in your project requires only
|
25
|
+
Setting up Alki in your project requires only creating a couple of files, but the
|
25
26
|
`alki` command line tool can also be used to automate the process. Project names
|
26
27
|
should be given in lowercase using underscores and forward slashes as separators.
|
27
28
|
|
28
29
|
.Example project
|
29
30
|
```
|
30
31
|
$ cd <project dir>
|
31
|
-
$ alki init --console <project name>
|
32
|
+
$ alki init --addons console <project name>
|
32
33
|
```
|
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.
|
114
34
|
|
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.
|
25
|
-
spec.add_dependency "alki-support", "~> 0.
|
24
|
+
spec.add_dependency "alki-dsl", "~> 0.4"
|
25
|
+
spec.add_dependency "alki-support", "~> 0.7"
|
26
26
|
end
|
data/exe/alki
CHANGED
@@ -102,7 +102,8 @@ if options[:addons].include? "reload"
|
|
102
102
|
|
103
103
|
env_name = project_name.tr('a-z/','A-Z_')+"_ENV"
|
104
104
|
fw.add_line primary_config_path, " mount(:reloader, 'alki/reload'){ set(:watch) { development? } }", match: /^\s*mount\(? *:reloader/, after: 'Alki do'
|
105
|
-
fw.add_line primary_config_path, " set(:development?){
|
105
|
+
fw.add_line primary_config_path, " set(:development?){ environment == 'development' }", match: /^\s*set\(? *:development\?/, after: 'Alki do'
|
106
|
+
fw.add_line primary_config_path, " set(:environment){ ENV['#{env_name}'] || 'development' }", match: /^\s*set\(? *:environment/, after: 'Alki do'
|
106
107
|
end
|
107
108
|
|
108
109
|
fw.write
|
@@ -11,6 +11,7 @@ module Alki
|
|
11
11
|
@assembly_name = nil
|
12
12
|
@definition = nil
|
13
13
|
@load_mode = :direct
|
14
|
+
@primary_config = 'assembly'
|
14
15
|
end
|
15
16
|
|
16
17
|
attr_reader :config_dir, :assembly_name, :definition
|
@@ -22,6 +23,9 @@ module Alki
|
|
22
23
|
def build(opts={},&blk)
|
23
24
|
@load_mode = opts[:load_mode] if opts[:load_mode]
|
24
25
|
build_assembly blk if blk
|
26
|
+
@primary_config = opts[:primary_config] if opts[:primary_config]
|
27
|
+
set_assembly_name opts[:name] if opts[:name]
|
28
|
+
setup_project_assembly opts[:project_assembly] if opts[:project_assembly]
|
25
29
|
if opts[:config_dir]
|
26
30
|
context = if opts[:project_assembly]
|
27
31
|
File.dirname opts[:project_assembly]
|
@@ -30,13 +34,11 @@ module Alki
|
|
30
34
|
end
|
31
35
|
@config_dir = File.expand_path opts[:config_dir], context
|
32
36
|
end
|
33
|
-
set_assembly_name opts[:name] if opts[:name]
|
34
|
-
setup_project_assembly opts[:project_assembly] if opts[:project_assembly]
|
35
37
|
register_config_directory if @config_dir
|
36
38
|
if blk
|
37
39
|
build_assembly blk
|
38
40
|
else
|
39
|
-
load_assembly_file
|
41
|
+
load_assembly_file
|
40
42
|
end
|
41
43
|
build_empty_assembly unless definition
|
42
44
|
build_class
|
@@ -44,16 +46,11 @@ module Alki
|
|
44
46
|
|
45
47
|
def setup_project_assembly(path)
|
46
48
|
root = Alki::Support.find_root(path) do |dir|
|
47
|
-
File.exists?(File.join(dir,'config',
|
49
|
+
File.exists?(File.join(dir,'config',"#{@primary_config}.rb")) ||
|
48
50
|
File.exists?(File.join(dir,'Gemfile')) ||
|
49
51
|
!Dir.glob(File.join(dir,'*.gemspec')).empty?
|
50
52
|
end
|
51
53
|
if root
|
52
|
-
unless @config_dir
|
53
|
-
config_dir = File.join(root,'config')
|
54
|
-
@config_dir = config_dir if File.exists? config_dir
|
55
|
-
end
|
56
|
-
|
57
54
|
unless @assembly_name
|
58
55
|
lib_dir = File.join(root,'lib')
|
59
56
|
name = Alki::Support.path_name path, lib_dir
|
@@ -62,6 +59,11 @@ module Alki
|
|
62
59
|
end
|
63
60
|
set_assembly_name name
|
64
61
|
end
|
62
|
+
|
63
|
+
unless @config_dir
|
64
|
+
config_dir = File.join(root,'config')
|
65
|
+
@config_dir = config_dir if File.exists? config_dir
|
66
|
+
end
|
65
67
|
end
|
66
68
|
end
|
67
69
|
|
@@ -69,18 +71,21 @@ module Alki
|
|
69
71
|
@assembly_name = name
|
70
72
|
end
|
71
73
|
|
74
|
+
def config_prefix
|
75
|
+
unless @assembly_name
|
76
|
+
raise "Can't use config directory without a name"
|
77
|
+
end
|
78
|
+
File.join(@assembly_name,'assembly_config')
|
79
|
+
end
|
80
|
+
|
72
81
|
def register_config_directory
|
73
|
-
Alki::
|
82
|
+
Alki::Loader.register @config_dir, builder: 'alki/dsls/assembly', name: config_prefix, **dsl_opts
|
74
83
|
end
|
75
84
|
|
76
|
-
def load_assembly_file
|
77
|
-
name ||= 'assembly'
|
85
|
+
def load_assembly_file
|
78
86
|
if @config_dir
|
79
|
-
|
80
|
-
|
81
|
-
@definition = assembly_config_path
|
82
|
-
true
|
83
|
-
end
|
87
|
+
@definition = File.join(config_prefix,@primary_config)
|
88
|
+
true
|
84
89
|
end
|
85
90
|
end
|
86
91
|
|
@@ -89,14 +94,17 @@ module Alki
|
|
89
94
|
end
|
90
95
|
|
91
96
|
def build_assembly(blk)
|
92
|
-
@definition = Alki::Dsl.build('alki/dsls/assembly', dsl_opts, &blk)
|
97
|
+
@definition = Alki::Dsl.build('alki/dsls/assembly', dsl_opts, &blk)
|
93
98
|
end
|
94
99
|
|
95
100
|
def dsl_opts
|
96
|
-
opts = {
|
101
|
+
opts = {}
|
97
102
|
if @assembly_name
|
98
|
-
opts[:prefix] = File.join(@assembly_name,'alki_config')
|
99
103
|
opts[:assembly_name] = @assembly_name
|
104
|
+
if @config_dir
|
105
|
+
opts[:config_dir] = @config_dir
|
106
|
+
opts[:prefix] = config_prefix
|
107
|
+
end
|
100
108
|
end
|
101
109
|
opts
|
102
110
|
end
|
@@ -122,9 +130,7 @@ module Alki
|
|
122
130
|
},
|
123
131
|
definition: {
|
124
132
|
body: ->{
|
125
|
-
|
126
|
-
Alki::Dsl.load(definition)[:class] :
|
127
|
-
definition
|
133
|
+
Alki.load definition
|
128
134
|
}
|
129
135
|
},
|
130
136
|
load_class: {
|
@@ -6,15 +6,15 @@ module Alki
|
|
6
6
|
InvalidPathError = Class.new(StandardError)
|
7
7
|
module Assembly
|
8
8
|
class Executor
|
9
|
-
def initialize(assembly,
|
9
|
+
def initialize(assembly,meta)
|
10
10
|
@assembly = assembly
|
11
|
-
@
|
11
|
+
@meta = meta
|
12
12
|
@data = {}
|
13
13
|
@semaphore = Monitor.new
|
14
14
|
@lookup_cache = {}
|
15
15
|
@call_cache = {}
|
16
16
|
@context_cache = {}
|
17
|
-
@
|
17
|
+
@processed_meta = false
|
18
18
|
end
|
19
19
|
|
20
20
|
def synchronize
|
@@ -28,26 +28,30 @@ module Alki
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def execute(meta,path,args,blk)
|
31
|
+
cache_entry = nil
|
32
|
+
synchronize do
|
31
33
|
cache_entry = @call_cache[path]
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
34
|
+
end
|
35
|
+
if cache_entry
|
36
|
+
if cache_entry.status == :building
|
37
|
+
raise "Circular element reference found: #{path.join(".")}"
|
38
|
+
end
|
39
|
+
else
|
40
|
+
synchronize do
|
41
|
+
cache_entry = @call_cache[path]
|
42
|
+
unless cache_entry
|
43
|
+
cache_entry = @call_cache[path] = Alki::Execution::CacheEntry.new
|
44
|
+
action = lookup(path)
|
45
|
+
if action[:build]
|
46
|
+
build_meta = meta.merge(building: path.join('.'))
|
47
|
+
build_meta.merge!(action[:meta]) if action[:meta]
|
48
|
+
build_action = action[:build].merge(scope: action[:scope],modules: action[:modules])
|
49
|
+
call_value(*process_action(build_action),build_meta,[action])
|
48
50
|
end
|
51
|
+
cache_entry.finish *process_action(action)
|
49
52
|
end
|
50
53
|
end
|
54
|
+
end
|
51
55
|
call_value(cache_entry.type,cache_entry.value,meta,args,blk)
|
52
56
|
end
|
53
57
|
|
@@ -62,25 +66,47 @@ module Alki
|
|
62
66
|
|
63
67
|
private
|
64
68
|
|
65
|
-
def
|
66
|
-
unless @
|
67
|
-
@
|
69
|
+
def process_meta
|
70
|
+
unless @processed_meta
|
71
|
+
@processed_meta = true
|
68
72
|
@data[:overlays] = {}
|
69
|
-
@
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
overlay = canonical_path(from,info.overlay) or
|
75
|
-
raise InvalidPathError.new("Invalid overlay path #{info.overlay.join('.')}")
|
73
|
+
@data[:tags] = {}
|
74
|
+
@meta.each do |(from,type,info)|
|
75
|
+
case type
|
76
|
+
when :overlay then process_overlay from, info
|
77
|
+
when :tags then process_tags from, info
|
76
78
|
end
|
77
|
-
(@data[:overlays][target]||=[]) << [overlay,info.args]
|
78
79
|
end
|
79
80
|
end
|
80
81
|
end
|
81
82
|
|
83
|
+
def process_tags(from,tags)
|
84
|
+
tags.each do |tag|
|
85
|
+
(@data[:tags][tag]||=[]) << from
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def process_overlay(from,info)
|
90
|
+
target_path = info.target.dup
|
91
|
+
if target_path.last.to_s.start_with?('%')
|
92
|
+
tag = target_path.pop
|
93
|
+
end
|
94
|
+
if target_path == []
|
95
|
+
target_path = [:root]
|
96
|
+
end
|
97
|
+
target = canonical_path(from,target_path) or
|
98
|
+
raise InvalidPathError.new("Invalid overlay target #{info.target.join('.')}")
|
99
|
+
target = target.dup.push tag if tag
|
100
|
+
overlay = info.overlay
|
101
|
+
if overlay.is_a?(Array)
|
102
|
+
overlay = canonical_path(from,info.overlay) or
|
103
|
+
raise InvalidPathError.new("Invalid overlay path #{info.overlay.join('.')}")
|
104
|
+
end
|
105
|
+
(@data[:overlays][target]||=[]) << [info.type, overlay, info.args]
|
106
|
+
end
|
107
|
+
|
82
108
|
def lookup(path)
|
83
|
-
|
109
|
+
process_meta
|
84
110
|
@lookup_cache[path] ||= lookup_elem(path).tap do |elem|
|
85
111
|
unless elem
|
86
112
|
raise InvalidPathError.new("Invalid path #{path.inspect}")
|
@@ -7,6 +7,7 @@ module Alki
|
|
7
7
|
def initialize(assembly_module,args)
|
8
8
|
@assembly_module = assembly_module
|
9
9
|
@args = args
|
10
|
+
@version = 0
|
10
11
|
end
|
11
12
|
|
12
13
|
def __reload__
|
@@ -14,7 +15,7 @@ module Alki
|
|
14
15
|
did_something = @obj.__reload__
|
15
16
|
end
|
16
17
|
if did_something != false && @obj
|
17
|
-
|
18
|
+
__setobj__ nil
|
18
19
|
did_something = true
|
19
20
|
end
|
20
21
|
if did_something
|
@@ -24,12 +25,18 @@ module Alki
|
|
24
25
|
end
|
25
26
|
|
26
27
|
def __setobj__(obj)
|
28
|
+
@version += 1
|
27
29
|
@obj = obj
|
28
30
|
end
|
29
31
|
|
32
|
+
def __version__
|
33
|
+
@version
|
34
|
+
end
|
35
|
+
|
30
36
|
def __getobj__
|
31
37
|
unless @obj
|
32
|
-
|
38
|
+
# Will call __setobj__
|
39
|
+
Alki.load(@assembly_module).raw_instance self, *@args
|
33
40
|
end
|
34
41
|
@obj
|
35
42
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Alki
|
2
|
+
module Assembly
|
3
|
+
class Type
|
4
|
+
def index(*args)
|
5
|
+
handler(args).index
|
6
|
+
end
|
7
|
+
|
8
|
+
def output(*args)
|
9
|
+
handler(args).output
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def handler(args)
|
15
|
+
self.class::Handler.new(self,*args)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -1,11 +1,11 @@
|
|
1
1
|
Alki do
|
2
|
-
require 'alki/execution/
|
2
|
+
require 'alki/execution/value_helpers'
|
3
3
|
|
4
4
|
attr :block
|
5
5
|
|
6
6
|
output do
|
7
7
|
{
|
8
|
-
modules: [Alki::Execution::
|
8
|
+
modules: [Alki::Execution::ValueHelpers],
|
9
9
|
scope: data[:scope],
|
10
10
|
build: {
|
11
11
|
methods: {
|
@@ -1,14 +1,30 @@
|
|
1
1
|
Alki do
|
2
|
-
require 'alki/execution/
|
2
|
+
require 'alki/execution/helpers'
|
3
3
|
|
4
4
|
attr(:children){ {} }
|
5
5
|
|
6
6
|
index do
|
7
7
|
update_scope children, data[:prefix], data[:scope]
|
8
8
|
|
9
|
+
data[:tags] = data[:tags].inject({}) do |tags,(tag,tagged)|
|
10
|
+
tagged.each do |path|
|
11
|
+
if path.empty? || path[0] == key.to_sym
|
12
|
+
tags[tag] = (tags[tag]||[]) | [path[1..-1]]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
tags
|
16
|
+
end
|
17
|
+
|
9
18
|
data[:overlays] = data[:overlays].inject({}) do |no,(target,overlays)|
|
10
19
|
target = target.dup
|
11
|
-
if target.
|
20
|
+
if target.size == 1 && target[0].to_s.start_with?('%')
|
21
|
+
tags = data[:tags][target[0].to_s[1..-1].to_sym]
|
22
|
+
if tags
|
23
|
+
tags.each do |target|
|
24
|
+
(no[target]||=[]).push *overlays
|
25
|
+
end
|
26
|
+
end
|
27
|
+
elsif target.empty? || target.shift == key.to_sym
|
12
28
|
(no[target]||=[]).push *overlays
|
13
29
|
end
|
14
30
|
no
|
@@ -23,7 +39,7 @@ Alki do
|
|
23
39
|
{
|
24
40
|
full_scope: update_scope(children, data[:prefix], data[:scope]),
|
25
41
|
scope: update_scope(children,data[:prefix]),
|
26
|
-
modules: [Alki::Execution::
|
42
|
+
modules: [Alki::Execution::Helpers],
|
27
43
|
proc: ->{self}
|
28
44
|
}
|
29
45
|
end
|
@@ -10,13 +10,6 @@ Alki do
|
|
10
10
|
|
11
11
|
if main_child && override_child
|
12
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
13
|
Alki::Assembly::Types::Override.new main_child, override_child
|
21
14
|
elsif main_child
|
22
15
|
data.replace data[:main]
|
@@ -1,5 +1,5 @@
|
|
1
1
|
Alki do
|
2
|
-
require 'alki/execution/
|
2
|
+
require 'alki/execution/value_helpers'
|
3
3
|
|
4
4
|
attr :proc
|
5
5
|
|
@@ -11,7 +11,7 @@ Alki do
|
|
11
11
|
},
|
12
12
|
proc: ->(desc) {desc[:value] = __build__}
|
13
13
|
},
|
14
|
-
modules: [Alki::Execution::
|
14
|
+
modules: [Alki::Execution::ValueHelpers],
|
15
15
|
scope: data[:scope]
|
16
16
|
}
|
17
17
|
end
|
@@ -1,26 +1,37 @@
|
|
1
1
|
Alki do
|
2
|
-
require 'alki/execution/
|
2
|
+
require 'alki/execution/value_helpers'
|
3
3
|
|
4
4
|
attr :block
|
5
5
|
|
6
6
|
output do
|
7
|
-
overlays = data[:overlays][[]]||[]
|
7
|
+
overlays = (data[:overlays][[]]||[]).group_by(&:first)
|
8
|
+
value_overlays = overlays[:value]||[]
|
9
|
+
reference_overlays = overlays[:reference]||[]
|
10
|
+
methods = {
|
11
|
+
__build__: block,
|
12
|
+
__apply_overlays__: -> obj, overlays {
|
13
|
+
overlays.inject(obj) do |val,(_,overlay,args)|
|
14
|
+
overlay = __raw_root__.lookup(overlay) if overlay.is_a?(Array)
|
15
|
+
if !overlay.respond_to?(:call) && overlay.respond_to?(:new)
|
16
|
+
overlay = overlay.method(:new)
|
17
|
+
end
|
18
|
+
overlay.call val, *args
|
19
|
+
end
|
20
|
+
}
|
21
|
+
}
|
22
|
+
unless reference_overlays.empty?
|
23
|
+
methods[:__process_reference__] = -> ref {
|
24
|
+
__apply_overlays__ ref, reference_overlays
|
25
|
+
}
|
26
|
+
end
|
8
27
|
{
|
9
28
|
build: {
|
10
|
-
methods:
|
11
|
-
__build__: block
|
12
|
-
},
|
29
|
+
methods: methods,
|
13
30
|
proc: -> (elem) {
|
14
|
-
elem[:value] =
|
15
|
-
overlay = root.lookup(overlay) if overlay.is_a?(Array)
|
16
|
-
if !overlay.respond_to?(:call) && overlay.respond_to?(:new)
|
17
|
-
overlay = overlay.method(:new)
|
18
|
-
end
|
19
|
-
overlay.call val, *args
|
20
|
-
end
|
31
|
+
elem[:value] = __apply_overlays__ __build__, value_overlays
|
21
32
|
},
|
22
33
|
},
|
23
|
-
modules: [Alki::Execution::
|
34
|
+
modules: [Alki::Execution::ValueHelpers],
|
24
35
|
scope: data[:scope],
|
25
36
|
}
|
26
37
|
end
|
data/lib/alki/assembly.rb
CHANGED
@@ -16,13 +16,14 @@ module Alki
|
|
16
16
|
override_root = overrides_info[:root] || build(:group)
|
17
17
|
|
18
18
|
assembly = build :assembly, root, override_root
|
19
|
-
update_instance_overlay = [[],OverlayInfo.new(
|
19
|
+
update_instance_overlay = [[],:overlay, OverlayInfo.new(
|
20
|
+
:value,
|
20
21
|
[:assembly_instance],
|
21
22
|
->obj{instance.__setobj__ obj; instance},
|
22
23
|
[]
|
23
24
|
)]
|
24
|
-
|
25
|
-
executor = Executor.new(assembly,
|
25
|
+
all_meta = meta+overrides_info[:meta]+[update_instance_overlay]
|
26
|
+
executor = Executor.new(assembly, all_meta)
|
26
27
|
|
27
28
|
override_root.children[:assembly_instance] = build(:service,->{
|
28
29
|
root
|
@@ -35,14 +36,14 @@ module Alki
|
|
35
36
|
self.definition.root
|
36
37
|
end
|
37
38
|
|
38
|
-
def
|
39
|
-
self.definition.
|
39
|
+
def meta
|
40
|
+
self.definition.meta
|
40
41
|
end
|
41
42
|
|
42
43
|
private
|
43
44
|
|
44
45
|
def build(type,*args)
|
45
|
-
Alki
|
46
|
+
Alki.load("alki/assembly/types/#{type}").new *args
|
46
47
|
end
|
47
48
|
end
|
48
49
|
end
|