alki 0.12.0 → 0.12.1

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.
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