alki 0.7.0 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/{README.ad → README.adoc} +2 -2
- data/doc/{assemblies.ad → assemblies.adoc} +24 -9
- data/doc/{assembly_dsl.ad → assembly_dsl.adoc} +113 -12
- data/doc/{index.ad → index.adoc} +4 -3
- data/doc/{projects.ad → projects.adoc} +1 -0
- data/lib/alki/dsls/assembly_types/assembly.rb +1 -1
- data/lib/alki/feature_test.rb +7 -0
- data/lib/alki/test.rb +4 -5
- data/lib/alki/version.rb +1 -1
- metadata +8 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 91b0f6c880177b0e4be1c5228c92b0295db5742a
|
4
|
+
data.tar.gz: 6c781108545400031137040024b040c3a67d9b16
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cc46916b429be7d64b76b2e9e93d086493699d8303607d248471a55fed9da1ab13e7c01bc7b2b700a44c71180943c53fb766b72d50b3dd10dd75ec700e6816cc
|
7
|
+
data.tar.gz: e17b68e68390ea600d2d5f2dabe48029696537d2d8ded480eec57cb1a6bf6601dc4035aaf666311ab63f3a28684dac9f571b2e8746e11885b204cfd5c2ccbe09
|
data/{README.ad → README.adoc}
RENAMED
@@ -4,9 +4,9 @@ Alki is a framework for creating projects that are modular, testable, and well o
|
|
4
4
|
|
5
5
|
It's goal is to remove uncertainty and friction when building Ruby projects, allowing developers to focus on implementing business logic.
|
6
6
|
|
7
|
-
# Synopsis
|
8
|
-
|
9
7
|
Best place to start would be to check out some examples:
|
10
8
|
|
11
9
|
* https://github.com/alki-project/alki-example
|
12
10
|
* https://github.com/alki-project/alki/tree/master/test/fixtures/example
|
11
|
+
|
12
|
+
Docs can be found at https://github.com/alki-project/alki/blob/master/doc/index.adoc
|
@@ -1,14 +1,25 @@
|
|
1
1
|
Assemblies
|
2
2
|
==========
|
3
|
+
:toc:
|
4
|
+
|
5
|
+
If a set of classes are your raw materials, an Assembly is the finished product,
|
6
|
+
ready to be used.
|
7
|
+
|
8
|
+
To get there, you provide Alki with your assembly definition, which acts as the instructions for
|
9
|
+
how to piece together your classes and objects. Assemblies are made up of elements, which are groups
|
10
|
+
of other elements, or various value types like services and factories.
|
11
|
+
|
12
|
+
Assembly definitions are written in a simple DSL.
|
3
13
|
|
4
14
|
Project Assemblies
|
5
15
|
------------------
|
6
16
|
|
7
|
-
Most of the time, a project will have a single assembly
|
17
|
+
Most of the time, a project will have a single assembly, so Alki makes having a single project wide
|
18
|
+
assembly especially easy.
|
8
19
|
|
9
20
|
First. in your project's `lib` directory create a ruby file for your assembly. If your assembly is
|
10
|
-
to be called `MyAssembly`, create `lib/my_assembly.rb`. If it's namespaced
|
11
|
-
as usual
|
21
|
+
to be called `MyAssembly`, create `lib/my_assembly.rb`. If it's namespaced put it in a subdirectory
|
22
|
+
as usual (i.e. `MyModule::MyAssembly` would go in `lib/my_module/my_assembly.rb`).
|
12
23
|
|
13
24
|
Your assembly file just needs two lines:
|
14
25
|
|
@@ -20,7 +31,8 @@ Alki.project_assembly!
|
|
20
31
|
It will detect the project root and what class name it should create automatically.
|
21
32
|
|
22
33
|
Second, a `config` directory must be created in the project root, and in that directory an `assembly.rb`
|
23
|
-
file should be created. It should
|
34
|
+
file should be created. It should contain an `Alki do ... end` block which contains the top level
|
35
|
+
definition for your Assembly.
|
24
36
|
|
25
37
|
```ruby
|
26
38
|
Alki do
|
@@ -47,6 +59,7 @@ It should be called with a block that contains the assembly DSL. It will return
|
|
47
59
|
be used directly or assigned to a constant.
|
48
60
|
|
49
61
|
```ruby
|
62
|
+
require 'alki'
|
50
63
|
assembly = Alki.create_assembly do
|
51
64
|
set :msg, "hello world"
|
52
65
|
func :run do
|
@@ -80,7 +93,7 @@ assembly = Alki.create_assembly do
|
|
80
93
|
end
|
81
94
|
```
|
82
95
|
|
83
|
-
|
96
|
+
One can use the logger service like so:
|
84
97
|
|
85
98
|
```ruby
|
86
99
|
instance = assembly.new
|
@@ -91,12 +104,12 @@ instance.util.logger.info "test"
|
|
91
104
|
|
92
105
|
### Overrides
|
93
106
|
|
94
|
-
Assembly overrides provide a way to
|
107
|
+
Assembly overrides provide a way to configure or customize an Assembly when
|
95
108
|
constructing an instance.
|
96
109
|
|
97
110
|
For example, using the assembly created above, one might want to change the IO object logged to.
|
98
111
|
|
99
|
-
The simplist way to do this is to provide a hash
|
112
|
+
The simplist way to do this is to provide a hash which will override values in the assembly (as if the `set`
|
100
113
|
command was called in the DSL):
|
101
114
|
|
102
115
|
```ruby
|
@@ -113,6 +126,7 @@ The limitiation of this is that it can only override basic values. To override m
|
|
113
126
|
a block can be given to `new` allowing the full assembly DSL.
|
114
127
|
|
115
128
|
```ruby
|
129
|
+
require 'alki'
|
116
130
|
class MyLogger
|
117
131
|
def initialize(io)
|
118
132
|
@io = io
|
@@ -134,5 +148,6 @@ instance.util.logger.info "test"
|
|
134
148
|
# output: INFO test
|
135
149
|
```
|
136
150
|
|
137
|
-
One thing of note is that elements from the assembly are
|
138
|
-
This can also be used to access the original versions of elements that have
|
151
|
+
One thing of note is that elements from the assembly are accessible in overrides via the `original`
|
152
|
+
method, as seen above. This can also be used to access the original versions of elements that have
|
153
|
+
been overriden.
|
@@ -1,10 +1,11 @@
|
|
1
1
|
Assembly DSL
|
2
|
-
|
2
|
+
============
|
3
|
+
:toc:
|
3
4
|
|
4
5
|
Building Assemblies is done via a DSL that makes putting together the pieces of your project easy.
|
5
6
|
|
6
|
-
Groups
|
7
|
-
|
7
|
+
Groups (group)
|
8
|
+
--------------
|
8
9
|
|
9
10
|
Groups are the basic way of organizing the elements of your Assembly. Creating elements at the top
|
10
11
|
level of an Assembly will place them in a root group, but subgroups are easily created via the `group`
|
@@ -18,30 +19,43 @@ assembly = Alki.create_assembly do
|
|
18
19
|
end
|
19
20
|
end
|
20
21
|
puts assembly.new.sub_group.val
|
22
|
+
|
23
|
+
#output: hello world
|
21
24
|
```
|
22
25
|
|
23
|
-
Scoping is also done by group, so that an element will be found by
|
26
|
+
Scoping is also done by group, so that an element will be found by searching through parent groups until
|
24
27
|
it is found.
|
25
28
|
|
26
29
|
```ruby
|
27
30
|
require 'alki'
|
28
31
|
assembly = Alki.create_assembly do
|
29
32
|
set :val, "one"
|
33
|
+
func :print do
|
34
|
+
puts val
|
35
|
+
end
|
36
|
+
|
30
37
|
group :g1 do
|
31
38
|
set :val, "two"
|
39
|
+
|
32
40
|
group :g2 do
|
33
41
|
func :print do
|
34
42
|
puts val
|
35
43
|
end
|
36
44
|
end
|
45
|
+
|
37
46
|
end
|
38
47
|
end
|
48
|
+
|
49
|
+
assembly.new.print
|
50
|
+
|
51
|
+
#output: one
|
52
|
+
|
39
53
|
assembly.new.g1.g2.print
|
40
54
|
|
41
55
|
#output: two
|
42
56
|
```
|
43
57
|
|
44
|
-
=== Loading groups
|
58
|
+
=== Loading groups (load)
|
45
59
|
|
46
60
|
Groups can also be loaded from other config files via the `load` command.
|
47
61
|
|
@@ -52,6 +66,7 @@ Alki do
|
|
52
66
|
end
|
53
67
|
```
|
54
68
|
|
69
|
+
.main code
|
55
70
|
```ruby
|
56
71
|
require 'alki'
|
57
72
|
assembly = Alki.create_assembly config_dir: 'config' do
|
@@ -69,6 +84,85 @@ assembly.new.print
|
|
69
84
|
Values
|
70
85
|
------
|
71
86
|
|
87
|
+
Values are how you add functionality to your Assembly. There are different types of values, but they
|
88
|
+
all share a number of common features.
|
89
|
+
|
90
|
+
### On-Demand
|
91
|
+
|
92
|
+
Values are only built when referenced, on demand. This means even if you have a very large assembly
|
93
|
+
only the things you actually use in a given run will be created, or often even `require`-d. It also
|
94
|
+
means that all values will automatically be built in the correct order to satisfy dependencies.
|
95
|
+
|
96
|
+
### Scope
|
97
|
+
|
98
|
+
When providing a block for a value, the block will be executed in a special context with some
|
99
|
+
additional helper methods.
|
100
|
+
|
101
|
+
The most important methods available are other elements that are "in scope". For example, a value can
|
102
|
+
reference a sibling element in the same group, or any value in any ancestor group. The order that
|
103
|
+
elements are defined does not effect what is in scope. All other elements are out of scope, but can
|
104
|
+
usually still be referenced by finding an ancestor group that 'is' in scope, and then drilling down
|
105
|
+
from there.
|
106
|
+
|
107
|
+
```ruby
|
108
|
+
require 'alki'
|
109
|
+
assembly = Alki.create_assembly config_dir: 'config' do
|
110
|
+
set :val1, "1"
|
111
|
+
group :main do
|
112
|
+
group :sub_group do
|
113
|
+
set :val2, "2"
|
114
|
+
end
|
115
|
+
|
116
|
+
set :values do
|
117
|
+
[
|
118
|
+
val1, # OK
|
119
|
+
# val2, # ERROR
|
120
|
+
sub_group.val2, # OK
|
121
|
+
val3, # OK
|
122
|
+
# val4, # ERROR
|
123
|
+
other_group.val4, #OK
|
124
|
+
].join('')
|
125
|
+
end
|
126
|
+
|
127
|
+
set :val3, "3"
|
128
|
+
end
|
129
|
+
|
130
|
+
group :other_group do
|
131
|
+
set :val4, "4"
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|
135
|
+
puts assembly.new.main.values
|
136
|
+
|
137
|
+
#output: 1234
|
138
|
+
```
|
139
|
+
|
140
|
+
### Helpers
|
141
|
+
|
142
|
+
In addition to elements in scope, there are some helper methods that are always available in value
|
143
|
+
blocks.
|
144
|
+
|
145
|
+
[horizontal]
|
146
|
+
|
147
|
+
assembly:: This will return the root group of the assembly the element is defined in.
|
148
|
+
|
149
|
+
root:: This will return the root group of the 'top most' assembly being run. If only a single
|
150
|
+
assembly is being run, this will be the same as `assembly` but if the element being run is in
|
151
|
+
an assembly that has been mounted into another assembly, they will differ.
|
152
|
+
|
153
|
+
lookup(path):: This can be used to reference an element by a string path (using periods (`.`) to
|
154
|
+
drill down into groups). If called directly it will lookup using the local scope. It is also available
|
155
|
+
as a method on all groups, so `assembly.lookup(path)` would lookup an element starting from the root
|
156
|
+
of the assembly.
|
157
|
+
|
158
|
+
lazy(path):: This works the same as `lookup`, but with an important difference: Instead of doing the
|
159
|
+
lookup immediately, it will instead return a "proxy" object, which will do the lookup the first time
|
160
|
+
a method is called on the proxy object, and then delegate all method calls to the actual element. This
|
161
|
+
can be used to handle circular references in services.
|
162
|
+
|
163
|
+
Value Types
|
164
|
+
-----------
|
165
|
+
|
72
166
|
There are four types of elements loosely categorized as "values".
|
73
167
|
|
74
168
|
### Basic Values (set)
|
@@ -162,7 +256,7 @@ assembly.new.main_logger << "hello"
|
|
162
256
|
#output: hello
|
163
257
|
```
|
164
258
|
|
165
|
-
|
259
|
+
## Overlays (overlay)
|
166
260
|
|
167
261
|
Overlays are a way to intercept and transform calls made to all services in a given group or it's
|
168
262
|
sub-groups.
|
@@ -171,24 +265,29 @@ Overlays are often most useful in groups where all services adhere to a common i
|
|
171
265
|
can be used to perform aspect oriented programming like logging, validation, or access controls.
|
172
266
|
|
173
267
|
|
174
|
-
|
268
|
+
## Assemblies (assembly)
|
175
269
|
|
176
270
|
Other assemblies can be mounted into your Assembly using the `assembly` command.
|
177
271
|
|
178
|
-
The first argument is what
|
179
|
-
is the name of the assembly. This should be formatted like a require string (relative path but
|
272
|
+
The first argument is what the element should be named in the parent assembly. The optional second argument
|
273
|
+
is the name of the assembly to be mounted. This should be formatted like a require string (relative path but
|
180
274
|
no `.rb`) and will default to the value of the first argument. If a classified version of that name
|
181
|
-
can't be found,
|
275
|
+
can't be found, Alki will attempt to `require` it, and then look for it again.
|
182
276
|
|
183
277
|
```ruby
|
184
278
|
require 'alki'
|
279
|
+
|
280
|
+
# Creates OtherAssembly
|
185
281
|
Alki.create_assembly name: 'other_assembly' do
|
186
282
|
set :val, "one"
|
187
283
|
|
284
|
+
# This is invalid as there is no such element as 'val2'
|
188
285
|
set :invalid_val2 do
|
189
286
|
val2
|
190
287
|
end
|
191
288
|
|
289
|
+
# Normally, this would also be invalid, but if mounted
|
290
|
+
# in an assembly that has a 'val2' element, this works.
|
192
291
|
set :root_val2 do
|
193
292
|
root.val2
|
194
293
|
end
|
@@ -196,13 +295,15 @@ end
|
|
196
295
|
|
197
296
|
Alki.create_assembly name: 'main_assembly' do
|
198
297
|
set :val2, "two"
|
298
|
+
# Mounts OtherAssembly as 'other'
|
199
299
|
assembly :other, 'other_assembly'
|
200
300
|
end
|
201
301
|
instance = MainAssembly.new
|
202
302
|
puts instance.other.val
|
203
303
|
#output: one
|
204
304
|
|
205
|
-
#
|
305
|
+
# Even though val2 exists in MainAssembly, it is not directly accessibly to elements
|
306
|
+
# within OtherAssembly
|
206
307
|
begin
|
207
308
|
puts instance.other.invalid_val2
|
208
309
|
rescue => e
|
@@ -210,7 +311,7 @@ rescue => e
|
|
210
311
|
end
|
211
312
|
# output: undefined local variable or method 'val2'
|
212
313
|
|
213
|
-
# This works, because root returns the root assembly
|
314
|
+
# This works, because root returns the root assembly, which has a 'val2' element
|
214
315
|
puts instance.other.root_val2
|
215
316
|
#output: two
|
216
317
|
```
|
data/doc/{index.ad → index.adoc}
RENAMED
@@ -1,15 +1,16 @@
|
|
1
1
|
Alki
|
2
2
|
====
|
3
|
+
:toc:
|
3
4
|
|
4
5
|
Alki is a framework for creating projects that are modular, testable, and well organized.
|
5
6
|
|
6
7
|
It's goal is to remove uncertainty and friction when building Ruby projects, allowing developers to focus on implementing business logic.
|
7
8
|
|
8
9
|
:leveloffset: 1
|
9
|
-
include::projects.
|
10
|
+
include::projects.adoc[]
|
10
11
|
|
11
12
|
:leveloffset: 1
|
12
|
-
include::assemblies.
|
13
|
+
include::assemblies.adoc[]
|
13
14
|
|
14
15
|
:leveloffset: 1
|
15
|
-
include::assembly_dsl.
|
16
|
+
include::assembly_dsl.adoc[]
|
@@ -58,7 +58,7 @@ Alki do
|
|
58
58
|
|
59
59
|
def main_data
|
60
60
|
assembly_path = data[:prefix] ? data[:prefix].dup : []
|
61
|
-
{scope: {assembly: assembly_path, root: []}, overlays: []}
|
61
|
+
{scope: {assembly: assembly_path, root: [], config_dir: (assembly_path + [:config_dir])}, overlays: []}
|
62
62
|
end
|
63
63
|
|
64
64
|
def override
|
data/lib/alki/test.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
|
-
require
|
2
|
-
Bundler.setup(:default,:test)
|
1
|
+
Bundler.require(:test)
|
3
2
|
require 'minitest/autorun'
|
4
3
|
require 'alki/dsl'
|
5
4
|
|
@@ -41,8 +40,8 @@ unless $LOAD_PATH.include? Alki::Test.lib_dir
|
|
41
40
|
$LOAD_PATH.unshift Alki::Test.lib_dir
|
42
41
|
end
|
43
42
|
|
44
|
-
|
43
|
+
test_helper = File.join(Alki::Test.tests_root,'test_helper.rb')
|
45
44
|
|
46
|
-
if File.exists?
|
47
|
-
require
|
45
|
+
if File.exists? test_helper
|
46
|
+
require test_helper
|
48
47
|
end
|
data/lib/alki/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: alki
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matt Edlefsen
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-12-
|
11
|
+
date: 2016-12-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -103,14 +103,14 @@ files:
|
|
103
103
|
- ".gitignore"
|
104
104
|
- Gemfile
|
105
105
|
- LICENSE.txt
|
106
|
-
- README.
|
106
|
+
- README.adoc
|
107
107
|
- Rakefile
|
108
108
|
- alki.gemspec
|
109
109
|
- config/dsls.rb
|
110
|
-
- doc/assemblies.
|
111
|
-
- doc/assembly_dsl.
|
112
|
-
- doc/index.
|
113
|
-
- doc/projects.
|
110
|
+
- doc/assemblies.adoc
|
111
|
+
- doc/assembly_dsl.adoc
|
112
|
+
- doc/index.adoc
|
113
|
+
- doc/projects.adoc
|
114
114
|
- lib/alki.rb
|
115
115
|
- lib/alki/assembly.rb
|
116
116
|
- lib/alki/assembly_builder.rb
|
@@ -126,6 +126,7 @@ files:
|
|
126
126
|
- lib/alki/dsls/assembly_types/overlay.rb
|
127
127
|
- lib/alki/dsls/assembly_types/value.rb
|
128
128
|
- lib/alki/dsls/service.rb
|
129
|
+
- lib/alki/feature_test.rb
|
129
130
|
- lib/alki/overlay_delegator.rb
|
130
131
|
- lib/alki/override_builder.rb
|
131
132
|
- lib/alki/service_delegator.rb
|