alki 0.8.0 → 0.9.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.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/README.adoc +108 -6
  3. data/alki.gemspec +2 -2
  4. data/bin/alki +17 -0
  5. data/config/dsls.rb +2 -2
  6. data/doc/assembly_dsl.adoc +6 -6
  7. data/exe/alki +275 -0
  8. data/lib/alki/assembly/builder.rb +113 -0
  9. data/lib/alki/assembly/executor.rb +127 -0
  10. data/lib/alki/assembly/handler_base.rb +21 -0
  11. data/lib/alki/assembly/instance.rb +21 -0
  12. data/lib/alki/assembly/types/assembly.rb +92 -0
  13. data/lib/alki/assembly/types/factory.rb +29 -0
  14. data/lib/alki/assembly/types/func.rb +12 -0
  15. data/lib/alki/assembly/types/group.rb +39 -0
  16. data/lib/alki/assembly/types/override.rb +40 -0
  17. data/lib/alki/assembly/types/proc_value.rb +18 -0
  18. data/lib/alki/assembly/types/service.rb +27 -0
  19. data/lib/alki/assembly/types/value.rb +9 -0
  20. data/lib/alki/assembly.rb +21 -40
  21. data/lib/alki/dsls/assembly.rb +10 -12
  22. data/lib/alki/dsls/assembly_group.rb +92 -0
  23. data/lib/alki/dsls/assembly_type.rb +5 -15
  24. data/lib/alki/execution/cache_entry.rb +16 -0
  25. data/lib/alki/execution/context.rb +29 -0
  26. data/lib/alki/execution/context_class_builder.rb +36 -0
  27. data/lib/alki/execution/value_context.rb +14 -0
  28. data/lib/alki/overlay_delegator.rb +8 -20
  29. data/lib/alki/overlay_info.rb +3 -0
  30. data/lib/alki/override_builder.rb +6 -4
  31. data/lib/alki/service_delegator.rb +3 -3
  32. data/lib/alki/version.rb +1 -1
  33. data/lib/alki.rb +4 -4
  34. data/test/feature/alki_test.rb +1 -2
  35. data/test/feature/example_test.rb +2 -3
  36. data/test/feature/factories_test.rb +48 -0
  37. data/test/feature/overlays_test.rb +225 -0
  38. data/test/feature/overrides_test.rb +1 -2
  39. data/test/feature/pseudo_elements_test.rb +67 -0
  40. data/test/feature_test_helper.rb +1 -0
  41. data/test/fixtures/example/config/assembly.rb +11 -2
  42. data/test/fixtures/example/config/handlers.rb +2 -7
  43. data/test/fixtures/example/lib/log_overlay.rb +3 -3
  44. data/test/integration/dsls/assembly_test.rb +3 -8
  45. data/test/integration/dsls/assembly_type_test.rb +2 -2
  46. data/test/integration/dsls/service_dsl_test.rb +2 -2
  47. metadata +36 -18
  48. data/lib/alki/assembly_builder.rb +0 -109
  49. data/lib/alki/assembly_executor.rb +0 -129
  50. data/lib/alki/assembly_handler_base.rb +0 -19
  51. data/lib/alki/dsls/assembly_type_dsl.rb +0 -21
  52. data/lib/alki/dsls/assembly_types/assembly.rb +0 -101
  53. data/lib/alki/dsls/assembly_types/group.rb +0 -41
  54. data/lib/alki/dsls/assembly_types/load.rb +0 -31
  55. data/lib/alki/dsls/assembly_types/overlay.rb +0 -9
  56. data/lib/alki/dsls/assembly_types/value.rb +0 -100
  57. data/test/test_helper.rb +0 -1
@@ -1,4 +1,4 @@
1
- require_relative '../../test_helper'
1
+ require 'alki/test'
2
2
  require 'alki/dsls/assembly_type'
3
3
 
4
4
  describe Alki::Dsls::AssemblyType do
@@ -55,4 +55,4 @@ describe Alki::Dsls::AssemblyType do
55
55
  obj.output(2).must_equal "12"
56
56
  end
57
57
  end
58
- end
58
+ end
@@ -1,4 +1,4 @@
1
- require_relative '../../test_helper'
1
+ require 'alki/test'
2
2
  require 'alki/dsls/service'
3
3
 
4
4
  describe Alki::Dsls::Service do
@@ -54,4 +54,4 @@ describe Alki::Dsls::Service do
54
54
  end.uses.must_equal(['ts','ts2'])
55
55
  end
56
56
  end
57
- end
57
+ 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.8.0
4
+ version: 0.9.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-10 00:00:00.000000000 Z
11
+ date: 2016-12-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -67,7 +67,7 @@ dependencies:
67
67
  version: '0.3'
68
68
  - - ">="
69
69
  - !ruby/object:Gem::Version
70
- version: 0.3.1
70
+ version: 0.3.3
71
71
  type: :runtime
72
72
  prerelease: false
73
73
  version_requirements: !ruby/object:Gem::Requirement
@@ -77,26 +77,27 @@ dependencies:
77
77
  version: '0.3'
78
78
  - - ">="
79
79
  - !ruby/object:Gem::Version
80
- version: 0.3.1
80
+ version: 0.3.3
81
81
  - !ruby/object:Gem::Dependency
82
82
  name: alki-support
83
83
  requirement: !ruby/object:Gem::Requirement
84
84
  requirements:
85
85
  - - "~>"
86
86
  - !ruby/object:Gem::Version
87
- version: '0.5'
87
+ version: '0.6'
88
88
  type: :runtime
89
89
  prerelease: false
90
90
  version_requirements: !ruby/object:Gem::Requirement
91
91
  requirements:
92
92
  - - "~>"
93
93
  - !ruby/object:Gem::Version
94
- version: '0.5'
94
+ version: '0.6'
95
95
  description: Base library for building applications. Provides tools for organizing
96
96
  and connecting application units.
97
97
  email:
98
98
  - matt.edlefsen@gmail.com
99
- executables: []
99
+ executables:
100
+ - alki
100
101
  extensions: []
101
102
  extra_rdoc_files: []
102
103
  files:
@@ -106,35 +107,50 @@ files:
106
107
  - README.adoc
107
108
  - Rakefile
108
109
  - alki.gemspec
110
+ - bin/alki
109
111
  - config/dsls.rb
110
112
  - doc/assemblies.adoc
111
113
  - doc/assembly_dsl.adoc
112
114
  - doc/index.adoc
113
115
  - doc/projects.adoc
116
+ - exe/alki
114
117
  - lib/alki.rb
115
118
  - lib/alki/assembly.rb
116
- - lib/alki/assembly_builder.rb
117
- - lib/alki/assembly_executor.rb
118
- - lib/alki/assembly_handler_base.rb
119
+ - lib/alki/assembly/builder.rb
120
+ - lib/alki/assembly/executor.rb
121
+ - lib/alki/assembly/handler_base.rb
122
+ - lib/alki/assembly/instance.rb
123
+ - lib/alki/assembly/types/assembly.rb
124
+ - lib/alki/assembly/types/factory.rb
125
+ - lib/alki/assembly/types/func.rb
126
+ - lib/alki/assembly/types/group.rb
127
+ - lib/alki/assembly/types/override.rb
128
+ - lib/alki/assembly/types/proc_value.rb
129
+ - lib/alki/assembly/types/service.rb
130
+ - lib/alki/assembly/types/value.rb
119
131
  - lib/alki/bin.rb
120
132
  - lib/alki/dsls/assembly.rb
133
+ - lib/alki/dsls/assembly_group.rb
121
134
  - lib/alki/dsls/assembly_type.rb
122
- - lib/alki/dsls/assembly_type_dsl.rb
123
- - lib/alki/dsls/assembly_types/assembly.rb
124
- - lib/alki/dsls/assembly_types/group.rb
125
- - lib/alki/dsls/assembly_types/load.rb
126
- - lib/alki/dsls/assembly_types/overlay.rb
127
- - lib/alki/dsls/assembly_types/value.rb
128
135
  - lib/alki/dsls/service.rb
136
+ - lib/alki/execution/cache_entry.rb
137
+ - lib/alki/execution/context.rb
138
+ - lib/alki/execution/context_class_builder.rb
139
+ - lib/alki/execution/value_context.rb
129
140
  - lib/alki/feature_test.rb
130
141
  - lib/alki/overlay_delegator.rb
142
+ - lib/alki/overlay_info.rb
131
143
  - lib/alki/override_builder.rb
132
144
  - lib/alki/service_delegator.rb
133
145
  - lib/alki/test.rb
134
146
  - lib/alki/version.rb
135
147
  - test/feature/alki_test.rb
136
148
  - test/feature/example_test.rb
149
+ - test/feature/factories_test.rb
150
+ - test/feature/overlays_test.rb
137
151
  - test/feature/overrides_test.rb
152
+ - test/feature/pseudo_elements_test.rb
153
+ - test/feature_test_helper.rb
138
154
  - test/fixtures/example/config/assembly.rb
139
155
  - test/fixtures/example/config/handlers.rb
140
156
  - test/fixtures/example/config/settings.rb
@@ -150,7 +166,6 @@ files:
150
166
  - test/integration/dsls/assembly_test.rb
151
167
  - test/integration/dsls/assembly_type_test.rb
152
168
  - test/integration/dsls/service_dsl_test.rb
153
- - test/test_helper.rb
154
169
  homepage: https://github.com/alki-project/alki
155
170
  licenses:
156
171
  - MIT
@@ -178,7 +193,11 @@ summary: Base library for building applications.
178
193
  test_files:
179
194
  - test/feature/alki_test.rb
180
195
  - test/feature/example_test.rb
196
+ - test/feature/factories_test.rb
197
+ - test/feature/overlays_test.rb
181
198
  - test/feature/overrides_test.rb
199
+ - test/feature/pseudo_elements_test.rb
200
+ - test/feature_test_helper.rb
182
201
  - test/fixtures/example/config/assembly.rb
183
202
  - test/fixtures/example/config/handlers.rb
184
203
  - test/fixtures/example/config/settings.rb
@@ -194,4 +213,3 @@ test_files:
194
213
  - test/integration/dsls/assembly_test.rb
195
214
  - test/integration/dsls/assembly_type_test.rb
196
215
  - test/integration/dsls/service_dsl_test.rb
197
- - test/test_helper.rb
@@ -1,109 +0,0 @@
1
- require 'alki/assembly'
2
- require 'alki/class_builder'
3
- require 'alki/dsl'
4
- require 'alki/support'
5
-
6
- module Alki
7
- class AssemblyBuilder
8
- def initialize
9
- @assembly_options = {}
10
- @assembly_name = nil
11
- @definition = nil
12
- end
13
-
14
- attr_reader :assembly_options, :assembly_name, :definition
15
-
16
- def self.build(opts={},&blk)
17
- new.build(opts,&blk)
18
- end
19
-
20
- def build(opts={},&blk)
21
- build_assembly blk if blk
22
- if opts[:config_dir]
23
- context = if opts[:project_assembly]
24
- File.dirname opts[:project_assembly]
25
- else
26
- Dir.pwd
27
- end
28
- set_config_directory File.expand_path opts[:config_dir], context
29
- end
30
- set_assembly_name opts[:name] if opts[:name]
31
- setup_project_assembly opts[:project_assembly] if opts[:project_assembly]
32
- load_assembly_file opts[:primary_config] unless definition
33
- build_empty_assembly unless definition
34
- build_class
35
- end
36
-
37
- def setup_project_assembly(path)
38
- root = Alki::Support.find_root(path) do |dir|
39
- File.exists?(File.join(dir,'config','assembly.rb')) ||
40
- File.exists?(File.join(dir,'Gemfile')) ||
41
- !Dir.glob(File.join(dir,'*.gemspec')).empty?
42
- end
43
- if root
44
- unless @assembly_options[:load_path]
45
- config_dir = File.join(root,'config')
46
- set_config_directory config_dir if File.exists? config_dir
47
- end
48
-
49
- unless @assembly_name
50
- lib_dir = File.join(root,'lib')
51
- name = Alki::Support.path_name path, lib_dir
52
- unless name
53
- raise "Can't auto-detect name of assembly"
54
- end
55
- set_assembly_name name
56
- end
57
- end
58
- end
59
-
60
- def set_assembly_name(name)
61
- @assembly_name = name
62
- end
63
-
64
- def set_config_directory(config_dir)
65
- Alki::Dsl.register_dir config_dir, 'alki/dsls/assembly', {config_dir: config_dir}
66
- @assembly_options[:load_path] = config_dir
67
- end
68
-
69
- def load_assembly_file(name = nil)
70
- name ||= 'assembly'
71
- if @assembly_options[:load_path]
72
- assembly_config_path = File.join(@assembly_options[:load_path],"#{name}.rb")
73
- if File.exists? assembly_config_path
74
- @definition = Alki::Dsl.load(assembly_config_path)[:class]
75
- true
76
- end
77
- end
78
- end
79
-
80
- def build_empty_assembly
81
- build_assembly ->{}
82
- end
83
-
84
- def build_assembly(blk)
85
- @definition = Alki::Dsl.build('alki/dsls/assembly', &blk)[:class]
86
- end
87
-
88
- def build_class
89
- assembly_options = @assembly_options
90
- definition = @definition
91
- Alki::ClassBuilder.build(
92
- prefix: '',
93
- name: @assembly_name,
94
- class_modules: [Alki::Assembly],
95
- type: :module,
96
- class_methods: {
97
- definition: {
98
- body: ->{
99
- definition
100
- }
101
- },
102
- assembly_options: {
103
- body: ->{ assembly_options }
104
- }
105
- }
106
- )
107
- end
108
- end
109
- end
@@ -1,129 +0,0 @@
1
- require 'alki/service_delegator'
2
- require 'alki/overlay_delegator'
3
- require 'alki/class_builder'
4
-
5
- module Alki
6
- class AssemblyExecutor
7
- class Resource
8
- attr_reader :pkg, :cache, :elem
9
- def initialize(pkg,cache,elem)
10
- @pkg = pkg
11
- @cache = cache
12
- @elem = elem
13
- end
14
-
15
- def with_elem(elem)
16
- Resource.new @pkg, @cache, elem
17
- end
18
- end
19
-
20
- def initialize(data={})
21
- @data = data
22
- end
23
-
24
- def call(assembly,cache,path,*args,&blk)
25
- unless cache[path]
26
- elem = assembly.lookup path, @data
27
- raise "Path not found: #{path.join('.')}" unless elem
28
- res = Resource.new assembly, cache, elem
29
- cache[path] = case elem[:type]
30
- when :value
31
- value res, path
32
- when :group
33
- group res
34
- end
35
- end
36
- cache[path].call *args, &blk
37
- end
38
-
39
- def value(res,path)
40
- evaluator = -> (value_block,*args,&blk) {
41
- with_scope_context(res,value_block) do |ctx|
42
- val = ctx.__call__(*args,&blk)
43
- if res.elem[:overlays]
44
- val = apply_overlays res, path, val
45
- end
46
- val
47
- end
48
- }
49
- res.elem[:block].call evaluator
50
- end
51
-
52
- def apply_overlays(res,path,obj)
53
- res.elem[:overlays].inject(obj) do |obj,overlay_elem|
54
- unless res.cache[overlay_elem[:block]]
55
- with_scope_context(res.with_elem(overlay_elem)) do |ctx|
56
- res.cache[overlay_elem[:block]] = ctx.__call__
57
- end
58
- end
59
- local_path = path[overlay_elem[:scope][:root].size..-1].join('.')
60
- Alki::OverlayDelegator.new local_path,obj, res.cache[overlay_elem[:block]]
61
- end
62
- end
63
-
64
- def group(res)
65
- proc = -> (name,*args,&blk) {
66
- call res.pkg, res.cache, res.elem[:scope][name], *args, &blk
67
- }
68
- group = create_context(GroupContext,res)
69
- -> { group }
70
- end
71
-
72
- def with_scope_context(res,blk = nil)
73
- methods = {
74
- __call__: { body: (blk || res.elem[:block])}
75
- }
76
- yield create_context(ValueContext,res,methods)
77
- end
78
-
79
- def create_context(super_class,res,methods={})
80
- executor = self
81
-
82
- res.elem[:scope].keys.each do |meth|
83
- methods[meth] = {
84
- body: ->(*args,&blk) {
85
- executor.call res.pkg, res.cache, res.elem[:scope][meth], *args, &blk
86
- }
87
- }
88
- end
89
- context_class = Alki::ClassBuilder.build(
90
- super_class: super_class,
91
- instance_methods: methods
92
- )
93
- context_class.new
94
- end
95
-
96
- class Context
97
- end
98
-
99
- class ValueContext < Context
100
- def lookup(path)
101
- unless path.is_a?(String) or path.is_a?(Symbol)
102
- raise ArgumentError.new("lookup can only take Strings or Symbols")
103
- end
104
- path.to_s.split('.').inject(self) do |group,name|
105
- raise "Invalid lookup path" unless group.is_a? Context
106
- group.send name.to_sym
107
- end
108
- end
109
-
110
- def lazy(path)
111
- unless path.is_a?(String) or path.is_a?(Symbol)
112
- raise ArgumentError.new("lazy can only take Strings or Symbols")
113
- end
114
- Alki::ServiceDelegator.new assembly, path
115
- end
116
- end
117
-
118
- class GroupContext < Context
119
- def lookup(path)
120
- unless path.is_a?(String) or path.is_a?(Symbol)
121
- raise ArgumentError.new("lookup can only take Strings or Symbols")
122
- end
123
- path.to_s.split('.').inject(self) do |group,name|
124
- group.send name.to_sym
125
- end
126
- end
127
- end
128
- end
129
- end
@@ -1,19 +0,0 @@
1
- module Alki
2
- class AssemblyHandlerBase
3
- def initialize(elem,data,key=nil)
4
- @elem = elem
5
- @data = data
6
- @key = key
7
- end
8
-
9
- attr_reader :elem, :data, :key
10
-
11
- def index
12
- raise NotImplementedError.new("Can't index into this element")
13
- end
14
-
15
- def output
16
- raise NotImplementedError.new("Can't output this element")
17
- end
18
- end
19
- end
@@ -1,21 +0,0 @@
1
- require 'alki/dsls/assembly_type'
2
-
3
- Alki do
4
- require_dsl 'alki/dsls/dsl'
5
-
6
- dsl_method :element_type do |name,&blk|
7
- data = Alki::Dsls::AssemblyType.build(prefix: 'alki/assembly_types', name: name,&blk)
8
- klass = data[:class]
9
- add_helper "build_#{name}".to_sym, &klass.method(:new)
10
- add_helper "add_#{name}".to_sym do |name,*args|
11
- add name, klass.new(*args)
12
- end
13
- end
14
-
15
- finish do
16
- add_method :add do |name,elem|
17
- (ctx[:elems]||={})[name.to_sym] = elem
18
- nil
19
- end
20
- end
21
- end
@@ -1,101 +0,0 @@
1
- require 'alki/override_builder'
2
- require 'alki/support'
3
-
4
- Alki do
5
- require_dsl 'alki/dsls/assembly_types/group'
6
- require_dsl 'alki/dsls/assembly_types/value'
7
-
8
- dsl_method :assembly do |name,pkg=name.to_s,**overrides,&blk|
9
- klass = Alki::Support.load_class pkg
10
- config_dir = klass.assembly_options[:load_path]
11
- config_dir = build_value config_dir if config_dir
12
- overrides = Alki::OverrideBuilder.build overrides, &blk
13
-
14
- add_assembly name, klass.root, config_dir, overrides
15
- end
16
-
17
- element_type :assembly do
18
- attr :root
19
- attr :config_dir
20
- attr :overrides, nil
21
-
22
- index do
23
- if key == :config_dir
24
- data.merge! main_data
25
- config_dir
26
- elsif key == :original
27
- root
28
- else
29
- if overrides
30
- data.replace(
31
- main: data.merge(main_data),
32
- override: override_data,
33
- )
34
- override.index data, key
35
- else
36
- root.index data.merge!(main_data), key
37
- end
38
- end
39
- end
40
-
41
- output do
42
- scope = root.output(data)[:scope]
43
- scope[:config_dir] = (data[:prefix]||[]) + [:config_dir]
44
- scope[:original] = (data[:prefix]||[]) + [:original]
45
- scope.merge! overrides.output(data)[:scope] if overrides
46
- {
47
- type: :group,
48
- scope: scope,
49
- }
50
- end
51
-
52
- def override_data
53
- od = data.dup
54
- od[:scope] ||= {}
55
- od[:scope].merge! original: ((data[:prefix]||[]) + [:original])
56
- od
57
- end
58
-
59
- def main_data
60
- assembly_path = data[:prefix] ? data[:prefix].dup : []
61
- {scope: {assembly: assembly_path, root: [], config_dir: (assembly_path + [:config_dir])}, overlays: []}
62
- end
63
-
64
- def override
65
- Alki::AssemblyTypes::Override.new root, overrides
66
- end
67
- end
68
-
69
- element_type :override do
70
- attr :main
71
- attr :override
72
-
73
- index do
74
- main_child = main.index data[:main], key
75
- override_child = override.index data[:override], key
76
-
77
- if main_child && override_child
78
- (data[:main][:scope]||={}).merge! (data[:override][:scope]||{})
79
- (data[:main][:overlays]||=[]).push *(data[:override][:overlays]||[])
80
- Alki::AssemblyTypes::Override.new main_child, override_child
81
- elsif main_child
82
- data.replace data[:main]
83
- main_child
84
- elsif override_child
85
- data.replace data[:override]
86
- override_child
87
- end
88
- end
89
-
90
- output do
91
- result = override.output(data[:override])
92
- if result[:type] == :group
93
- main_result = main.output(data[:main])
94
- if main_result[:type] == :group
95
- result[:scope] = main_result[:scope].merge result[:scope]
96
- end
97
- end
98
- result
99
- end
100
- end
101
- end
@@ -1,41 +0,0 @@
1
- require 'alki/dsls/assembly'
2
-
3
- Alki do
4
- dsl_method :group do |name,&blk|
5
- add name, Alki::Dsls::Assembly.build(&blk)[:root]
6
- end
7
-
8
- element_type :group do
9
- attr :children, {}
10
- attr :overlays, []
11
-
12
- index do
13
- data[:scope] ||= {}
14
- data[:prefix] ||= []
15
- update_scope children, data[:prefix], data[:scope]
16
- data[:prefix] << key
17
-
18
- if overlays
19
- data[:overlays] = overlays.map do |o|
20
- o == :clear ? o : {block: o, scope: data[:scope].merge(root: [])}
21
- end
22
- end
23
-
24
- children[key]
25
- end
26
-
27
- output do
28
- {
29
- type: :group,
30
- scope: update_scope(children,data[:prefix]||[],{})
31
- }
32
- end
33
-
34
- def update_scope(children, prefix, scope)
35
- children.keys.inject(scope) do |h,k|
36
- h.merge! k => (prefix+[k])
37
- end
38
- scope
39
- end
40
- end
41
- end
@@ -1,31 +0,0 @@
1
- require 'alki/support'
2
-
3
- Alki do
4
- dsl_method :load do |group_name,name=group_name.to_s|
5
- add_load group_name, name
6
- end
7
-
8
- element_type :load do
9
- attr :name
10
-
11
- index do
12
- group.index data, key
13
- end
14
-
15
- output do
16
- group.output data
17
- end
18
-
19
- def group
20
- unless (data[:loaded]||={})[name]
21
- path = if data[:load_path]
22
- File.join(data[:load_path],"#{name}.rb")
23
- else
24
- name
25
- end
26
- data[:loaded][name] = Alki::Dsl.load(path)[:class].root
27
- end
28
- data[:loaded][name]
29
- end
30
- end
31
- end
@@ -1,9 +0,0 @@
1
- Alki do
2
- dsl_method :overlay do |&blk|
3
- (ctx[:overlays]||=[]) << blk
4
- end
5
-
6
- dsl_method :clear_overlays do
7
- (ctx[:overlays]||=[]) << :clear
8
- end
9
- end