alki 0.12.0 → 0.12.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -0
  3. data/README.adoc +132 -20
  4. data/Rakefile +2 -27
  5. data/alki.gemspec +1 -3
  6. data/bin/bundler +17 -0
  7. data/bin/rake +17 -0
  8. data/doc/assemblies.adoc +2 -3
  9. data/doc/assembly_dsl.adoc +191 -30
  10. data/doc/{projects.adoc → executables.adoc} +40 -16
  11. data/doc/index.adoc +4 -3
  12. data/lib/alki.rb +3 -0
  13. data/lib/alki/assembly.rb +4 -34
  14. data/lib/alki/assembly/builder.rb +3 -3
  15. data/lib/alki/assembly/instance.rb +31 -5
  16. data/lib/alki/assembly/instance_builder.rb +48 -0
  17. data/lib/alki/assembly/meta/overlay.rb +7 -2
  18. data/lib/alki/assembly/meta/tags.rb +4 -4
  19. data/lib/alki/assembly/types.rb +9 -0
  20. data/lib/alki/assembly/types/assembly.rb +3 -3
  21. data/lib/alki/assembly/types/group.rb +16 -25
  22. data/lib/alki/assembly/types/original.rb +12 -0
  23. data/lib/alki/assembly/types/override.rb +0 -2
  24. data/lib/alki/assembly/types/service.rb +4 -4
  25. data/lib/alki/circular_reference_error.rb +25 -0
  26. data/lib/alki/dsls/assembly.rb +1 -1
  27. data/lib/alki/dsls/assembly_group.rb +28 -12
  28. data/lib/alki/execution/context_class_builder.rb +1 -1
  29. data/lib/alki/execution/helpers.rb +4 -4
  30. data/lib/alki/execution/overlay_map.rb +37 -0
  31. data/lib/alki/execution/tag_map.rb +42 -0
  32. data/lib/alki/executor.rb +140 -0
  33. data/lib/alki/override_builder.rb +30 -24
  34. data/lib/alki/overrides.rb +4 -0
  35. data/lib/alki/version.rb +1 -1
  36. data/test/feature/mounts_test.rb +15 -0
  37. data/test/feature/multithreading_test.rb +0 -3
  38. data/test/feature/overlays_test.rb +2 -2
  39. data/test/feature/overrides_test.rb +26 -1
  40. data/test/feature/references_test.rb +35 -0
  41. data/test/feature/try_mounts_test.rb +23 -0
  42. data/test/feature/values_test.rb +14 -0
  43. data/test/feature_test_helper.rb +1 -0
  44. data/test/fixtures/example/config/assembly.rb +17 -8
  45. data/test/fixtures/example/config/handlers.rb +10 -5
  46. data/test/fixtures/example/lib/dsls/num_handler.rb +2 -2
  47. data/test/fixtures/example/lib/example/array_output.rb +13 -0
  48. data/test/fixtures/example/lib/example/echo_handler.rb +11 -0
  49. data/test/fixtures/example/lib/example/log_overlay.rb +12 -0
  50. data/test/fixtures/example/lib/example/num_handler.rb +13 -0
  51. data/test/fixtures/example/lib/example/range_handler.rb +13 -0
  52. data/test/fixtures/example/lib/example/switch_handler.rb +11 -0
  53. metadata +39 -44
  54. data/lib/alki/assembly/executor.rb +0 -137
  55. data/test/fixtures/example/lib/array_output.rb +0 -11
  56. data/test/fixtures/example/lib/echo_handler.rb +0 -9
  57. data/test/fixtures/example/lib/log_overlay.rb +0 -10
  58. data/test/fixtures/example/lib/num_handler.rb +0 -11
  59. data/test/fixtures/example/lib/range_handler.rb +0 -11
  60. data/test/fixtures/example/lib/switch_handler.rb +0 -9
@@ -1,137 +0,0 @@
1
- require 'alki/execution/context_class_builder'
2
- require 'alki/execution/cache_entry'
3
- require 'concurrent'
4
- require 'alki/invalid_path_error'
5
-
6
- module Alki
7
- module Assembly
8
- class Executor
9
- def initialize(assembly,meta)
10
- @assembly = assembly
11
- @meta = meta
12
- @semaphore = Concurrent::ReentrantReadWriteLock.new
13
- @lookup_cache = {}
14
- @call_cache = {}
15
- @context_cache = {}
16
- end
17
-
18
- def lock
19
- @semaphore.with_write_lock do
20
- yield
21
- end
22
- end
23
-
24
- def call(path,*args,&blk)
25
- execute({},path,args,blk)
26
- end
27
-
28
- def lookup(path)
29
- @semaphore.with_read_lock do
30
- unless @lookup_cache[path]
31
- @semaphore.with_write_lock do
32
- @lookup_cache[path] = lookup_elem(path).tap do |elem|
33
- unless elem
34
- raise InvalidPathError.new("Invalid path #{path.inspect}")
35
- end
36
- end
37
- end
38
- end
39
- @lookup_cache[path]
40
- end
41
- end
42
-
43
- def canonical_path(from,path)
44
- from_elem = lookup(from)
45
- scope = from_elem[:full_scope] || from_elem[:scope]
46
- path.inject(nil) do |p,elem|
47
- scope = lookup(p)[:scope] if p
48
- scope[elem]
49
- end
50
- end
51
-
52
- def execute(meta,path,args,blk)
53
- type,value = nil,nil
54
- @semaphore.with_read_lock do
55
- cache_entry = @call_cache[path]
56
- if cache_entry
57
- if cache_entry == :building
58
- raise "Circular element reference found: #{path.join(".")}"
59
- end
60
- type,value = cache_entry.type,cache_entry.value
61
- else
62
- @semaphore.with_write_lock do
63
- @call_cache[path] = :building
64
- type, value = build(path)
65
- @call_cache[path] = Alki::Execution::CacheEntry.finished type, value
66
- end
67
- end
68
- end
69
- call_value(type, value, meta, args, blk)
70
- end
71
-
72
- private
73
-
74
- def build(path)
75
- action = lookup(path)
76
- if action[:build]
77
- build_meta = {building: path.join('.')}
78
- build_meta.merge!(action[:meta]) if action[:meta]
79
- build_action = action[:build].merge(scope: action[:scope], modules: action[:modules])
80
- call_value(*process_action(build_action), build_meta, [action])
81
- end
82
- process_action action
83
- end
84
-
85
- def data_copy
86
- unless @data
87
- @data = {}
88
- @meta.each do |(from,meta)|
89
- meta.process self, from, @data
90
- end
91
- IceNine.deep_freeze @data
92
- end
93
- @data.dup
94
- end
95
-
96
- def lookup_elem(path)
97
- data = data_copy
98
- elem = @assembly
99
- path.each do |key|
100
- elem = elem.index data, key
101
- return nil unless elem
102
- end
103
- elem.output data
104
- end
105
-
106
- def process_action(action)
107
- if action.key?(:value)
108
- [:value,action[:value]]
109
- elsif action[:proc]
110
- if action[:scope]
111
- [:class,context_class(action)]
112
- else
113
- [:proc,action[:proc]]
114
- end
115
- end or raise "Invalid action"
116
- end
117
-
118
- def call_value(type,value,meta,args=[],blk=nil)
119
- case type
120
- when :value then value
121
- when :proc then proc.call *args, &blk
122
- when :class then value.new(self,meta).__call__ *args, &blk
123
- end
124
- end
125
-
126
- def context_class(action)
127
- desc = {
128
- scope: action[:scope],
129
- body: action[:proc],
130
- modules: action[:modules],
131
- methods: action[:methods]
132
- }
133
- @context_cache[desc] ||= Alki::Execution::ContextClassBuilder.build(desc)
134
- end
135
- end
136
- end
137
- end
@@ -1,11 +0,0 @@
1
- class ArrayOutput
2
- def initialize
3
- @output = []
4
- end
5
- def <<(val)
6
- @output << val
7
- end
8
- def to_a
9
- @output.dup
10
- end
11
- end
@@ -1,9 +0,0 @@
1
- class EchoHandler
2
- def initialize(output)
3
- @output = output
4
- end
5
-
6
- def handle(val)
7
- @output << val.to_s
8
- end
9
- end
@@ -1,10 +0,0 @@
1
- class LogOverlay
2
- def initialize(log)
3
- @log = log
4
- end
5
-
6
- def overlay_send(obj,info,method,*args,&blk)
7
- @log << "Calling #{info[:name]}##{method} #{args.join(", ")}\n"
8
- obj.public_send method, *args, &blk
9
- end
10
- end
@@ -1,11 +0,0 @@
1
- class NumHandler
2
- def initialize(num,message,output)
3
- @num = num
4
- @msg = message
5
- @output = output
6
- end
7
-
8
- def handle(val)
9
- @output << @msg if val % @num == 0
10
- end
11
- end
@@ -1,11 +0,0 @@
1
- class RangeHandler
2
- def initialize(subhandler)
3
- @subhandler = subhandler
4
- end
5
-
6
- def handle(range)
7
- range.each do |i|
8
- @subhandler.handle i
9
- end
10
- end
11
- end
@@ -1,9 +0,0 @@
1
- class SwitchHandler
2
- def initialize(handlers)
3
- @types = handlers
4
- end
5
-
6
- def handle(val)
7
- @types.find {|h| h.handle val }
8
- end
9
- end