aws-cfn-compiler 0.6.0 → 0.7.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 +8 -8
- data/Gemfile +1 -1
- data/aws-cfn-compiler.gemspec +5 -7
- data/aws-cfn-compiler.iml +1 -0
- data/lib/aws/cfn/compiler/base.rb +26 -286
- data/lib/aws/cfn/compiler/main.rb +6 -51
- data/lib/aws/cfn/compiler/mixins/compile.rb +154 -0
- data/lib/aws/cfn/compiler/mixins/load.rb +81 -0
- data/lib/aws/cfn/compiler/mixins/options.rb +40 -0
- data/lib/aws/cfn/compiler/mixins/parse.rb +119 -0
- data/lib/aws/cfn/compiler/mixins/save.rb +54 -0
- data/lib/aws/cfn/compiler/version.rb +1 -1
- metadata +11 -34
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
NTljZDM3YzBkMWZhYzVhM2RhMDBkMjA4MjQ3MTljZjdlNjczZDUyYg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
YWIzN2E1YTE3YTk3OWVlNDVlYTYyZGQzNWZiYjc5N2QzNDY1NjU5YQ==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
Y2RhZTI5ODI1Y2MzODU2OTQzYjI3ODFlOGEzMDU4MjM2ZTJiMDU5MWIyODg3
|
10
|
+
YWJmOGQwYTFlNDNiMWQ5Y2FjMmJhN2JiMzBlMTg1YTE3ZGQ5NDk3N2FiZTU5
|
11
|
+
YTYyMjU0ZjU2YWY5MWUxYTMxOThmYzc5NjU3MDlhNjI0ZTQ2MjQ=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
NDdkYjUyOTA4Y2U1MDM0YjZlZmM5YmZhN2E2NzIyMWZiZjQ1ODQwNWRmOGM2
|
14
|
+
MTZjMzExOWVhNWE0MjM5YjQyZTc3ZGFmZDk1OTY5MTFmN2RlYmVmZjljMThj
|
15
|
+
M2Q4YzIyNzJkNGFlZDFiMDFmYWRkOTdlZjYwNzcxNDhiN2ZhOWI=
|
data/Gemfile
CHANGED
@@ -9,9 +9,9 @@ gem 'dldinternet-mixlib-logging', :path => '../dldinternet-mixlib-logging', :gro
|
|
9
9
|
gem 'dldinternet-mixlib-cli', :path => '../dldinternet-mixlib-cli', :group => :development
|
10
10
|
gem 'aws-cfn-dsl', :path => '../aws-cfn-dsl', :group => :development
|
11
11
|
gem 'aws-cfn-decompiler', :path => '../aws-cfn-decompiler', :group => :development
|
12
|
-
gem 'aws-cfn-compiler', :path => '../aws-cfn-compiler', :group => :development
|
13
12
|
gem 'aws-cfn-yats', :path => '../aws-cfn-yats', :group => :development
|
14
13
|
gem 'aws-cfn-stacker', :path => '../aws-cfn-stacker', :group => :development
|
15
14
|
|
15
|
+
gem 'json_pure', :group => :development
|
16
16
|
gem 'bundler', "~> 1.6", :group => :development
|
17
17
|
gem 'rake', :group => :development
|
data/aws-cfn-compiler.gemspec
CHANGED
@@ -18,13 +18,11 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.add_dependency
|
22
|
-
spec.add_dependency
|
23
|
-
spec.add_dependency
|
24
|
-
spec.add_dependency
|
25
|
-
spec.add_dependency '
|
26
|
-
spec.add_dependency 'inifile'
|
27
|
-
spec.add_dependency 'aws-cfn-dsl', '>= 0.2.0', '~> 0.2'
|
21
|
+
spec.add_dependency 'awesome_print', '~> 1.2', '>= 1.2.0'
|
22
|
+
spec.add_dependency 'psych'
|
23
|
+
spec.add_dependency 'json'
|
24
|
+
spec.add_dependency 'slop'
|
25
|
+
spec.add_dependency 'aws-cfn-dsl', '>= 0.7.0', '~> 0.7'
|
28
26
|
spec.add_dependency 'dldinternet-mixlib-cli', ">= 0.1.0", '~> 0.1'
|
29
27
|
spec.add_dependency 'dldinternet-mixlib-logging', '>= 0.1.6', '~> 0.1'
|
30
28
|
|
data/aws-cfn-compiler.iml
CHANGED
@@ -52,6 +52,7 @@
|
|
52
52
|
<orderEntry type="library" scope="PROVIDED" name="detabulator (v0.1.0, RVM: ruby-1.9.3-p547 [aws-cfn-compile]) [gem]" level="application" />
|
53
53
|
<orderEntry type="library" scope="PROVIDED" name="inifile (v2.0.2, RVM: ruby-1.9.3-p547 [aws-cfn-compile]) [gem]" level="application" />
|
54
54
|
<orderEntry type="library" scope="PROVIDED" name="json (v1.8.1, RVM: ruby-1.9.3-p547 [aws-cfn-compile]) [gem]" level="application" />
|
55
|
+
<orderEntry type="library" scope="PROVIDED" name="json_pure (v1.8.1, RVM: ruby-1.9.3-p547 [aws-cfn-compile]) [gem]" level="application" />
|
55
56
|
<orderEntry type="library" scope="PROVIDED" name="little-plugger (v1.1.3, RVM: ruby-1.9.3-p547 [aws-cfn-compile]) [gem]" level="application" />
|
56
57
|
<orderEntry type="library" scope="PROVIDED" name="logging (v1.8.2, RVM: ruby-1.9.3-p547 [aws-cfn-compile]) [gem]" level="application" />
|
57
58
|
<orderEntry type="library" scope="PROVIDED" name="mixlib-cli (v1.5.0, RVM: ruby-1.9.3-p547 [aws-cfn-compile]) [gem]" level="application" />
|
@@ -21,7 +21,7 @@ module Aws
|
|
21
21
|
|
22
22
|
def validate(compiled)
|
23
23
|
abort! 'No Resources!?' unless compiled['Resources']
|
24
|
-
logStep 'Validating
|
24
|
+
logStep 'Validating template'
|
25
25
|
|
26
26
|
# Mappings => Resources
|
27
27
|
maps = find_maps(compiled) #.select { |a| !(a =~ /^AWS::/) }
|
@@ -55,8 +55,12 @@ module Aws
|
|
55
55
|
end
|
56
56
|
|
57
57
|
def save_template(output_file,compiled)
|
58
|
-
|
59
|
-
|
58
|
+
file = output_file
|
59
|
+
file = File.expand_path(output_file) if @config[:expandedpaths]
|
60
|
+
if File.exists?(file)
|
61
|
+
file = File.realpath(file)
|
62
|
+
end
|
63
|
+
logStep "Writing compiled file to #{file}..."
|
60
64
|
begin
|
61
65
|
hash = {}
|
62
66
|
compiled.each do |item,value|
|
@@ -67,13 +71,15 @@ module Aws
|
|
67
71
|
end
|
68
72
|
end
|
69
73
|
|
70
|
-
File.
|
71
|
-
|
72
|
-
|
74
|
+
dir = File.dirname(output_file)
|
75
|
+
file = File.basename(output_file)
|
76
|
+
sect = dir == '.' ? Dir.pwd : dir
|
77
|
+
sect = File.basename(sect) unless @config[:expandedpaths]
|
78
|
+
save_section(dir, file, @config[:format], sect, hash, '', 'template')
|
79
|
+
|
73
80
|
@logger.info ' Compiled file written.'
|
74
81
|
rescue
|
75
|
-
|
76
|
-
abort!
|
82
|
+
abort! "!!! Could not write compiled file: #{$!}"
|
77
83
|
end
|
78
84
|
end
|
79
85
|
|
@@ -107,295 +113,29 @@ module Aws
|
|
107
113
|
abort! "Unsupported file type for specification: #{spec}"
|
108
114
|
end
|
109
115
|
else
|
110
|
-
abort!
|
111
|
-
end
|
112
|
-
@dsl ||= Aws::Cfn::Dsl::Template.new(@config[:directory])
|
113
|
-
%w( Mappings Parameters Resources Outputs ).each do |dir|
|
114
|
-
load_dir(dir,@spec)
|
116
|
+
abort! 'Unable to open specification'+ (abs.nil? ? " or {,#{@config[:directory]}/}#{spec} not found" : ": #{abs}")
|
115
117
|
end
|
116
118
|
else
|
117
|
-
|
119
|
+
abort! 'No specification provided'
|
118
120
|
end
|
119
121
|
end
|
120
122
|
|
121
123
|
protected
|
122
124
|
|
123
|
-
|
124
|
-
|
125
|
-
logStep "Loading #{dir}..."
|
126
|
-
|
127
|
-
if spec and spec[dir]
|
128
|
-
raise "No such directory: #{@config[:directory]}" unless File.directory?(@config[:directory])
|
129
|
-
path = vet_path(dir)
|
130
|
-
@items ||= {}
|
131
|
-
@items[dir] ||= {}
|
132
|
-
set = {}
|
133
|
-
get = {}
|
134
|
-
get[path] = get_file_set([".*"], path, @config[:precedence])
|
135
|
-
|
136
|
-
item = {}
|
137
|
-
spec[dir].each do |rsrc|
|
138
|
-
@logger.info "\tUsing #{dir}::#{rsrc}"
|
139
|
-
set = get[path]
|
140
|
-
refp,sub,base,rel = map_resource_reference(rsrc)
|
141
|
-
unless refp.nil?
|
142
|
-
path = vet_path(sub ? sub : dir,refp, rel)
|
143
|
-
unless get[path]
|
144
|
-
get[path] = get_file_set([".*"], path, @config[:precedence])
|
145
|
-
set = get[path]
|
146
|
-
end
|
147
|
-
end
|
148
|
-
if set[base]
|
149
|
-
if item.has_key?(base)
|
150
|
-
@logger.error " !! error: Duplicate item: #{dir}/#{base}"
|
151
|
-
abort!
|
152
|
-
end
|
153
|
-
|
154
|
-
filename = set[base]
|
155
|
-
unless filename =~ /\.(ru?by?|ya?ml|js(|on))\z/i
|
156
|
-
@logger.info "Brick not supported/ relevant: #{filename}"
|
157
|
-
next
|
158
|
-
end
|
159
|
-
|
160
|
-
begin
|
161
|
-
@logger.debug " reading #{filename}"
|
162
|
-
content = File.read(filename)
|
163
|
-
next if content.size==0
|
164
|
-
|
165
|
-
if filename =~ /\.(rb|ruby)\z/i
|
166
|
-
compile_rb_file(base, dir, filename)
|
167
|
-
item.merge! @dsl.dict[dir.to_sym]
|
168
|
-
elsif filename =~ /\.js(|on)\z/i
|
169
|
-
item.merge! JSON.parse(content)
|
170
|
-
elsif filename =~ /\.ya?ml\z/i
|
171
|
-
item.merge! YAML.load(content)
|
172
|
-
else
|
173
|
-
next
|
174
|
-
end
|
175
|
-
|
176
|
-
rescue
|
177
|
-
@logger.error " !! error: #{$!}"
|
178
|
-
abort!
|
179
|
-
end
|
180
|
-
else
|
181
|
-
@logger.error " !! error: #{dir}/#{base} not found!"
|
182
|
-
abort!
|
183
|
-
end
|
184
|
-
end
|
185
|
-
item.keys.each { |key|
|
186
|
-
if @items[dir].has_key?(key)
|
187
|
-
@logger.error " !! error: Duplicate item: #{dir}/#{key}"
|
188
|
-
abort!
|
189
|
-
end
|
190
|
-
}
|
191
|
-
@items[dir].merge! item
|
192
|
-
|
193
|
-
unless @items[dir].keys.count == spec[dir].count
|
194
|
-
@logger.error " !! error: Suspect that a #{dir} item was missed! \nRequested: #{spec[dir]}\n Found: #{@items[dir].keys}"
|
195
|
-
abort!
|
196
|
-
end
|
197
|
-
end
|
198
|
-
|
199
|
-
end
|
200
|
-
|
201
|
-
def compile_rb_file(base, dir, filename)
|
202
|
-
Aws::Cfn::Compiler.binding ||= {}
|
203
|
-
Aws::Cfn::Compiler.binding[dir] ||= {}
|
204
|
-
Aws::Cfn::Compiler.binding[dir][base] ||= {
|
205
|
-
brick_path: @config[:directory],
|
206
|
-
template: @dsl,
|
207
|
-
logger: @logger
|
208
|
-
}
|
209
|
-
source_file = File.expand_path(filename)
|
210
|
-
# source = IO.read(source_file)
|
211
|
-
eval "require source_file", binding
|
212
|
-
unless @dsl.dict[dir.to_sym]
|
213
|
-
abort! "Unable to compile/expand #{filename} for #{dir}/#{base}"
|
214
|
-
end
|
215
|
-
end
|
216
|
-
|
217
|
-
def find_refs(hash, type='Reference', parent='')
|
218
|
-
h = {}
|
219
|
-
newparent = parent
|
220
|
-
if hash.is_a? Hash
|
221
|
-
hash.keys.collect do |key|
|
222
|
-
if %w{Mappings Parameters Resources Outputs}.include? key
|
223
|
-
type = key#.gsub(/s$/, '')
|
224
|
-
newparent = key
|
225
|
-
elsif %w{Mappings Parameters Resources Outputs}.include? parent
|
226
|
-
newparent = key
|
227
|
-
end
|
228
|
-
if %w{Ref}.include? key
|
229
|
-
h = { hash[key] => [type,newparent] }
|
230
|
-
elsif 'Fn::GetAtt' == key
|
231
|
-
h = { hash[key].first => [type,newparent] }
|
232
|
-
# elsif %w{SourceSecurityGroupName CacheSecurityGroupNames SecurityGroupNames}.include? key
|
233
|
-
# a = find_refs(hash[key],type,newparent)
|
234
|
-
# h = merge(h, a, *[type,newparent])
|
235
|
-
else
|
236
|
-
a = find_refs(hash[key],type,newparent)
|
237
|
-
h = merge(h, a, *[type,newparent])
|
238
|
-
end
|
239
|
-
end.flatten.compact.uniq
|
240
|
-
elsif hash.is_a? Array
|
241
|
-
a = hash.map{|i| find_refs(i,type,newparent) }
|
242
|
-
h = merge(h, a, type, *[type,newparent])
|
243
|
-
end
|
244
|
-
h
|
245
|
-
end
|
246
|
-
|
247
|
-
def merge(h, a, *type)
|
248
|
-
if a.is_a? Hash
|
249
|
-
if a.size > 0
|
250
|
-
h.merge! a
|
251
|
-
end
|
252
|
-
else
|
253
|
-
a.flatten.compact.uniq.map { |i|
|
254
|
-
if i.is_a? Hash
|
255
|
-
if i.size > 0
|
256
|
-
h.merge! i
|
257
|
-
h
|
258
|
-
end
|
259
|
-
else
|
260
|
-
h[i] = type
|
261
|
-
end
|
262
|
-
}
|
263
|
-
end
|
264
|
-
h
|
265
|
-
end
|
125
|
+
require 'aws/cfn/compiler/mixins/options'
|
126
|
+
include Aws::Cfn::Compiler::Options
|
266
127
|
|
267
|
-
|
268
|
-
|
269
|
-
tr = []
|
270
|
-
hash.keys.collect do |key|
|
271
|
-
if 'Fn::FindInMap' == key
|
272
|
-
hash[key].first
|
273
|
-
else
|
274
|
-
find_maps(hash[key])
|
275
|
-
end
|
276
|
-
end.flatten.compact.uniq
|
277
|
-
elsif hash.is_a? Array
|
278
|
-
hash.collect{|a| find_maps(a)}.flatten.compact.uniq
|
279
|
-
end
|
280
|
-
end
|
128
|
+
require 'aws/cfn/compiler/mixins/load'
|
129
|
+
include Aws::Cfn::Compiler::Load
|
281
130
|
|
282
|
-
|
283
|
-
|
284
|
-
raise "Bad call to #{self.class.name}.get_file_set: want == nil" unless want
|
285
|
-
@logger.debug "Look for #{want.ai} in #{[path]} with #{exts} extensions"
|
286
|
-
if exts.nil?
|
287
|
-
exts = @config[:precedence]
|
288
|
-
end
|
289
|
-
file_regex=%r/^(\S+)\.(#{exts.join('|')})$/
|
290
|
-
if exts.empty?
|
291
|
-
file_regex=%r/^(\S+)()$/
|
292
|
-
exts=['']
|
293
|
-
end
|
294
|
-
regex = "^(#{want.join('|')})$"
|
295
|
-
set = {}
|
296
|
-
abs = File.expand_path(path)
|
297
|
-
abs = path unless @config[:expandedpaths]
|
298
|
-
raise "Oops! Does '#{path}' directory exist?" unless File.directory?(abs)
|
299
|
-
#abs = File.realpath(abs)
|
300
|
-
begin
|
301
|
-
Dir.glob("#{abs}/*").each{ |f|
|
302
|
-
match = File.basename(f).match(file_regex)
|
303
|
-
if match
|
304
|
-
name = match[1]
|
305
|
-
ext = match[2]
|
306
|
-
set[ext] = {} unless set[ext]
|
307
|
-
@logger.trace "#{name} =~ #{regex}"
|
308
|
-
set[ext][name] = f if name.match(regex)
|
309
|
-
end
|
310
|
-
}
|
311
|
-
rescue RegexpError => e
|
312
|
-
raise "The regular expression attempting to match resources in '#{path}' is incorrect! #{e.message}"
|
313
|
-
end
|
314
|
-
@logger.debug "getPathSet set=#{set.ai}"
|
315
|
-
res = {}
|
316
|
-
# Iterate extension sets in increasing precedence order ...
|
317
|
-
# Survivor will be the most desireable version of the item
|
318
|
-
# i.e. the .rb environment, role, data bag, etc. will be preferred over the .json version
|
319
|
-
exts.each{ |e|
|
320
|
-
h = set[e]
|
321
|
-
if h
|
322
|
-
h.each{ |n,f|
|
323
|
-
@logger.info "Ignoring #{File.basename(res[n])}" if res[n]
|
324
|
-
res[n] = f
|
325
|
-
}
|
326
|
-
else
|
327
|
-
@logger.debug "'#{e}' set is empty! (No #{path}/*.#{e} files found using precedence #{exts})"
|
328
|
-
end
|
329
|
-
}
|
330
|
-
res
|
331
|
-
end
|
131
|
+
require 'aws/cfn/compiler/mixins/parse'
|
132
|
+
include Aws::Cfn::Compiler::Parse
|
332
133
|
|
333
|
-
|
334
|
-
|
335
|
-
sub = nil
|
336
|
-
ref = nil
|
337
|
-
rel = false
|
338
|
-
# noinspection RubyParenthesesAroundConditionInspection
|
339
|
-
if rsrc.match %r'^(\.\./.*?)::(.*)$'
|
340
|
-
# Relative path stack reference
|
341
|
-
path,sub,ref,rel = map_resource_reference(File.basename(rsrc))
|
342
|
-
elsif rsrc.match %r'^(~/.*?)$'
|
343
|
-
# Relative to HOME
|
344
|
-
path,sub,ref,rel = map_resource_reference(File.expand_path(rsrc))
|
345
|
-
elsif rsrc.match %r'^(\.\./[^:]*?)$'
|
346
|
-
# Relative path
|
347
|
-
path = File.dirname(rsrc)
|
348
|
-
sub = File.basename(path)
|
349
|
-
path = File.dirname(path)
|
350
|
-
ref = File.basename(rsrc)
|
351
|
-
rel = true
|
352
|
-
elsif rsrc.match %r'(^/.*?)::(.*)$'
|
353
|
-
# Absolute path
|
354
|
-
_,sub,ref,rel = map_resource_reference(File.basename(rsrc))
|
355
|
-
path = File.realpath(File.join(File.dirname(rsrc),_))
|
356
|
-
elsif rsrc.match %r'(^/.*?[^:]*?)$'
|
357
|
-
# Absolute path
|
358
|
-
path = File.dirname(rsrc)
|
359
|
-
sub = File.basename(path)
|
360
|
-
path = File.dirname(path)
|
361
|
-
ref = File.basename(rsrc)
|
362
|
-
elsif (match = rsrc.match %r'^(.*?)::(.*)$')
|
363
|
-
# Inherited stack reference
|
364
|
-
ref = match[2]
|
365
|
-
# noinspection RubyParenthesesAroundConditionInspection
|
366
|
-
if (subm = match[1].match(%r'^(.+?)/(.+)$'))
|
367
|
-
path = File.join(File.dirname(@config[:directory]),subm[1])
|
368
|
-
sub = subm[2]
|
369
|
-
else
|
370
|
-
# sub = nil
|
371
|
-
path = File.join(File.dirname(@config[:directory]),match[1])
|
372
|
-
end
|
373
|
-
else
|
374
|
-
# Otherwise it is what it seems ;)
|
375
|
-
ref = rsrc
|
376
|
-
end
|
377
|
-
[path,sub,ref,rel]
|
378
|
-
end
|
134
|
+
require 'aws/cfn/compiler/mixins/compile'
|
135
|
+
include Aws::Cfn::Compiler::Compile
|
379
136
|
|
380
|
-
|
381
|
-
|
382
|
-
base = File.realpath(File.expand_path(File.join(@config[:directory], base)))
|
383
|
-
else
|
384
|
-
base = @config[:directory] unless base
|
385
|
-
end
|
386
|
-
path = nil
|
387
|
-
[dir, dir.downcase].each do |d|
|
388
|
-
path = File.join(base, dir)
|
389
|
-
if File.directory?(path)
|
390
|
-
break
|
391
|
-
end
|
392
|
-
end
|
393
|
-
unless File.directory?(path)
|
394
|
-
@logger.error " !! error: Cannot load bricks from #{path} (started with #{File.join(base, dir)}')"
|
395
|
-
abort!
|
396
|
-
end
|
397
|
-
path
|
398
|
-
end
|
137
|
+
require 'aws/cfn/compiler/mixins/save'
|
138
|
+
include Aws::Cfn::Compiler::Save
|
399
139
|
|
400
140
|
end
|
401
141
|
end
|
@@ -1,8 +1,4 @@
|
|
1
1
|
|
2
|
-
require 'json'
|
3
|
-
require 'ap'
|
4
|
-
require 'yaml'
|
5
|
-
require 'slop'
|
6
2
|
|
7
3
|
module Aws
|
8
4
|
module Cfn
|
@@ -11,60 +7,19 @@ module Aws
|
|
11
7
|
|
12
8
|
def run
|
13
9
|
|
14
|
-
|
15
|
-
# command File.basename(__FILE__,'.rb')
|
16
|
-
on :d, :directory=, 'The directory containing template sections', as: String
|
17
|
-
on :o, :output=, 'The JSON file to output', as: String
|
18
|
-
on :s, :specification=, 'The specification to use when selecting components. A JSON or YAML file or JSON object', as: String
|
19
|
-
on :f, :formatversion=, 'The AWS Template format version. ', { as: String,
|
20
|
-
optional_argument: true,
|
21
|
-
default: '2010-09-09' }
|
22
|
-
on :p, :precedence=, 'The precedence of template component types. Default: rb,ruby,yaml,yml,json,js', { as: String,
|
23
|
-
default: 'rb,ruby,yaml,yml,json,js' }
|
24
|
-
on :t, :description=, "The AWS Template description. Default: output basename or #{File.basename(__FILE__,'.rb')}", { as: String,
|
25
|
-
default: File.basename(__FILE__,'.rb') }
|
26
|
-
on :x, :expandedpaths, 'Show expanded paths in output', { as: String,
|
27
|
-
optional_argument: true,
|
28
|
-
default: 'off',
|
29
|
-
match: %r/0|1|yes|no|on|off|enable|disable|set|unset|true|false|raw/i }
|
30
|
-
on :O, :overwrite, 'Overwrite existing generated source files. (HINT: Think twice ...)', { as: String,
|
31
|
-
optional_argument: true,
|
32
|
-
default: 'off',
|
33
|
-
match: %r/0|1|yes|no|on|off|enable|disable|set|unset|true|false|raw/i }
|
34
|
-
end
|
10
|
+
parse_options
|
35
11
|
|
36
|
-
|
37
|
-
puts @opts
|
38
|
-
exit
|
39
|
-
end
|
12
|
+
set_config_options
|
40
13
|
|
41
|
-
@config[:
|
42
|
-
@config[:expandedpaths] = @opts[:expandedpaths].downcase.match %r'^(1|true|on|yes|enable|set)$'
|
43
|
-
@config[:directory] = @opts[:directory]
|
14
|
+
load_spec @config[:specification]
|
44
15
|
|
45
|
-
|
16
|
+
parse
|
46
17
|
|
47
|
-
|
48
|
-
if @spec and @spec['Description']
|
49
|
-
desc = @spec['Description']
|
50
|
-
end
|
51
|
-
vers = '2010-09-09'
|
52
|
-
if @spec and @spec['AWSTemplateFormatVersion']
|
53
|
-
vers = @spec['AWSTemplateFormatVersion']
|
54
|
-
end
|
55
|
-
# noinspection RubyStringKeysInHashInspection
|
56
|
-
compiled = {
|
57
|
-
'AWSTemplateFormatVersion' => (@opts[:formatversion].nil? ? vers : @opts[:formatversion]),
|
58
|
-
'Description' => (@opts[:description].nil? ? desc : @opts[:description]),
|
59
|
-
'Mappings' => @items['Mappings'],
|
60
|
-
'Parameters' => @items['Parameters'],
|
61
|
-
'Resources' => @items['Resources'],
|
62
|
-
'Outputs' => @items['Outputs'],
|
63
|
-
}
|
18
|
+
compiled = compile
|
64
19
|
|
65
20
|
validate(compiled)
|
66
21
|
|
67
|
-
output_file = @
|
22
|
+
output_file = @config[:template] || 'compiled.json'
|
68
23
|
save_template(output_file,compiled)
|
69
24
|
|
70
25
|
@logger.step '*** Compiled Successfully ***'
|
@@ -0,0 +1,154 @@
|
|
1
|
+
module Aws
|
2
|
+
module Cfn
|
3
|
+
module Compiler
|
4
|
+
module Compile
|
5
|
+
|
6
|
+
def compile
|
7
|
+
desc = if @config[:description]
|
8
|
+
@config[:description]
|
9
|
+
elsif @spec and @spec['Description']
|
10
|
+
@spec['Description']
|
11
|
+
elsif @config[:template]
|
12
|
+
File.basename(@config[:template]).gsub(%r/\..*$/, '')
|
13
|
+
else
|
14
|
+
'compiled template'
|
15
|
+
end
|
16
|
+
vers = if @config[:formatversion]
|
17
|
+
@config[:formatversion]
|
18
|
+
else
|
19
|
+
if @spec and @spec['AWSTemplateFormatVersion']
|
20
|
+
@spec['AWSTemplateFormatVersion']
|
21
|
+
else
|
22
|
+
'2010-09-09'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
# [2014-06-29 Christo] IIRC it is important that the section names be strings instead of symbols ...
|
26
|
+
# noinspection RubyStringKeysInHashInspection
|
27
|
+
compiled =
|
28
|
+
{
|
29
|
+
'AWSTemplateFormatVersion' => vers,
|
30
|
+
'Description' => desc,
|
31
|
+
'Mappings' => @items['Mappings'],
|
32
|
+
'Parameters' => @items['Parameters'],
|
33
|
+
'Resources' => @items['Resources'],
|
34
|
+
'Outputs' => @items['Outputs'],
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
def find_refs(hash, type='Reference', parent='')
|
39
|
+
h = {}
|
40
|
+
newparent = parent
|
41
|
+
if hash.is_a? Hash
|
42
|
+
hash.keys.collect do |key|
|
43
|
+
if %w{Mappings Parameters Resources Outputs}.include? key
|
44
|
+
type = key#.gsub(/s$/, '')
|
45
|
+
newparent = key
|
46
|
+
elsif %w{Mappings Parameters Resources Outputs}.include? parent
|
47
|
+
newparent = key
|
48
|
+
end
|
49
|
+
if %w{Ref}.include? key
|
50
|
+
h = { hash[key] => [type,newparent] }
|
51
|
+
elsif 'Fn::GetAtt' == key
|
52
|
+
h = { hash[key].first => [type,newparent] }
|
53
|
+
# elsif %w{SourceSecurityGroupName CacheSecurityGroupNames SecurityGroupNames}.include? key
|
54
|
+
# a = find_refs(hash[key],type,newparent)
|
55
|
+
# h = merge(h, a, *[type,newparent])
|
56
|
+
else
|
57
|
+
a = find_refs(hash[key],type,newparent)
|
58
|
+
h = merge(h, a, *[type,newparent])
|
59
|
+
end
|
60
|
+
end.flatten.compact.uniq
|
61
|
+
elsif hash.is_a? Array
|
62
|
+
a = hash.map{|i| find_refs(i,type,newparent) }
|
63
|
+
h = merge(h, a, type, *[type,newparent])
|
64
|
+
end
|
65
|
+
h
|
66
|
+
end
|
67
|
+
|
68
|
+
def merge(h, a, *type)
|
69
|
+
if a.is_a? Hash
|
70
|
+
if a.size > 0
|
71
|
+
h.merge! a
|
72
|
+
end
|
73
|
+
else
|
74
|
+
a.flatten.compact.uniq.map { |i|
|
75
|
+
if i.is_a? Hash
|
76
|
+
if i.size > 0
|
77
|
+
h.merge! i
|
78
|
+
h
|
79
|
+
end
|
80
|
+
else
|
81
|
+
h[i] = type
|
82
|
+
end
|
83
|
+
}
|
84
|
+
end
|
85
|
+
h
|
86
|
+
end
|
87
|
+
|
88
|
+
def find_maps(hash)
|
89
|
+
if hash.is_a? Hash
|
90
|
+
tr = []
|
91
|
+
hash.keys.collect do |key|
|
92
|
+
if 'Fn::FindInMap' == key
|
93
|
+
hash[key].first
|
94
|
+
else
|
95
|
+
find_maps(hash[key])
|
96
|
+
end
|
97
|
+
end.flatten.compact.uniq
|
98
|
+
elsif hash.is_a? Array
|
99
|
+
hash.collect{|a| find_maps(a)}.flatten.compact.uniq
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def map_resource_reference(rsrc)
|
104
|
+
path = nil
|
105
|
+
sub = nil
|
106
|
+
ref = nil
|
107
|
+
rel = false
|
108
|
+
# noinspection RubyParenthesesAroundConditionInspection
|
109
|
+
if rsrc.match %r'^(\.\./.*?)::(.*)$'
|
110
|
+
# Relative path stack reference
|
111
|
+
path,sub,ref,rel = map_resource_reference(File.basename(rsrc))
|
112
|
+
elsif rsrc.match %r'^(~/.*?)$'
|
113
|
+
# Relative to HOME
|
114
|
+
path,sub,ref,rel = map_resource_reference(File.expand_path(rsrc))
|
115
|
+
elsif rsrc.match %r'^(\.\./[^:]*?)$'
|
116
|
+
# Relative path
|
117
|
+
path = File.dirname(rsrc)
|
118
|
+
sub = File.basename(path)
|
119
|
+
path = File.dirname(path)
|
120
|
+
ref = File.basename(rsrc)
|
121
|
+
rel = true
|
122
|
+
elsif rsrc.match %r'(^/.*?)::(.*)$'
|
123
|
+
# Absolute path
|
124
|
+
_,sub,ref,rel = map_resource_reference(File.basename(rsrc))
|
125
|
+
path = File.realpath(File.join(File.dirname(rsrc),_))
|
126
|
+
elsif rsrc.match %r'(^/.*?[^:]*?)$'
|
127
|
+
# Absolute path
|
128
|
+
path = File.dirname(rsrc)
|
129
|
+
sub = File.basename(path)
|
130
|
+
path = File.dirname(path)
|
131
|
+
ref = File.basename(rsrc)
|
132
|
+
elsif (match = rsrc.match %r'^(.*?)::(.*)$')
|
133
|
+
# Inherited stack reference
|
134
|
+
ref = match[2]
|
135
|
+
# noinspection RubyParenthesesAroundConditionInspection
|
136
|
+
if (subm = match[1].match(%r'^(.+?)/(.+)$'))
|
137
|
+
path = File.join(File.dirname(@config[:directory]),subm[1])
|
138
|
+
sub = subm[2]
|
139
|
+
else
|
140
|
+
# sub = nil
|
141
|
+
path = File.join(File.dirname(@config[:directory]),match[1])
|
142
|
+
end
|
143
|
+
else
|
144
|
+
# Otherwise it is what it seems ;)
|
145
|
+
ref = rsrc
|
146
|
+
end
|
147
|
+
[path,sub,ref,rel]
|
148
|
+
end
|
149
|
+
|
150
|
+
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module Aws
|
2
|
+
module Cfn
|
3
|
+
module Compiler
|
4
|
+
module Load
|
5
|
+
|
6
|
+
# --------------------------------------------------------------------------------
|
7
|
+
def get_file_set(want, path, exts=[])
|
8
|
+
raise "Bad call to #{self.class.name}.get_file_set: want == nil" unless want
|
9
|
+
@logger.debug "Look for #{want.ai} in #{[path]} with #{exts} extensions"
|
10
|
+
if exts.nil?
|
11
|
+
exts = @config[:precedence]
|
12
|
+
end
|
13
|
+
file_regex=%r/^(\S+)\.(#{exts.join('|')})$/
|
14
|
+
if exts.empty?
|
15
|
+
file_regex=%r/^(\S+)()$/
|
16
|
+
exts=['']
|
17
|
+
end
|
18
|
+
regex = "^(#{want.join('|')})$"
|
19
|
+
set = {}
|
20
|
+
abs = File.expand_path(path)
|
21
|
+
abs = path unless @config[:expandedpaths]
|
22
|
+
raise "Oops! Does '#{path}' directory exist?" unless File.directory?(abs)
|
23
|
+
#abs = File.realpath(abs)
|
24
|
+
begin
|
25
|
+
Dir.glob("#{abs}/*").each{ |f|
|
26
|
+
match = File.basename(f).match(file_regex)
|
27
|
+
if match
|
28
|
+
name = match[1]
|
29
|
+
ext = match[2]
|
30
|
+
set[ext] = {} unless set[ext]
|
31
|
+
@logger.trace "#{name} =~ #{regex}"
|
32
|
+
set[ext][name] = f if name.match(regex)
|
33
|
+
end
|
34
|
+
}
|
35
|
+
rescue RegexpError => e
|
36
|
+
raise "The regular expression attempting to match resources in '#{path}' is incorrect! #{e.message}"
|
37
|
+
end
|
38
|
+
@logger.debug "getPathSet set=#{set.ai}"
|
39
|
+
res = {}
|
40
|
+
# Iterate extension sets in increasing precedence order ...
|
41
|
+
# Survivor will be the most desireable version of the item
|
42
|
+
# i.e. the .rb environment, role, data bag, etc. will be preferred over the .json version
|
43
|
+
exts.each{ |e|
|
44
|
+
h = set[e]
|
45
|
+
if h
|
46
|
+
h.each{ |n,f|
|
47
|
+
@logger.info "Ignoring #{File.basename(res[n])}" if res[n]
|
48
|
+
res[n] = f
|
49
|
+
}
|
50
|
+
else
|
51
|
+
@logger.debug "'#{e}' set is empty! (No #{path}/*.#{e} files found using precedence #{exts})"
|
52
|
+
end
|
53
|
+
}
|
54
|
+
res
|
55
|
+
end
|
56
|
+
|
57
|
+
def vet_path(dir,base=nil,rel=false)
|
58
|
+
if rel
|
59
|
+
base = File.realpath(File.expand_path(File.join(@config[:directory], base)))
|
60
|
+
else
|
61
|
+
base = @config[:directory] unless base
|
62
|
+
end
|
63
|
+
path = nil
|
64
|
+
[dir, dir.downcase].each do |d|
|
65
|
+
path = File.join(base, dir)
|
66
|
+
if File.directory?(path)
|
67
|
+
break
|
68
|
+
end
|
69
|
+
end
|
70
|
+
unless File.directory?(path)
|
71
|
+
@logger.error " !! error: Cannot load bricks from #{path} (started with #{File.join(base, dir)}')"
|
72
|
+
abort!
|
73
|
+
end
|
74
|
+
path
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Aws
|
2
|
+
module Cfn
|
3
|
+
module Compiler
|
4
|
+
module Options
|
5
|
+
|
6
|
+
# TODO: [2014-06-29 Christo] Hook into super class and add on options instead of starting from scratch every time
|
7
|
+
def parse_options
|
8
|
+
|
9
|
+
setup_options
|
10
|
+
|
11
|
+
@opts.on :F, :format=, 'The output format of the components. [JSON|YAML|Ruby]', { as: String, match: @format_regex, default: 'yaml' }
|
12
|
+
@opts.on :s, :specification=, 'The specification to use when selecting components. A JSON or YAML file', { as: String
|
13
|
+
}
|
14
|
+
@opts.on :f, :formatversion=, 'The AWS Template format version. ', {as: String,
|
15
|
+
default: '2010-09-09'
|
16
|
+
}
|
17
|
+
@opts.on :D, :description=, "The AWS Template description. Default: template name", { as: String }
|
18
|
+
@opts.on :p, :precedence=, 'The precedence of template component types. Default: rb,ruby,yaml,yml,json,js', { as: String,
|
19
|
+
default: 'rb,ruby,yaml,yml,json,js', }
|
20
|
+
|
21
|
+
@opts.parse!
|
22
|
+
|
23
|
+
if ARGV.size > 0
|
24
|
+
puts @opts
|
25
|
+
abort! "Extra arguments! #{ARGV}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def set_config_options
|
30
|
+
|
31
|
+
@config[:precedence] = @opts[:precedence].split(%r',+\s*').reverse
|
32
|
+
|
33
|
+
setup_config
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
module Aws
|
2
|
+
module Cfn
|
3
|
+
module Compiler
|
4
|
+
module Parse
|
5
|
+
|
6
|
+
def parse
|
7
|
+
@dsl ||= Aws::Cfn::Dsl::Template.new(@config[:directory])
|
8
|
+
%w( Mappings Parameters Resources Outputs ).each do |section|
|
9
|
+
parse_section(section,@spec)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# noinspection RubyGlobalVariableNamingConvention
|
14
|
+
def parse_section(section,spec=nil)
|
15
|
+
logStep "Parsing #{section}..."
|
16
|
+
|
17
|
+
if spec and spec[section]
|
18
|
+
abort! "No such directory: #{@config[:directory]} (I am here: #{Dir.pwd})" unless File.directory?(@config[:directory])
|
19
|
+
@items ||= {}
|
20
|
+
@items[section] ||= {}
|
21
|
+
get = {}
|
22
|
+
item = {}
|
23
|
+
spec[section].each do |rsrc|
|
24
|
+
@logger.info "\tUsing #{section}::#{rsrc}"
|
25
|
+
refp,sub,base,rel = map_resource_reference(rsrc)
|
26
|
+
if refp.nil?
|
27
|
+
path = vet_path(section)
|
28
|
+
else
|
29
|
+
path = vet_path(sub ? sub : section, refp, rel)
|
30
|
+
end
|
31
|
+
unless get[path]
|
32
|
+
get[path] = get_file_set([".*"], path, @config[:precedence])
|
33
|
+
end
|
34
|
+
set = get[path]
|
35
|
+
if set[base]
|
36
|
+
if item.has_key?(base)
|
37
|
+
@logger.error " !! error: Duplicate item: #{section}/#{base}"
|
38
|
+
abort!
|
39
|
+
end
|
40
|
+
|
41
|
+
filename = set[base]
|
42
|
+
unless filename =~ /\.(ru?by?|ya?ml|js(|on))\z/i
|
43
|
+
@logger.info "Brick not supported/ relevant: #{filename}"
|
44
|
+
next
|
45
|
+
end
|
46
|
+
|
47
|
+
begin
|
48
|
+
@logger.debug " reading #{filename}"
|
49
|
+
content = File.read(filename)
|
50
|
+
next if content.size==0
|
51
|
+
|
52
|
+
if filename =~ /\.(rb|ruby)\z/i
|
53
|
+
item.merge! parse_rb_file(base, section, filename)
|
54
|
+
elsif filename =~ /\.js(|on)\z/i
|
55
|
+
item.merge! JSON.parse(content)
|
56
|
+
elsif filename =~ /\.ya?ml\z/i
|
57
|
+
item.merge! YAML.load(content)
|
58
|
+
else
|
59
|
+
next
|
60
|
+
end
|
61
|
+
|
62
|
+
rescue
|
63
|
+
abort! " !! error: #{$!}"
|
64
|
+
end
|
65
|
+
else
|
66
|
+
abort! " !! error: #{section}/#{base} not found!"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
item.keys.each { |key|
|
70
|
+
if @items[section].has_key?(key)
|
71
|
+
abort! " !! error: Duplicate item: #{section}/#{key}"
|
72
|
+
end
|
73
|
+
}
|
74
|
+
@items[section].merge! item
|
75
|
+
|
76
|
+
unless @items[section].keys.count == spec[section].count
|
77
|
+
abort! " !! error: Suspect that a #{section} item was missed! \nRequested: #{spec[section]}\n Found: #{@items[section].keys}"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
def parse_rb_file(base, section, filename)
|
84
|
+
Aws::Cfn::Compiler.binding ||= {}
|
85
|
+
Aws::Cfn::Compiler.binding[section] ||= {}
|
86
|
+
Aws::Cfn::Compiler.binding[section][base] ||= {
|
87
|
+
brick_path: @config[:directory],
|
88
|
+
template: @dsl,
|
89
|
+
logger: @logger
|
90
|
+
}
|
91
|
+
source_file = File.expand_path(filename)
|
92
|
+
# source = IO.read(source_file)
|
93
|
+
eval "require source_file", binding
|
94
|
+
unless @dsl.dict[section.to_sym]
|
95
|
+
abort! "Unable to compile/expand #{filename} for #{section}/#{base}"
|
96
|
+
end
|
97
|
+
sym_to_s(@dsl.dict[section.to_sym])
|
98
|
+
end
|
99
|
+
|
100
|
+
def sym_to_s(hash)
|
101
|
+
if hash.is_a?(Hash)
|
102
|
+
item = {}
|
103
|
+
hash.each { |k,v|
|
104
|
+
item[k.to_s] = sym_to_s(v)
|
105
|
+
}
|
106
|
+
item
|
107
|
+
elsif hash.is_a?(Array)
|
108
|
+
hash.map{|e| sym_to_s(e) }
|
109
|
+
elsif hash.is_a?(String)
|
110
|
+
hash
|
111
|
+
else
|
112
|
+
abort! "#{hash} is a #{hash.class.name}"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Aws
|
2
|
+
module Cfn
|
3
|
+
module Compiler
|
4
|
+
module Save
|
5
|
+
|
6
|
+
def save_section(dir, file, format, section, hash, join='/', brick=nil)
|
7
|
+
brick ||= "brick #{hash.keys[0]}"
|
8
|
+
path = File.join(File.expand_path(dir), file)
|
9
|
+
filn = if @config[:expandedpaths]
|
10
|
+
path
|
11
|
+
else
|
12
|
+
File.join(dir, file)
|
13
|
+
end
|
14
|
+
logStep "Saving #{brick} to #{filn} "
|
15
|
+
# noinspection RubyAssignmentExpressionInConditionalInspection
|
16
|
+
if match = file.match(%r'\.(.*)$')
|
17
|
+
if (section != '') and (not formats_compatible?(format, match[1]))
|
18
|
+
msg = "The file extension (#{match[1]}) does not match the chosen output format (#{format})!"
|
19
|
+
if @config[:force]
|
20
|
+
logger.warn msg
|
21
|
+
else
|
22
|
+
abort! "#{msg}\n\tIf you are SURE this is what you want then use the --force option!"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
if i_am_maintainer(path) or @config[:force]
|
28
|
+
begin
|
29
|
+
File.open path, File::CREAT|File::TRUNC|File::RDWR, 0644 do |f|
|
30
|
+
case format
|
31
|
+
when /ruby|rb|yaml|yml/
|
32
|
+
f.write maintainer_comment('')
|
33
|
+
f.write hash.to_yaml line_width: 1024, indentation: 4, canonical: false
|
34
|
+
when /json|js/
|
35
|
+
# You wish ... f.write maintainer_comment('')
|
36
|
+
f.write JSON.pretty_generate(hash, { indent: "\t", space: ' '})
|
37
|
+
else
|
38
|
+
abort! "Internal: Unsupported format #{format}. Should have noticed this earlier!"
|
39
|
+
end
|
40
|
+
f.close
|
41
|
+
end
|
42
|
+
@logger.info " decompiled #{filn}."
|
43
|
+
rescue
|
44
|
+
abort! "!!! Could not write compiled file #{path}: #{$!}"
|
45
|
+
end
|
46
|
+
else
|
47
|
+
@logger.warn " Did not overwrite #{filn}."
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aws-cfn-compiler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- PKinney
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-06-
|
11
|
+
date: 2014-06-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: awesome_print
|
@@ -72,54 +72,26 @@ dependencies:
|
|
72
72
|
- - ! '>='
|
73
73
|
- !ruby/object:Gem::Version
|
74
74
|
version: '0'
|
75
|
-
- !ruby/object:Gem::Dependency
|
76
|
-
name: colorize
|
77
|
-
requirement: !ruby/object:Gem::Requirement
|
78
|
-
requirements:
|
79
|
-
- - ! '>='
|
80
|
-
- !ruby/object:Gem::Version
|
81
|
-
version: '0'
|
82
|
-
type: :runtime
|
83
|
-
prerelease: false
|
84
|
-
version_requirements: !ruby/object:Gem::Requirement
|
85
|
-
requirements:
|
86
|
-
- - ! '>='
|
87
|
-
- !ruby/object:Gem::Version
|
88
|
-
version: '0'
|
89
|
-
- !ruby/object:Gem::Dependency
|
90
|
-
name: inifile
|
91
|
-
requirement: !ruby/object:Gem::Requirement
|
92
|
-
requirements:
|
93
|
-
- - ! '>='
|
94
|
-
- !ruby/object:Gem::Version
|
95
|
-
version: '0'
|
96
|
-
type: :runtime
|
97
|
-
prerelease: false
|
98
|
-
version_requirements: !ruby/object:Gem::Requirement
|
99
|
-
requirements:
|
100
|
-
- - ! '>='
|
101
|
-
- !ruby/object:Gem::Version
|
102
|
-
version: '0'
|
103
75
|
- !ruby/object:Gem::Dependency
|
104
76
|
name: aws-cfn-dsl
|
105
77
|
requirement: !ruby/object:Gem::Requirement
|
106
78
|
requirements:
|
107
79
|
- - ! '>='
|
108
80
|
- !ruby/object:Gem::Version
|
109
|
-
version: 0.
|
81
|
+
version: 0.7.0
|
110
82
|
- - ~>
|
111
83
|
- !ruby/object:Gem::Version
|
112
|
-
version: '0.
|
84
|
+
version: '0.7'
|
113
85
|
type: :runtime
|
114
86
|
prerelease: false
|
115
87
|
version_requirements: !ruby/object:Gem::Requirement
|
116
88
|
requirements:
|
117
89
|
- - ! '>='
|
118
90
|
- !ruby/object:Gem::Version
|
119
|
-
version: 0.
|
91
|
+
version: 0.7.0
|
120
92
|
- - ~>
|
121
93
|
- !ruby/object:Gem::Version
|
122
|
-
version: '0.
|
94
|
+
version: '0.7'
|
123
95
|
- !ruby/object:Gem::Dependency
|
124
96
|
name: dldinternet-mixlib-cli
|
125
97
|
requirement: !ruby/object:Gem::Requirement
|
@@ -197,6 +169,11 @@ files:
|
|
197
169
|
- lib/aws/cfn/compiler.rb
|
198
170
|
- lib/aws/cfn/compiler/base.rb
|
199
171
|
- lib/aws/cfn/compiler/main.rb
|
172
|
+
- lib/aws/cfn/compiler/mixins/compile.rb
|
173
|
+
- lib/aws/cfn/compiler/mixins/load.rb
|
174
|
+
- lib/aws/cfn/compiler/mixins/options.rb
|
175
|
+
- lib/aws/cfn/compiler/mixins/parse.rb
|
176
|
+
- lib/aws/cfn/compiler/mixins/save.rb
|
200
177
|
- lib/aws/cfn/compiler/version.rb
|
201
178
|
homepage: https://github.com/dldinternet/aws-cfn-compiler
|
202
179
|
licenses:
|