Module: AutoStacker24::Preprocessor

Defined in:
lib/autostacker24/template_preprocessor.rb

Class Method Summary collapse

Class Method Details

.parse_json(template) ⇒ Object



16
17
18
19
20
21
22
# File 'lib/autostacker24/template_preprocessor.rb', line 16

def self.parse_json(template)
  JSON(template)
rescue JSON::ParserError => e
  require 'json/pure' # pure ruby parser has better error diagnostics
  JSON(template)
  raise e
end

.preprocess(template) ⇒ Object



9
10
11
12
13
14
# File 'lib/autostacker24/template_preprocessor.rb', line 9

def self.preprocess(template)
  if template =~ /^\s*\/{2}\s*/i
    template = preprocess_json(parse_json(template)).to_json
  end
  template
end

.preprocess_json(json) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/autostacker24/template_preprocessor.rb', line 24

def self.preprocess_json(json)
  if json.is_a?(Hash)
    json.inject({}) do |m, (k, v)|
      if k == 'UserData' && v.is_a?(String)
        m.merge(k => preprocess_user_data(v))
      else
        m.merge(k => preprocess_json(v))
      end
    end
  elsif json.is_a?(Array)
    json.map{|v| preprocess_json(v)}
  elsif json.is_a?(String)
    preprocess_string(json)
  else
    json
  end
end

.preprocess_string(s) ⇒ Object



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/autostacker24/template_preprocessor.rb', line 48

def self.preprocess_string(s)
  parts = tokenize(s).map do |token|
    case token
      when '@@' then '@'
      when /^@/ then {'Ref' => token[1..-1]}
      else token
    end
  end

  # merge neighboured strings
  parts = parts.reduce([])do |m, p|
    if m.last.is_a?(String) && p.is_a?(String)
      m[-1] += p
    else
      m << p
    end
    m
  end

  if parts.length == 1
    parts.first
  else # we need a join construct
    {'Fn::Join' => ['', parts]}
  end
end

.preprocess_user_data(s) ⇒ Object



42
43
44
45
46
# File 'lib/autostacker24/template_preprocessor.rb', line 42

def self.preprocess_user_data(s)
  m = /^@file:\/\/(.*)/.match(s)
  s = File.read(m[1]) if m
  {'Fn::Base64' => s}
end

.tokenize(s) ⇒ Object



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/autostacker24/template_preprocessor.rb', line 74

def self.tokenize(s)
  pattern = /@@|@((\w+(::)?\w+)+)/
  tokens = []
  loop do
    m = pattern.match(s)
    if m
      tokens << m.pre_match unless m.pre_match.empty?
      tokens << m.to_s
      s = m.post_match
    else
      tokens << s unless s.empty? && !tokens.empty?
      break
    end
  end
  tokens
end