cfndsl 0.14.0 → 0.15.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 +15 -2
- data/README.md +12 -5
- data/bin/cfndsl +5 -2
- data/cfndsl.gemspec +1 -1
- data/lib/cfndsl.rb +1 -0
- data/lib/cfndsl/external_parameters.rb +11 -1
- data/lib/cfndsl/globals.rb +8 -0
- data/lib/cfndsl/version.rb +1 -1
- data/lib/deep_merge/core.rb +244 -0
- data/lib/deep_merge/deep_merge.rb +18 -0
- data/spec/cli_spec.rb +1 -0
- data/spec/deep_merge_spec.rb +12 -0
- metadata +10 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c35481efeaa53234104932119ca1f2d30618dce3
|
4
|
+
data.tar.gz: a80db4b44cce2a4e0fc4591fc1df3496b5adda2d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0bddda0ad62f9d9d1c89378c41add30867e0cf9ef37a4fe505f0b00cf76eac09231406c8f28f4e09b0ed7382376577f7209b1979927179b320411f11b52eba5d
|
7
|
+
data.tar.gz: a46c41614907b56f121ea34f8eaa42216df064c349f85076352fd80d770e60d2da1ea4d34793fcd27d0adc1f9b57765be06efb929018eeb408ec7a3441f6c56a
|
data/CHANGELOG.md
CHANGED
@@ -1,7 +1,20 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
-
## [0.
|
4
|
-
[Full Changelog](https://github.com/stevenjack/cfndsl/compare/v0.
|
3
|
+
## [0.15.0](https://github.com/stevenjack/cfndsl/tree/0.15.0) (2017-06-19)
|
4
|
+
[Full Changelog](https://github.com/stevenjack/cfndsl/compare/v0.14.0...0.15.0)
|
5
|
+
|
6
|
+
**Closed issues:**
|
7
|
+
|
8
|
+
- Please add support for multiple input files with deep merge [\#327](https://github.com/stevenjack/cfndsl/issues/327)
|
9
|
+
|
10
|
+
**Merged pull requests:**
|
11
|
+
|
12
|
+
- Clean up of README [\#330](https://github.com/stevenjack/cfndsl/pull/330) ([elmobp](https://github.com/elmobp))
|
13
|
+
- remove 'disable\_binding', merge 0.x changes [\#329](https://github.com/stevenjack/cfndsl/pull/329) ([gergnz](https://github.com/gergnz))
|
14
|
+
- enable deep merge as the default for yaml [\#328](https://github.com/stevenjack/cfndsl/pull/328) ([gergnz](https://github.com/gergnz))
|
15
|
+
|
16
|
+
## [v0.14.0](https://github.com/stevenjack/cfndsl/tree/v0.14.0) (2017-06-15)
|
17
|
+
[Full Changelog](https://github.com/stevenjack/cfndsl/compare/v0.13.1...v0.14.0)
|
5
18
|
|
6
19
|
**Implemented enhancements:**
|
7
20
|
|
data/README.md
CHANGED
@@ -431,14 +431,16 @@ Usage: cfndsl [options] FILE
|
|
431
431
|
-r, --ruby FILE Evaluate ruby file before template
|
432
432
|
-j, --json FILE Import json file as local variables
|
433
433
|
-p, --pretty Pretty-format output JSON
|
434
|
+
-f, --format FORMAT Specify the output format (JSON default)
|
434
435
|
-D, --define "VARIABLE=VALUE" Directly set local VARIABLE as VALUE
|
435
436
|
-v, --verbose Turn on verbose ouptut
|
436
437
|
-b, --disable-binding Disable binding configuration
|
438
|
+
-m, --disable-deep-merge Disable deep merging of yaml
|
439
|
+
-s, --specification-file FILE Location of Cloudformation Resource Specification file
|
440
|
+
-u, --update-specification Update the Cloudformation Resource Specification file
|
437
441
|
-g RESOURCE_TYPE,RESOURCE_LOGICAL_NAME,
|
438
|
-
|
439
|
-
-i, --indent TOKEN Use TOKEN for indent character (default space)
|
442
|
+
--generate Add resource type and logical name
|
440
443
|
-l, --list List supported resources
|
441
|
-
-c, --indent-count [COUNT] Count of characters to use for indenting. (default: 2)
|
442
444
|
-h, --help Display this screen
|
443
445
|
```
|
444
446
|
|
@@ -549,6 +551,9 @@ $ cfndsl sample/t1.rb -y sample/t1.yaml
|
|
549
551
|
|
550
552
|
would generate a template with 5 instances declared.
|
551
553
|
|
554
|
+
Specifying multiple -y options will default deep_merge all the yaml in the order specified.
|
555
|
+
You can disable this with -m.
|
556
|
+
|
552
557
|
Finally, the -r option gives you the opportunity to execute some
|
553
558
|
arbitrary ruby code in the evaluation context before the cloudformation
|
554
559
|
template is evaluated (this is not available if `--disable-binding` is used).
|
@@ -580,11 +585,13 @@ $ bin/rake generate
|
|
580
585
|
```
|
581
586
|
|
582
587
|
### Generating CloudFormation resources from cfndsl
|
583
|
-
By supplying the -g paramater you are now able to generate cloudformation resources for
|
588
|
+
By supplying the -g paramater you are now able to generate cloudformation resources for supported objects, for a list of supported resources run cfndsl -l
|
584
589
|
|
585
590
|
Example
|
591
|
+
```bash
|
592
|
+
cfndsl -g AWS::EC2::EIP,EIP
|
586
593
|
```
|
587
|
-
|
594
|
+
```ruby
|
588
595
|
require 'cfndsl'
|
589
596
|
CloudFormation do
|
590
597
|
Description 'auto generated cloudformation cfndsl template'
|
data/bin/cfndsl
CHANGED
@@ -38,8 +38,7 @@ optparse = OptionParser.new do |opts|
|
|
38
38
|
end
|
39
39
|
|
40
40
|
opts.on('-f', '--format FORMAT', 'Specify the output format (JSON default)') do |format|
|
41
|
-
|
42
|
-
raise "Format #{format} not supported" unless types.include? format
|
41
|
+
raise "Format #{format} not supported" unless %w[json yaml].include?(format)
|
43
42
|
options[:outformat] = format
|
44
43
|
end
|
45
44
|
|
@@ -56,6 +55,10 @@ optparse = OptionParser.new do |opts|
|
|
56
55
|
CfnDsl.disable_binding
|
57
56
|
end
|
58
57
|
|
58
|
+
opts.on('-m', '--disable-deep-merge', 'Disable deep merging of yaml') do
|
59
|
+
CfnDsl.disable_deep_merge
|
60
|
+
end
|
61
|
+
|
59
62
|
opts.on('-s', '--specification-file FILE', 'Location of Cloudformation Resource Specification file') do |file|
|
60
63
|
CfnDsl.specification_file File.expand_path(file)
|
61
64
|
end
|
data/cfndsl.gemspec
CHANGED
@@ -19,7 +19,7 @@ Gem::Specification.new do |s|
|
|
19
19
|
|
20
20
|
s.executables << 'cfndsl'
|
21
21
|
|
22
|
-
s.add_development_dependency 'bundler'
|
22
|
+
s.add_development_dependency 'bundler', '~> 1.13'
|
23
23
|
|
24
24
|
s.post_install_message = "'addTag' is now deprecated in favour of 'add_tag'. 'addTag' will be removed in the next major version."
|
25
25
|
end
|
data/lib/cfndsl.rb
CHANGED
@@ -31,6 +31,10 @@ module CfnDsl
|
|
31
31
|
parameters[k.to_sym] = v
|
32
32
|
end
|
33
33
|
|
34
|
+
def merge_param(x)
|
35
|
+
parameters.deep_merge!(x)
|
36
|
+
end
|
37
|
+
|
34
38
|
def get_param(k)
|
35
39
|
parameters[k.to_sym]
|
36
40
|
end
|
@@ -57,7 +61,13 @@ module CfnDsl
|
|
57
61
|
else
|
58
62
|
raise "Unrecognized extension #{format}"
|
59
63
|
end
|
60
|
-
|
64
|
+
if CfnDsl.disable_deep_merge?
|
65
|
+
params.each { |key, val| set_param(key, val) }
|
66
|
+
else
|
67
|
+
x = {}
|
68
|
+
params.map { |k, v| x[k.to_sym] = v }
|
69
|
+
merge_param(x)
|
70
|
+
end
|
61
71
|
end
|
62
72
|
end
|
63
73
|
end
|
data/lib/cfndsl/globals.rb
CHANGED
@@ -10,6 +10,14 @@ module CfnDsl
|
|
10
10
|
@disable_binding
|
11
11
|
end
|
12
12
|
|
13
|
+
def disable_deep_merge
|
14
|
+
@disable_deep_merge = true
|
15
|
+
end
|
16
|
+
|
17
|
+
def disable_deep_merge?
|
18
|
+
@disable_deep_merge
|
19
|
+
end
|
20
|
+
|
13
21
|
def specification_file(file = nil)
|
14
22
|
@specification_file = file if file
|
15
23
|
@specification_file ||= File.join(ENV['HOME'], '.cfndsl/resource_specification.json')
|
data/lib/cfndsl/version.rb
CHANGED
@@ -0,0 +1,244 @@
|
|
1
|
+
# rubocop:disable Metrics/AbcSize, Metrics/BlockNesting, Metrics/CyclomaticComplexity, Metrics/MethodLength
|
2
|
+
# rubocop:disable Metrics/ModuleLength, Metrics/PerceivedComplexity, Style/IfInsideElse, Style/Semicolon
|
3
|
+
#
|
4
|
+
# Totally borrowed from https://github.com/danielsdeleo/deep_merge
|
5
|
+
module DeepMerge
|
6
|
+
class InvalidParameter < StandardError; end
|
7
|
+
|
8
|
+
DEFAULT_FIELD_KNOCKOUT_PREFIX = '--'.freeze
|
9
|
+
|
10
|
+
# Deep Merge core documentation.
|
11
|
+
# deep_merge! method permits merging of arbitrary child elements. The two top level
|
12
|
+
# elements must be hashes. These hashes can contain unlimited (to stack limit) levels
|
13
|
+
# of child elements. These child elements to not have to be of the same types.
|
14
|
+
# Where child elements are of the same type, deep_merge will attempt to merge them together.
|
15
|
+
# Where child elements are not of the same type, deep_merge will skip or optionally overwrite
|
16
|
+
# the destination element with the contents of the source element at that level.
|
17
|
+
# So if you have two hashes like this:
|
18
|
+
# source = {:x => [1,2,3], :y => 2}
|
19
|
+
# dest = {:x => [4,5,'6'], :y => [7,8,9]}
|
20
|
+
# dest.deep_merge!(source)
|
21
|
+
# Results: {:x => [1,2,3,4,5,'6'], :y => 2}
|
22
|
+
# By default, "deep_merge!" will overwrite any unmergeables and merge everything else.
|
23
|
+
# To avoid this, use "deep_merge" (no bang/exclamation mark)
|
24
|
+
#
|
25
|
+
# Options:
|
26
|
+
# Options are specified in the last parameter passed, which should be in hash format:
|
27
|
+
# hash.deep_merge!({:x => [1,2]}, {:knockout_prefix => '--'})
|
28
|
+
# :preserve_unmergeables DEFAULT: false
|
29
|
+
# Set to true to skip any unmergeable elements from source
|
30
|
+
# :knockout_prefix DEFAULT: nil
|
31
|
+
# Set to string value to signify prefix which deletes elements from existing element
|
32
|
+
# :overwrite_arrays DEFAULT: false
|
33
|
+
# Set to true if you want to avoid merging arrays
|
34
|
+
# :sort_merged_arrays DEFAULT: false
|
35
|
+
# Set to true to sort all arrays that are merged together
|
36
|
+
# :unpack_arrays DEFAULT: nil
|
37
|
+
# Set to string value to run "Array::join" then "String::split" against all arrays
|
38
|
+
# :merge_hash_arrays DEFAULT: false
|
39
|
+
# Set to true to merge hashes within arrays
|
40
|
+
# :keep_array_duplicates DEFAULT: false
|
41
|
+
# Set to true to preserve duplicate array entries
|
42
|
+
# :merge_debug DEFAULT: false
|
43
|
+
# Set to true to get console output of merge process for debugging
|
44
|
+
#
|
45
|
+
# Selected Options Details:
|
46
|
+
# :knockout_prefix => The purpose of this is to provide a way to remove elements
|
47
|
+
# from existing Hash by specifying them in a special way in incoming hash
|
48
|
+
# source = {:x => ['--1', '2']}
|
49
|
+
# dest = {:x => ['1', '3']}
|
50
|
+
# dest.ko_deep_merge!(source)
|
51
|
+
# Results: {:x => ['2','3']}
|
52
|
+
# Additionally, if the knockout_prefix is passed alone as a string, it will cause
|
53
|
+
# the entire element to be removed:
|
54
|
+
# source = {:x => '--'}
|
55
|
+
# dest = {:x => [1,2,3]}
|
56
|
+
# dest.ko_deep_merge!(source)
|
57
|
+
# Results: {:x => ""}
|
58
|
+
# :unpack_arrays => The purpose of this is to permit compound elements to be passed
|
59
|
+
# in as strings and to be converted into discrete array elements
|
60
|
+
# irsource = {:x => ['1,2,3', '4']}
|
61
|
+
# dest = {:x => ['5','6','7,8']}
|
62
|
+
# dest.deep_merge!(source, {:unpack_arrays => ','})
|
63
|
+
# Results: {:x => ['1','2','3','4','5','6','7','8'}
|
64
|
+
# Why: If receiving data from an HTML form, this makes it easy for a checkbox
|
65
|
+
# to pass multiple values from within a single HTML element
|
66
|
+
#
|
67
|
+
# :merge_hash_arrays => merge hashes within arrays
|
68
|
+
# source = {:x => [{:y => 1}]}
|
69
|
+
# dest = {:x => [{:z => 2}]}
|
70
|
+
# dest.deep_merge!(source, {:merge_hash_arrays => true})
|
71
|
+
# Results: {:x => [{:y => 1, :z => 2}]}
|
72
|
+
#
|
73
|
+
# :keep_array_duplicates => merges arrays within hashes but keeps duplicate elements
|
74
|
+
# source = {:x => {:y => [1,2,2,2,3]}}
|
75
|
+
# dest = {:x => {:y => [4,5,6]}}
|
76
|
+
# dest.deep_merge!(source, {:keep_array_duplicates => true})
|
77
|
+
# Results: {:x => {:y => [1,2,2,2,3,4,5,6]}}
|
78
|
+
#
|
79
|
+
# There are many tests for this library - and you can learn more about the features
|
80
|
+
# and usages of deep_merge! by just browsing the test examples
|
81
|
+
def self.deep_merge!(source, dest, options = {})
|
82
|
+
# turn on this line for stdout debugging text
|
83
|
+
merge_debug = options[:merge_debug] || false
|
84
|
+
overwrite_unmergeable = !options[:preserve_unmergeables]
|
85
|
+
knockout_prefix = options[:knockout_prefix] || nil
|
86
|
+
raise InvalidParameter, 'knockout_prefix cannot be an empty string in deep_merge!' if knockout_prefix == ''
|
87
|
+
raise InvalidParameter, 'overwrite_unmergeable must be true if knockout_prefix is specified in deep_merge!' if knockout_prefix && !overwrite_unmergeable
|
88
|
+
# if present: we will split and join arrays on this char before merging
|
89
|
+
array_split_char = options[:unpack_arrays] || false
|
90
|
+
# request that we avoid merging arrays
|
91
|
+
overwrite_arrays = options[:overwrite_arrays] || false
|
92
|
+
# request that we sort together any arrays when they are merged
|
93
|
+
sort_merged_arrays = options[:sort_merged_arrays] || false
|
94
|
+
# request that arrays of hashes are merged together
|
95
|
+
merge_hash_arrays = options[:merge_hash_arrays] || false
|
96
|
+
# request to extend existing arrays, instead of overwriting them
|
97
|
+
extend_existing_arrays = options[:extend_existing_arrays] || false
|
98
|
+
# request that arrays keep duplicate elements
|
99
|
+
keep_array_duplicates = options[:keep_array_duplicates] || false
|
100
|
+
# request that nil values are merged or skipped (Skipped/false by default)
|
101
|
+
merge_nil_values = options[:merge_nil_values] || false
|
102
|
+
|
103
|
+
di = options[:debug_indent] || ''
|
104
|
+
# do nothing if source is nil
|
105
|
+
return dest if !merge_nil_values && source.nil?
|
106
|
+
# if dest doesn't exist, then simply copy source to it
|
107
|
+
if !dest && overwrite_unmergeable
|
108
|
+
dest = source; return dest
|
109
|
+
end
|
110
|
+
|
111
|
+
puts "#{di}Source class: #{source.class.inspect} :: Dest class: #{dest.class.inspect}" if merge_debug
|
112
|
+
if source.is_a?(Hash)
|
113
|
+
puts "#{di}Hashes: #{source.inspect} :: #{dest.inspect}" if merge_debug
|
114
|
+
source.each do |src_key, src_value|
|
115
|
+
if dest.is_a?(Hash)
|
116
|
+
puts "#{di} looping: #{src_key.inspect} => #{src_value.inspect} :: #{dest.inspect}" if merge_debug
|
117
|
+
if dest[src_key]
|
118
|
+
puts "#{di} ==>merging: #{src_key.inspect} => #{src_value.inspect} :: #{dest[src_key].inspect}" if merge_debug
|
119
|
+
dest[src_key] = deep_merge!(src_value, dest[src_key], options.merge(debug_indent: di + ' '))
|
120
|
+
else # dest[src_key] doesn't exist so we want to create and overwrite it (but we do this via deep_merge!)
|
121
|
+
puts "#{di} ==>merging over: #{src_key.inspect} => #{src_value.inspect}" if merge_debug
|
122
|
+
# note: we rescue here b/c some classes respond to "dup" but don't implement it (Numeric, TrueClass, FalseClass, NilClass among maybe others)
|
123
|
+
begin
|
124
|
+
src_dup = src_value.dup # we dup src_value if possible because we're going to merge into it (since dest is empty)
|
125
|
+
rescue TypeError
|
126
|
+
src_dup = src_value
|
127
|
+
end
|
128
|
+
dest[src_key] = deep_merge!(src_value, src_dup, options.merge(debug_indent: di + ' '))
|
129
|
+
end
|
130
|
+
elsif dest.is_a?(Array) && extend_existing_arrays
|
131
|
+
dest.push(source)
|
132
|
+
else # dest isn't a hash, so we overwrite it completely (if permitted)
|
133
|
+
if overwrite_unmergeable
|
134
|
+
puts "#{di} overwriting dest: #{src_key.inspect} => #{src_value.inspect} -over-> #{dest.inspect}" if merge_debug
|
135
|
+
dest = overwrite_unmergeables(source, dest, options)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
elsif source.is_a?(Array)
|
140
|
+
puts "#{di}Arrays: #{source.inspect} :: #{dest.inspect}" if merge_debug
|
141
|
+
if overwrite_arrays
|
142
|
+
puts "#{di} overwrite arrays" if merge_debug
|
143
|
+
dest = source
|
144
|
+
else
|
145
|
+
# if we are instructed, join/split any source arrays before processing
|
146
|
+
if array_split_char
|
147
|
+
puts "#{di} split/join on source: #{source.inspect}" if merge_debug
|
148
|
+
source = source.join(array_split_char).split(array_split_char)
|
149
|
+
if dest.is_a?(Array)
|
150
|
+
dest = dest.join(array_split_char).split(array_split_char)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
# if there's a naked knockout_prefix in source, that means we are to truncate dest
|
154
|
+
if knockout_prefix && source.index(knockout_prefix)
|
155
|
+
dest = clear_or_nil(dest); source.delete(knockout_prefix)
|
156
|
+
end
|
157
|
+
if dest.is_a?(Array)
|
158
|
+
if knockout_prefix
|
159
|
+
print "#{di} knocking out: " if merge_debug
|
160
|
+
# remove knockout prefix items from both source and dest
|
161
|
+
source.delete_if do |ko_item|
|
162
|
+
retval = false
|
163
|
+
item = ko_item.respond_to?(:gsub) ? ko_item.gsub(/^#{knockout_prefix}/, '') : ko_item
|
164
|
+
if item != ko_item
|
165
|
+
print "#{ko_item} - " if merge_debug
|
166
|
+
dest.delete(item)
|
167
|
+
dest.delete(ko_item)
|
168
|
+
retval = true
|
169
|
+
end
|
170
|
+
retval
|
171
|
+
end
|
172
|
+
puts if merge_debug
|
173
|
+
end
|
174
|
+
puts "#{di} merging arrays: #{source.inspect} :: #{dest.inspect}" if merge_debug
|
175
|
+
source_all_hashes = source.all? { |i| i.is_a?(Hash) }
|
176
|
+
dest_all_hashes = dest.all? { |i| i.is_a?(Hash) }
|
177
|
+
if merge_hash_arrays && source_all_hashes && dest_all_hashes
|
178
|
+
# merge hashes in lists
|
179
|
+
list = []
|
180
|
+
dest.each_index do |i|
|
181
|
+
list[i] = deep_merge!(source[i] || {}, dest[i],
|
182
|
+
options.merge(debug_indent: di + ' '))
|
183
|
+
end
|
184
|
+
list += source[dest.count..-1] if source.count > dest.count
|
185
|
+
dest = list
|
186
|
+
elsif keep_array_duplicates
|
187
|
+
dest = dest.concat(source)
|
188
|
+
else
|
189
|
+
dest |= source
|
190
|
+
end
|
191
|
+
dest.sort! if sort_merged_arrays
|
192
|
+
elsif overwrite_unmergeable
|
193
|
+
puts "#{di} overwriting dest: #{source.inspect} -over-> #{dest.inspect}" if merge_debug
|
194
|
+
dest = overwrite_unmergeables(source, dest, options)
|
195
|
+
end
|
196
|
+
end
|
197
|
+
else # src_hash is not an array or hash, so we'll have to overwrite dest
|
198
|
+
if dest.is_a?(Array) && extend_existing_arrays
|
199
|
+
dest.push(source)
|
200
|
+
else
|
201
|
+
puts "#{di}Others: #{source.inspect} :: #{dest.inspect}" if merge_debug
|
202
|
+
dest = overwrite_unmergeables(source, dest, options)
|
203
|
+
end
|
204
|
+
end
|
205
|
+
puts "#{di}Returning #{dest.inspect}" if merge_debug
|
206
|
+
dest
|
207
|
+
end # deep_merge!
|
208
|
+
|
209
|
+
# allows deep_merge! to uniformly handle overwriting of unmergeable entities
|
210
|
+
def self.overwrite_unmergeables(source, dest, options)
|
211
|
+
merge_debug = options[:merge_debug] || false
|
212
|
+
overwrite_unmergeable = !options[:preserve_unmergeables]
|
213
|
+
knockout_prefix = options[:knockout_prefix] || false
|
214
|
+
di = options[:debug_indent] || ''
|
215
|
+
if knockout_prefix && overwrite_unmergeable
|
216
|
+
src_tmp = if source.is_a?(String) # remove knockout string from source before overwriting dest
|
217
|
+
source.gsub(/^#{knockout_prefix}/, '')
|
218
|
+
elsif source.is_a?(Array) # remove all knockout elements before overwriting dest
|
219
|
+
source.delete_if { |ko_item| ko_item.is_a?(String) && ko_item.match(/^#{knockout_prefix}/) }
|
220
|
+
else
|
221
|
+
source
|
222
|
+
end
|
223
|
+
if src_tmp == source # if we didn't find a knockout_prefix then we just overwrite dest
|
224
|
+
puts "#{di}#{src_tmp.inspect} -over-> #{dest.inspect}" if merge_debug
|
225
|
+
dest = src_tmp
|
226
|
+
else # if we do find a knockout_prefix, then we just delete dest
|
227
|
+
puts "#{di}\"\" -over-> #{dest.inspect}" if merge_debug
|
228
|
+
dest = ''
|
229
|
+
end
|
230
|
+
elsif overwrite_unmergeable
|
231
|
+
dest = source
|
232
|
+
end
|
233
|
+
dest
|
234
|
+
end
|
235
|
+
|
236
|
+
def self.clear_or_nil(obj)
|
237
|
+
if obj.respond_to?(:clear)
|
238
|
+
obj.clear
|
239
|
+
else
|
240
|
+
obj = nil
|
241
|
+
end
|
242
|
+
obj
|
243
|
+
end
|
244
|
+
end # module DeepMerge
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# Totally borrowed from https://github.com/danielsdeleo/deep_merge
|
2
|
+
require 'deep_merge/core'
|
3
|
+
|
4
|
+
module DeepMerge
|
5
|
+
# Implements a deep merge with default options
|
6
|
+
module DeepMergeHash
|
7
|
+
# deep_merge! will merge and overwrite any unmergeables in destination hash
|
8
|
+
def deep_merge!(source, options = {})
|
9
|
+
default_opts = { preserve_unmergeables: false }
|
10
|
+
DeepMerge.deep_merge!(source, self, default_opts.merge(options))
|
11
|
+
end
|
12
|
+
end # DeepMergeHashExt
|
13
|
+
end
|
14
|
+
|
15
|
+
# Extends hash with deep merge
|
16
|
+
class Hash
|
17
|
+
include DeepMerge::DeepMergeHash
|
18
|
+
end
|
data/spec/cli_spec.rb
CHANGED
@@ -13,6 +13,7 @@ describe 'cfndsl', type: :aruba do
|
|
13
13
|
-D, --define "VARIABLE=VALUE" Directly set local VARIABLE as VALUE
|
14
14
|
-v, --verbose Turn on verbose ouptut
|
15
15
|
-b, --disable-binding Disable binding configuration
|
16
|
+
-m, --disable-deep-merge Disable deep merging of yaml
|
16
17
|
-s, --specification-file FILE Location of Cloudformation Resource Specification file
|
17
18
|
-u, --update-specification Update the Cloudformation Resource Specification file
|
18
19
|
-g RESOURCE_TYPE,RESOURCE_LOGICAL_NAME,
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
describe DeepMerge do
|
3
|
+
source = { key1: { keya1: 1, keya2: 2 }, key2: [1, 2] }
|
4
|
+
let(:merged_hash) { source.deep_merge!(key1: { keya1: '1a', keya3: 3 }, key2: [2, 3]) }
|
5
|
+
|
6
|
+
context 'deep_merge' do
|
7
|
+
it 'merges correctly' do
|
8
|
+
test_hash = { key1: { keya1: '1a', keya2: 2, keya3: 3 }, key2: [1, 2, 3] }
|
9
|
+
expect(merged_hash).to eq test_hash
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cfndsl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.15.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Steven Jack
|
@@ -9,22 +9,22 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2017-06-
|
12
|
+
date: 2017-06-18 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
requirements:
|
18
|
-
- - "
|
18
|
+
- - "~>"
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version: '
|
20
|
+
version: '1.13'
|
21
21
|
type: :development
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
|
-
- - "
|
25
|
+
- - "~>"
|
26
26
|
- !ruby/object:Gem::Version
|
27
|
-
version: '
|
27
|
+
version: '1.13'
|
28
28
|
description: DSL for creating AWS Cloudformation templates
|
29
29
|
email:
|
30
30
|
- stevenmajack@gmail.com
|
@@ -79,6 +79,8 @@ files:
|
|
79
79
|
- lib/cfnlego/cloudformation.erb
|
80
80
|
- lib/cfnlego/cloudformation.rb
|
81
81
|
- lib/cfnlego/resource.rb
|
82
|
+
- lib/deep_merge/core.rb
|
83
|
+
- lib/deep_merge/deep_merge.rb
|
82
84
|
- sample/autoscale.rb
|
83
85
|
- sample/autoscale.template
|
84
86
|
- sample/autoscale2.rb
|
@@ -105,6 +107,7 @@ files:
|
|
105
107
|
- spec/cfndsl_spec.rb
|
106
108
|
- spec/cli_spec.rb
|
107
109
|
- spec/cloud_formation_template_spec.rb
|
110
|
+
- spec/deep_merge_spec.rb
|
108
111
|
- spec/external_parameters_spec.rb
|
109
112
|
- spec/fixtures/heattest.rb
|
110
113
|
- spec/fixtures/serverless-api.json
|
@@ -158,6 +161,7 @@ test_files:
|
|
158
161
|
- spec/cfndsl_spec.rb
|
159
162
|
- spec/cli_spec.rb
|
160
163
|
- spec/cloud_formation_template_spec.rb
|
164
|
+
- spec/deep_merge_spec.rb
|
161
165
|
- spec/external_parameters_spec.rb
|
162
166
|
- spec/fixtures/heattest.rb
|
163
167
|
- spec/fixtures/serverless-api.json
|