sparkle_formation 2.0.2 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
- - ">="
|