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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 31a32ce28977b35ce72bab1992d4512c7ea33f44
4
- data.tar.gz: c6ab121484e99b437aaae6390db983d83a011cc7
3
+ metadata.gz: 91b0f6c880177b0e4be1c5228c92b0295db5742a
4
+ data.tar.gz: 6c781108545400031137040024b040c3a67d9b16
5
5
  SHA512:
6
- metadata.gz: bd1da1b284b8caa1d75a32ac5e199f5f64e504213de1abeedb694e6f6fca517633992b8f2572129b71d329ed0069de2d698b89c0dd2f395a72d49243dbe2032c
7
- data.tar.gz: fd7e999ffc561b91e6452bd859f8f8783fd0a90f097a703febd7746d837227717fa2bfafdaac310903eecef08090d1b2fd834444682b49a38ccdb37dac404a10
6
+ metadata.gz: cc46916b429be7d64b76b2e9e93d086493699d8303607d248471a55fed9da1ab13e7c01bc7b2b700a44c71180943c53fb766b72d50b3dd10dd75ec700e6816cc
7
+ data.tar.gz: e17b68e68390ea600d2d5f2dabe48029696537d2d8ded480eec57cb1a6bf6601dc4035aaf666311ab63f3a28684dac9f571b2e8746e11885b204cfd5c2ccbe09
@@ -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. Alki makes doing this easy.
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 but it in a subdirectory
11
- as usual, `MyModule::MyAssembly` would go in `lib/my_module/my_assembly.rb`
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 be a normal Alki loader block.
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
- Once can use the logger service like so:
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 do configure or customize an Assembly when
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 of values which will set values (as if the `set`
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 accessibly via the `original` method.
138
- This can also be used to access the original versions of elements that have been overriden.
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 moving up parent groups until
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
- ### Overlays (overlay)
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
- ### Assemblies (assembly)
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 it should be named in your assembly. The optional second argument
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, it will attempt to `require` it, and then try again.
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
- # Can't access val2 in main assembly
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
  ```
@@ -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.ad[]
10
+ include::projects.adoc[]
10
11
 
11
12
  :leveloffset: 1
12
- include::assemblies.ad[]
13
+ include::assemblies.adoc[]
13
14
 
14
15
  :leveloffset: 1
15
- include::assembly_dsl.ad[]
16
+ include::assembly_dsl.adoc[]
@@ -1,5 +1,6 @@
1
1
  Setting up Alki Projects
2
2
  ========================
3
+ :toc:
3
4
 
4
5
  Generally, projects that use alki work the same as normal Ruby projects but there are a couple of
5
6
  guidelines to make life easier.
@@ -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
@@ -0,0 +1,7 @@
1
+ require 'alki/test'
2
+
3
+ feature_test_helper = File.join(Alki::Test.tests_root,'feature_test_helper.rb')
4
+
5
+ if File.exists? feature_test_helper
6
+ require feature_test_helper
7
+ end
data/lib/alki/test.rb CHANGED
@@ -1,5 +1,4 @@
1
- require 'bundler'
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
- test_helper_dir = File.join(Alki::Test.tests_root,'test_helper.rb')
43
+ test_helper = File.join(Alki::Test.tests_root,'test_helper.rb')
45
44
 
46
- if File.exists? test_helper_dir
47
- require test_helper_dir
45
+ if File.exists? test_helper
46
+ require test_helper
48
47
  end
data/lib/alki/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Alki
2
- VERSION = "0.7.0"
2
+ VERSION = "0.8.0"
3
3
  end
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.7.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-05 00:00:00.000000000 Z
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.ad
106
+ - README.adoc
107
107
  - Rakefile
108
108
  - alki.gemspec
109
109
  - config/dsls.rb
110
- - doc/assemblies.ad
111
- - doc/assembly_dsl.ad
112
- - doc/index.ad
113
- - doc/projects.ad
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