Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
mkstack / bin / mkstack
Size: Mime:
#!/usr/bin/env ruby

require "logger"
require "optparse"
require_relative "../lib/mkstack"

version = "1.3.1"


##################################################
# Main

# Define logger
$logger = Logger.new(STDERR)
$logger.level = Logger::WARN
$logger.formatter = proc { |s, d, p, m|
  x = caller(4, 1)[0]
  line = x.split(':')[1]
  file = x.split(':')[0].split('/')[-1]
  func = x.split("'")[-1]
  "[%s] %5s [%-12s] [%4d] %s: %s\n" % [ d.strftime("%Y-%m-%d %H:%M:%S"), s, file, line, func, m ]
}

# Default options
options = {}
options[:erb] = true
options[:format] = "json"
options[:erb_argv] = []

# Command line options
opts = OptionParser.new do |p|
  desc_padding = " " * (p.summary_indent.length + p.summary_width)

  p.banner = "Usage: #{p.program_name} [ options ] file1 [ file2... ]"

  # Help
  p.on("-h", "--help", "Display this message") { puts opts ; exit }
  p.on("--version", "Show version") { puts version ; exit }
  p.separator(" ")

  # Verbosity
  p.on("-d", "--debug",   "Show debug messages")         { $logger.level = Logger::DEBUG }
  p.on("-v", "--verbose", "Be verbose")                  { $logger.level = Logger::INFO }
  p.on("-q", "--quiet",   "Only show errors")            { $logger.level = Logger::ERROR }
  p.on("-s", "--silent",  "Don't show any log messages") { $logger.level = Logger::FATAL }
  p.separator(" ")

  # Output
  p.on("-o", "--output=FILE",   "Print final template to FILE") { |x| options[:save] = x }
  p.on("%s Use '-' for stdout" % [ desc_padding ])
  p.on("-f", "--format=FORMAT", [ "json", "yaml" ], "Print as FORMAT") { |x| options[:format] = x }
  p.on("%s Supported formats: json (default), yaml" % [ desc_padding ])
  p.separator(" ")

  # Operations
  p.on("--erb", "--[no-]erb", "Perform ERB processing (default is true)") { |x| options[:erb] = x }
  p.on("--validate", "Call ValidateTemplate after merging") { options[:validate] = true }
  p.separator(" ")

  # ERB options
  p.on("---", "Marks end of mkstack options") { p.terminate("---") }
  p.on("%s Remaining arguments are available to ERB as an Array argv" % [ desc_padding ])
end

# Separate files from ERB arguments
args = opts.parse!

if args.index("---")
  files = args[0..(args.index("---") - 1)]
  options[:erb_argv] = args[(args.index("---") + 1)..nil]
else
  files = args
end

# At least one file is required
files.uniq!
opts.parse "--help" if ((files.count == 0) or (files[0].eql?("---")))

# Merge files
template = MkStack::Template.new(options[:format], options[:erb_argv])

files.each do |file|
  begin
    Dir.chdir(File.dirname(file)) {
      template.merge(File.basename(file), options[:erb])
    }
  rescue KeyError => e
    $logger.warn { "#{file}: already parsed" }
  rescue Exception => e
    $logger.error { e.message }
  end
end

# Check limits
$logger.debug { "Checking limits" }

template.sections.each do |name, section|
  $logger.warn { "#{name} limit exceeded: (#{section.length} > #{section.limit})" } if section.exceeds_limit?
end

$logger.warn { "At least one Resources member must be defined" } if template["Resources"].length == 0
$logger.warn { "Template too large (#{template.length} > #{template.limit})" } if template.exceeds_limit?

# Validate template
if options[:validate] then
  begin
    $logger.info { "Validating #{template.format} template" }

    template.validate
  rescue Exception => e
    $logger.error { e.message }
  end
end

# Save template
if options[:save] then
  $logger.debug { "saving #{options[:save]}" }

  begin
    unless options[:save] == '-'
      f = File.new(options[:save], File::CREAT | File::WRONLY)
      f.truncate(0)
      $stdout = f
    end

    $logger.info { "Saving #{template.format} to #{$stdout.path}" } unless $stdout == STDOUT

    puts template.pp
  rescue Exception => e
    $logger.error { e.message }
  end
end