sparkle_formation 2.0.2 → 2.1.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/docs/building-blocks.md +1 -1
- data/docs/inheritance-merging.md +159 -0
- data/lib/sparkle_formation/error.rb +3 -0
- data/lib/sparkle_formation/sparkle.rb +4 -1
- data/lib/sparkle_formation/sparkle_collection.rb +26 -14
- data/lib/sparkle_formation/sparkle_collection/rainbow.rb +92 -0
- data/lib/sparkle_formation/sparkle_formation.rb +140 -19
- data/lib/sparkle_formation/version.rb +1 -1
- data/sparkle_formation.gemspec +1 -1
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7ed2f1e3bec855db611f4a8fcd7c3e3c509aa209
|
4
|
+
data.tar.gz: d6dc132ef582d52c55080c4a4e80d60fbb28c702
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 09bd692653d5f7816a332fc2d7f772760bac7e13e34e8314518f99ec48604146a5c8bdf5ce3a321a4599307dcbf6b5673800979a9497c75e708722772882c4c0
|
7
|
+
data.tar.gz: e4958183360a572b03aff5ebeab2a9c2ea6db984f8db91bb146b0d26b59665290096a43a0d05e425ecdcfd6c096bb080205a25c3e44f0ce798f34632a9affe4e
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
# v2.1.0
|
2
|
+
* Add template inheritance support (#145)
|
3
|
+
* Add layer merging support for templates, components, and dynamics (#145)
|
4
|
+
* Update allowed Ruby constraint to require version greater than or equal to 2.1
|
5
|
+
|
1
6
|
# v2.0.2
|
2
7
|
* Provide useful return value from `#dynamic!` (#137)
|
3
8
|
* Implement proper Azure resource generator (#141)
|
data/docs/building-blocks.md
CHANGED
@@ -0,0 +1,159 @@
|
|
1
|
+
---
|
2
|
+
title: "Inheritance and Merging"
|
3
|
+
category: "dsl"
|
4
|
+
weight: 8
|
5
|
+
anchors:
|
6
|
+
- title: "Template Inheritance"
|
7
|
+
url: "#template-inheritance"
|
8
|
+
- title: "Template Merging"
|
9
|
+
url: "#template-merging"
|
10
|
+
- title: "Component and Dynamic Merging"
|
11
|
+
url: "#component-and-dynamic-merging"
|
12
|
+
- title: "Registry Items"
|
13
|
+
url: "#registry-items"
|
14
|
+
---
|
15
|
+
|
16
|
+
## Inheritance and Merging
|
17
|
+
|
18
|
+
SparkleFormation includes functionality allowing SparklePacks to
|
19
|
+
interact with previous layers when a file is requested from the
|
20
|
+
collection. This functionality makes it easy to slightly modify
|
21
|
+
files provided within previously registered SparklePacks without
|
22
|
+
having to recreate the entire contents of the file. It also allows
|
23
|
+
for creation of new templates based on existing templates.
|
24
|
+
|
25
|
+
### Template Inheritance
|
26
|
+
|
27
|
+
Template inheritance allows a new template to inherit the data structures
|
28
|
+
of an existing template. For example, lets start with a simple template:
|
29
|
+
|
30
|
+
~~~ruby
|
31
|
+
SparkleFormation.new(:simple) do
|
32
|
+
simple_template true
|
33
|
+
end
|
34
|
+
~~~
|
35
|
+
|
36
|
+
The dumped result of this template is:
|
37
|
+
|
38
|
+
~~~json
|
39
|
+
{
|
40
|
+
"SimpleTemplate": true
|
41
|
+
}
|
42
|
+
~~~
|
43
|
+
|
44
|
+
Suppose that we wanted create a new template that was composed of everything
|
45
|
+
described in the `simple` template, but had an extra addition. Instead of
|
46
|
+
re-creating the contents in a new file, or attempting to break out components
|
47
|
+
or dynamics that may not be ideal, we can inherit the template instead:
|
48
|
+
|
49
|
+
~~~ruby
|
50
|
+
SparkleFormation.new(:advanced, :inherit => :simple) do
|
51
|
+
advanced.item 'added'
|
52
|
+
end
|
53
|
+
~~~
|
54
|
+
|
55
|
+
When this template is dumped, it will inherit the `simple` template and
|
56
|
+
add on to the resultant data structure giving the result:
|
57
|
+
|
58
|
+
~~~json
|
59
|
+
{
|
60
|
+
"SimpleTemplate": true,
|
61
|
+
"Advanced": {
|
62
|
+
"Item": "added"
|
63
|
+
}
|
64
|
+
}
|
65
|
+
~~~
|
66
|
+
|
67
|
+
Inheritance is not restricted to templates at a common level. A new
|
68
|
+
template can inherit templates provided by SparklePacks.
|
69
|
+
|
70
|
+
### Template Merging
|
71
|
+
|
72
|
+
Template merging is only applicable when SparklePacks are in use. Template
|
73
|
+
merging allows direct modification of a specific named template. This strategy
|
74
|
+
is extremely useful when packs may be layering functionality into a template,
|
75
|
+
or the root pack wants to make a specific adjustment without creating a new
|
76
|
+
template.
|
77
|
+
|
78
|
+
The default behavior of SparkleFormation when a SparklePack provides a template with
|
79
|
+
the same name as a previously loaded SparklePack, it will overwrite the original
|
80
|
+
template. In some cases, this may not be the desired effect. If a pack would like
|
81
|
+
to make a simple adjustment to the template, this would require duplicating the
|
82
|
+
contents of the original template and appending the customization. Merging allows
|
83
|
+
adding customization without recreation.
|
84
|
+
|
85
|
+
Lets assume we have a core SparklePack loaded and it provides us with the `simple`
|
86
|
+
template:
|
87
|
+
|
88
|
+
~~~ruby
|
89
|
+
SparkleFormation.new(:simple) do
|
90
|
+
simple_template true
|
91
|
+
end
|
92
|
+
~~~
|
93
|
+
|
94
|
+
Now in our root SparklePack we want to make an adjustment to the `simple` template
|
95
|
+
directly. We can do this by merging:
|
96
|
+
|
97
|
+
~~~ruby
|
98
|
+
SparkleFormation.new(:simple, :layering => :merge) do
|
99
|
+
modifier 'spox'
|
100
|
+
end
|
101
|
+
~~~
|
102
|
+
|
103
|
+
When we dump the `simple` template now we get:
|
104
|
+
|
105
|
+
~~~json
|
106
|
+
{
|
107
|
+
"SimpleTemplate": true,
|
108
|
+
"Modifier": "spox"
|
109
|
+
}
|
110
|
+
~~~
|
111
|
+
|
112
|
+
This sort of merging make two strategies possible:
|
113
|
+
|
114
|
+
1. Modifying the final result of a template for a specific need
|
115
|
+
2. Modifying at serveral layers to allow SparklePacks to be additive
|
116
|
+
|
117
|
+
### Component and Dynamic Merging
|
118
|
+
|
119
|
+
Merging behavior for components and dynamics follows the same pattern as templates.
|
120
|
+
Adding the `:layering => :merge` option will cause the item to be merged instead
|
121
|
+
of overwritten.
|
122
|
+
|
123
|
+
For components:
|
124
|
+
|
125
|
+
~~~ruby
|
126
|
+
SparkleFormation.component(:name, :layering => :merge)
|
127
|
+
~~~
|
128
|
+
|
129
|
+
and dynamics:
|
130
|
+
|
131
|
+
~~~ruby
|
132
|
+
SparkleFormation.dynamic(:name, :layering => :merge)
|
133
|
+
~~~
|
134
|
+
|
135
|
+
#### Dynamic return value
|
136
|
+
|
137
|
+
The return value of a dynamic cannot be inferred. This is due to the freeform nature
|
138
|
+
of dynamics leaving the resulting return value up to the author of the dynamic. When
|
139
|
+
merging dynamics it can be easy to return the wrong value. The library _could_ take
|
140
|
+
care of this and always return the context provided by the initial dynamic, but this
|
141
|
+
behavior is problematic: merges could remove the original context, or may want to
|
142
|
+
change the return context completely. Returning the proper value is left to the
|
143
|
+
author, but SparkleFormation makes it easy to return the previous context.
|
144
|
+
|
145
|
+
When the dynamics are merged, SparkleFormation will include an extra key in the
|
146
|
+
options `Hash` for the dynamic: `:previous_layer_result`. Now a dynamic can merge
|
147
|
+
in extra changes, and ensure the correct value is returned from the call:
|
148
|
+
|
149
|
+
~~~ruby
|
150
|
+
SparkleFormation.dynamic(:name, :layering => :merge) do |name, args={}|
|
151
|
+
new.things.added 'here'
|
152
|
+
args[:previous_layer_result]
|
153
|
+
end
|
154
|
+
~~~
|
155
|
+
|
156
|
+
### Registry Items
|
157
|
+
|
158
|
+
Registry items are exempt from the merging behavior described above. Registry items
|
159
|
+
are always overwritten when redefined in higher level SparklePacks.
|
@@ -110,11 +110,14 @@ class SparkleFormation
|
|
110
110
|
).last
|
111
111
|
end
|
112
112
|
|
113
|
-
def component(name, &block)
|
113
|
+
def component(name, args={}, &block)
|
114
114
|
part_data[:component].push(
|
115
115
|
::Smash.new(
|
116
116
|
:name => name,
|
117
117
|
:block => block,
|
118
|
+
:args => Smash[
|
119
|
+
args.map(&:to_a)
|
120
|
+
],
|
118
121
|
:type => :component
|
119
122
|
)
|
120
123
|
).last
|
@@ -6,6 +6,8 @@ class SparkleFormation
|
|
6
6
|
# leak on long running processes with long lasting collections
|
7
7
|
class SparkleCollection < Sparkle
|
8
8
|
|
9
|
+
autoload :Rainbow, 'sparkle_formation/sparkle_collection/rainbow'
|
10
|
+
|
9
11
|
# Create a new collection of sparkles
|
10
12
|
#
|
11
13
|
# @return [self]
|
@@ -68,7 +70,10 @@ class SparkleFormation
|
|
68
70
|
memoize("components_#{checksum}") do
|
69
71
|
Smash.new.tap do |hsh|
|
70
72
|
sparkles.each do |sprkl|
|
71
|
-
|
73
|
+
sprkl.components.each_pair do |c_name, c_value|
|
74
|
+
hsh[c_name] ||= Rainbow.new(c_name, :component)
|
75
|
+
hsh[c_name].add_layer(c_value)
|
76
|
+
end
|
72
77
|
end
|
73
78
|
end
|
74
79
|
end
|
@@ -79,7 +84,10 @@ class SparkleFormation
|
|
79
84
|
memoize("dynamics_#{checksum}") do
|
80
85
|
Smash.new.tap do |hsh|
|
81
86
|
sparkles.each do |sprkl|
|
82
|
-
|
87
|
+
sprkl.dynamics.each_pair do |c_name, c_value|
|
88
|
+
hsh[c_name] ||= Rainbow.new(c_name, :dynamic)
|
89
|
+
hsh[c_name].add_layer(c_value)
|
90
|
+
end
|
83
91
|
end
|
84
92
|
end
|
85
93
|
end
|
@@ -101,7 +109,10 @@ class SparkleFormation
|
|
101
109
|
memoize("templates_#{checksum}") do
|
102
110
|
Smash.new.tap do |hsh|
|
103
111
|
sparkles.each do |sprkl|
|
104
|
-
|
112
|
+
sprkl.templates.each_pair do |c_name, c_value|
|
113
|
+
hsh[c_name] ||= Rainbow.new(c_name, :template)
|
114
|
+
hsh[c_name].add_layer(c_value)
|
115
|
+
end
|
105
116
|
end
|
106
117
|
end
|
107
118
|
end
|
@@ -113,20 +124,21 @@ class SparkleFormation
|
|
113
124
|
# @param name [String, Symbol] name of item
|
114
125
|
# @return [Smash] requested item
|
115
126
|
# @raises [NameError, Error::NotFound]
|
116
|
-
def get(
|
127
|
+
def get(type, name)
|
128
|
+
type_name = Sparkle::TYPES[type.to_s]
|
129
|
+
unless(type_name)
|
130
|
+
raise ArgumentError.new "Unknown file type requested from collection `#{type}`"
|
131
|
+
end
|
117
132
|
result = nil
|
118
133
|
error = nil
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
if(result)
|
126
|
-
result
|
127
|
-
else
|
128
|
-
raise error
|
134
|
+
result = send(type_name)[name]
|
135
|
+
unless(result)
|
136
|
+
error_klass = Error::NotFound.const_get(
|
137
|
+
Bogo::Utility.camel(type)
|
138
|
+
)
|
139
|
+
raise error_klass.new(:name => name)
|
129
140
|
end
|
141
|
+
result
|
130
142
|
end
|
131
143
|
|
132
144
|
protected
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'sparkle_formation'
|
2
|
+
require 'forwardable'
|
3
|
+
|
4
|
+
class SparkleFormation
|
5
|
+
|
6
|
+
class SparkleCollection
|
7
|
+
|
8
|
+
# Contains a layered number of a specific item defined via
|
9
|
+
# a Sparkle. Items higher in the spectrum (greater layer index)
|
10
|
+
# have higher precedence than those below. This can be used for
|
11
|
+
# properly generating the end result based on merging or knockout rules.
|
12
|
+
class Rainbow
|
13
|
+
|
14
|
+
# Valid types for a rainbow
|
15
|
+
VALID_TYPES = [
|
16
|
+
:template,
|
17
|
+
:component,
|
18
|
+
:dynamic
|
19
|
+
].freeze
|
20
|
+
|
21
|
+
extend Forwardable
|
22
|
+
def_delegators :top, *(Smash.public_instance_methods - Object.public_instance_methods)
|
23
|
+
|
24
|
+
# @return [String]
|
25
|
+
attr_reader :name
|
26
|
+
# @return [Symbol]
|
27
|
+
attr_reader :type
|
28
|
+
# @return [Array<Hash>]
|
29
|
+
attr_reader :spectrum
|
30
|
+
|
31
|
+
# Create a new rainbow
|
32
|
+
#
|
33
|
+
# @param name [String, Symbol] name of item
|
34
|
+
# @param type [String, Symbol] type of item
|
35
|
+
# @return [self]
|
36
|
+
def initialize(name, type)
|
37
|
+
unless(VALID_TYPES.include?(type.to_sym))
|
38
|
+
raise ArgumentError.new "Invalid type provdied for Rainbow instance `#{type}`"
|
39
|
+
end
|
40
|
+
@name = name.to_s
|
41
|
+
@type = type.to_sym
|
42
|
+
@spectrum = []
|
43
|
+
end
|
44
|
+
|
45
|
+
# Add a new layer to the top of the spectrum
|
46
|
+
#
|
47
|
+
# @param item [Hash]
|
48
|
+
# @return [self]
|
49
|
+
def add_layer(item)
|
50
|
+
unless(item.is_a?(Hash))
|
51
|
+
raise TypeError.new "Expecting type `Hash` but received type `#{item.class}`"
|
52
|
+
end
|
53
|
+
spectrum << item.to_smash
|
54
|
+
self
|
55
|
+
end
|
56
|
+
|
57
|
+
# Fetch item defined at given layer
|
58
|
+
#
|
59
|
+
# @param idx [Integer]
|
60
|
+
# @return [Hash]
|
61
|
+
def layer_at(idx)
|
62
|
+
if(idx <= spectrum.size)
|
63
|
+
spectrum.at(idx)
|
64
|
+
else
|
65
|
+
raise KeyError.new "Invalid layer requested for #{type} - #{name} (index: #{idx})"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# Generates a list of items to be processed in
|
70
|
+
# order to achieve the correct result based on
|
71
|
+
# expected merging behavior
|
72
|
+
#
|
73
|
+
# @return [Array<Hash>]
|
74
|
+
def monochrome
|
75
|
+
Array.new.tap do |result|
|
76
|
+
spectrum.each do |item|
|
77
|
+
unless(item.get(:args, :layering).to_s == 'merge')
|
78
|
+
result.clear
|
79
|
+
end
|
80
|
+
result << item
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# @return [Hash]
|
86
|
+
def top
|
87
|
+
spectrum.last || {}
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
end
|
@@ -94,11 +94,14 @@ class SparkleFormation
|
|
94
94
|
# @return [Hashish, SparkleStruct]
|
95
95
|
def compile(path, *args)
|
96
96
|
opts = args.detect{|i| i.is_a?(Hash) } || {}
|
97
|
-
|
98
|
-
|
99
|
-
|
97
|
+
unless(path.is_a?(String) && File.file?(path.to_s))
|
98
|
+
if(spath = (opts.delete(:sparkle_path) || SparkleFormation.sparkle_path))
|
99
|
+
container = Sparkle.new(:root => spath)
|
100
|
+
path = container.get(:template, path)[:path]
|
101
|
+
end
|
100
102
|
end
|
101
103
|
formation = instance_eval(IO.read(path), path, 1)
|
104
|
+
formation.template_path = path
|
102
105
|
if(args.delete(:sparkle))
|
103
106
|
formation
|
104
107
|
else
|
@@ -213,7 +216,17 @@ class SparkleFormation
|
|
213
216
|
begin
|
214
217
|
dyn = struct._self.sparkle.get(:dynamic, dynamic_name)
|
215
218
|
raise dyn if dyn.is_a?(Exception)
|
216
|
-
|
219
|
+
dyn.monochrome.each do |dynamic_item|
|
220
|
+
if(result)
|
221
|
+
opts = args.detect{|i| i.is_a?(Hash)}
|
222
|
+
if(opts)
|
223
|
+
opts[:previous_layer_result] = result
|
224
|
+
else
|
225
|
+
args.push(:previous_layer_result => result)
|
226
|
+
end
|
227
|
+
end
|
228
|
+
result = struct.instance_exec(*args, &dynamic_item[:block])
|
229
|
+
end
|
217
230
|
if(block_given?)
|
218
231
|
result.instance_exec(&block)
|
219
232
|
end
|
@@ -364,6 +377,10 @@ class SparkleFormation
|
|
364
377
|
attr_reader :provider
|
365
378
|
# @return [Class] Provider resources
|
366
379
|
attr_reader :provider_resources
|
380
|
+
# @return [String] local path to template
|
381
|
+
attr_accessor :template_path
|
382
|
+
# @return [Array<String>] black listed templates
|
383
|
+
attr_reader :blacklisted_templates
|
367
384
|
|
368
385
|
# Create new instance
|
369
386
|
#
|
@@ -379,19 +396,23 @@ class SparkleFormation
|
|
379
396
|
def initialize(name, options={}, &block)
|
380
397
|
@name = name.to_sym
|
381
398
|
@component_paths = []
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
399
|
+
if(options[:sparkle_collection])
|
400
|
+
@sparkle = options[:sparkle_collection]
|
401
|
+
else
|
402
|
+
@sparkle = SparkleCollection.new
|
403
|
+
@sparkle.set_root(
|
404
|
+
Sparkle.new(
|
405
|
+
Smash.new.tap{|h|
|
406
|
+
s_path = options.fetch(:sparkle_path,
|
407
|
+
self.class.custom_paths[:sparkle_path]
|
408
|
+
)
|
409
|
+
if(s_path)
|
410
|
+
h[:root] = s_path
|
411
|
+
end
|
412
|
+
}
|
413
|
+
)
|
393
414
|
)
|
394
|
-
|
415
|
+
end
|
395
416
|
self.provider = options.fetch(:provider, @parent ? @parent.provider : :aws)
|
396
417
|
if(provider == :aws || !options[:disable_aws_builtins])
|
397
418
|
require 'sparkle_formation/aws'
|
@@ -405,16 +426,105 @@ class SparkleFormation
|
|
405
426
|
stack_resource_type,
|
406
427
|
*options.fetch(:stack_resource_types, [])
|
407
428
|
].compact.uniq
|
429
|
+
@blacklisted_templates = [name]
|
408
430
|
@components = Smash.new
|
409
431
|
@load_order = []
|
410
432
|
@overrides = []
|
411
433
|
@parent = options[:parent]
|
434
|
+
@seed = Smash.new(
|
435
|
+
:inherit => options[:inherit],
|
436
|
+
:layering => options[:layering]
|
437
|
+
)
|
412
438
|
if(block)
|
413
439
|
load_block(block)
|
414
440
|
end
|
415
441
|
@compiled = nil
|
416
442
|
end
|
417
443
|
|
444
|
+
# @return [Array<Proc>]
|
445
|
+
def raw_overrides
|
446
|
+
@overrides
|
447
|
+
end
|
448
|
+
|
449
|
+
# Update underlying data structures based on inherit
|
450
|
+
# or layering behavior if defined for this template
|
451
|
+
#
|
452
|
+
# @param options [Hash]
|
453
|
+
# @return [self]
|
454
|
+
def seed_self
|
455
|
+
memoize(:seed) do
|
456
|
+
options = @seed
|
457
|
+
if(options[:inherit] && options[:layering].to_s == 'merge')
|
458
|
+
raise ArgumentError.new 'Cannot merge and inherit!'
|
459
|
+
end
|
460
|
+
if(options[:inherit])
|
461
|
+
inherit_from(options[:inherit])
|
462
|
+
elsif(options[:layering].to_s == 'merge')
|
463
|
+
merge_previous!
|
464
|
+
end
|
465
|
+
true
|
466
|
+
end
|
467
|
+
self
|
468
|
+
end
|
469
|
+
|
470
|
+
# Merge previous layer template structure
|
471
|
+
#
|
472
|
+
# @return [self]
|
473
|
+
def merge_previous!
|
474
|
+
my_index = sparkle.get(:template, name).spectrum.find_index do |item|
|
475
|
+
item[:path] == template_path
|
476
|
+
end
|
477
|
+
template = self.class.compile(sparkle.get(:template, name).layer_at(my_index - 1)[:path], :sparkle)
|
478
|
+
extract_template_data(template)
|
479
|
+
end
|
480
|
+
|
481
|
+
# Inhert template structure
|
482
|
+
#
|
483
|
+
# @param template_name [String] name of template to inherit
|
484
|
+
# @return [self]
|
485
|
+
def inherit_from(template_name)
|
486
|
+
if(blacklisted_templates.map(&:to_s).include?(template_name.to_s))
|
487
|
+
raise Error::CircularInheritance.new "Circular inheritance detected between templates `#{template_name}` and `#{name}`" # rubocop:disable Metrics/LineLength
|
488
|
+
end
|
489
|
+
template = self.class.compile(sparkle.get(:template, template_name)[:path], :sparkle)
|
490
|
+
template.blacklisted_templates.replace(
|
491
|
+
(template.blacklisted_templates + blacklisted_templates).map(&:to_s).uniq
|
492
|
+
)
|
493
|
+
extract_template_data(template)
|
494
|
+
end
|
495
|
+
|
496
|
+
# Extract information from given template and integrate with current instance
|
497
|
+
#
|
498
|
+
# @param template [SparkleFormation]
|
499
|
+
# @return [self]
|
500
|
+
def extract_template_data(template)
|
501
|
+
if(provider != template.provider)
|
502
|
+
raise TypeError.new "This template `#{name}` cannot inherit template `#{template.name}`! Provider mismatch: `#{provider}` != `#{template.provider}`" # rubocop:disable Metrics/LineLength
|
503
|
+
end
|
504
|
+
sparkle.size.times do |idx|
|
505
|
+
template.sparkle.add_sparkle(sparkle.sparkle_at(idx))
|
506
|
+
end
|
507
|
+
template.seed_self
|
508
|
+
blacklisted_templates.replace(
|
509
|
+
(blacklisted_templates + template.blacklisted_templates).map(&:to_s).uniq
|
510
|
+
)
|
511
|
+
@parameters = template.parameters
|
512
|
+
@overrides = template.raw_overrides + raw_overrides
|
513
|
+
new_components = template.components
|
514
|
+
new_load_order = template.load_order
|
515
|
+
load_order.each do |comp_key|
|
516
|
+
if(components[comp_key])
|
517
|
+
original_key = comp_key
|
518
|
+
comp_key = "#{comp_key}_#{Smash.new(:name => name, :path => template_path).checksum}_child"
|
519
|
+
new_components[comp_key] = components[original_key]
|
520
|
+
end
|
521
|
+
new_load_order << comp_key
|
522
|
+
end
|
523
|
+
@components = new_components
|
524
|
+
@load_order = new_load_order
|
525
|
+
self
|
526
|
+
end
|
527
|
+
|
418
528
|
# @return [String] provider stack resource type
|
419
529
|
def stack_resource_type
|
420
530
|
DEFAULT_STACK_RESOURCE
|
@@ -536,11 +646,13 @@ class SparkleFormation
|
|
536
646
|
args.each do |thing|
|
537
647
|
key = File.basename(thing.to_s).sub('.rb', '')
|
538
648
|
if(thing.is_a?(String))
|
649
|
+
# NOTE: This needs to be deprecated and removed
|
650
|
+
# TODO: deprecate
|
539
651
|
components[key] = self.class.load_component(thing)
|
652
|
+
@load_order << key
|
540
653
|
else
|
541
|
-
|
654
|
+
@load_order << thing
|
542
655
|
end
|
543
|
-
@load_order << key
|
544
656
|
end
|
545
657
|
self
|
546
658
|
end
|
@@ -565,6 +677,9 @@ class SparkleFormation
|
|
565
677
|
unmemoize(:compile)
|
566
678
|
end
|
567
679
|
memoize(:compile) do
|
680
|
+
# NOTE: this is where we inject inherit or layering
|
681
|
+
seed_self
|
682
|
+
|
568
683
|
set_compile_time_parameters!
|
569
684
|
if(provider && SparkleAttribute.const_defined?(camel(provider)))
|
570
685
|
const = SparkleAttribute.const_get(camel(provider))
|
@@ -593,7 +708,13 @@ class SparkleFormation
|
|
593
708
|
compiled.set_state!(compile_state)
|
594
709
|
end
|
595
710
|
@load_order.each do |key|
|
596
|
-
|
711
|
+
if(components[key])
|
712
|
+
self.class.build(compiled, &components[key])
|
713
|
+
else
|
714
|
+
sparkle.get(:component, key).monochrome.each do |component_block|
|
715
|
+
self.class.build(compiled, &component_block[:block])
|
716
|
+
end
|
717
|
+
end
|
597
718
|
end
|
598
719
|
@overrides.each do |override|
|
599
720
|
if(override[:args] && !override[:args].empty?)
|
data/sparkle_formation.gemspec
CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |s|
|
|
10
10
|
s.description = 'Ruby DSL for programmatic orchestration API template generation'
|
11
11
|
s.license = 'Apache-2.0'
|
12
12
|
s.require_path = 'lib'
|
13
|
-
s.required_ruby_version = '>= 2.
|
13
|
+
s.required_ruby_version = '>= 2.1'
|
14
14
|
s.add_runtime_dependency 'attribute_struct', '>= 0.3.0', '< 0.5'
|
15
15
|
s.add_runtime_dependency 'multi_json'
|
16
16
|
s.add_runtime_dependency 'bogo'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sparkle_formation
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Roberts
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-02-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: attribute_struct
|
@@ -158,6 +158,7 @@ files:
|
|
158
158
|
- docs/building-blocks.md
|
159
159
|
- docs/compile-time-parameters.md
|
160
160
|
- docs/helper-methods.md
|
161
|
+
- docs/inheritance-merging.md
|
161
162
|
- docs/nested-stacks.md
|
162
163
|
- docs/overview.md
|
163
164
|
- docs/sparkle-packs.md
|
@@ -195,6 +196,7 @@ files:
|
|
195
196
|
- lib/sparkle_formation/sparkle_attribute/heat.rb
|
196
197
|
- lib/sparkle_formation/sparkle_attribute/rackspace.rb
|
197
198
|
- lib/sparkle_formation/sparkle_collection.rb
|
199
|
+
- lib/sparkle_formation/sparkle_collection/rainbow.rb
|
198
200
|
- lib/sparkle_formation/sparkle_formation.rb
|
199
201
|
- lib/sparkle_formation/sparkle_struct.rb
|
200
202
|
- lib/sparkle_formation/translation.rb
|
@@ -215,7 +217,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
215
217
|
requirements:
|
216
218
|
- - ">="
|
217
219
|
- !ruby/object:Gem::Version
|
218
|
-
version: '2.
|
220
|
+
version: '2.1'
|
219
221
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
220
222
|
requirements:
|
221
223
|
- - ">="
|