Last active
September 11, 2020 18:24
-
-
Save coreyti/17dda3c996d9d188bf72feb41e678290 to your computer and use it in GitHub Desktop.
Command to render ERB+YAML
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
require 'optparse' | |
require 'ostruct' | |
require 'erb' | |
require 'json' | |
require 'yaml' | |
module GCP | |
class Context | |
def self.for(path, params) | |
self.new(path, params).send(:__binding__) | |
end | |
def initialize(path, params) | |
file = File.read(path) if path && File.exist?(path) | |
@data = file.nil? ? {} : YAML.load(file) | |
@path = path | |
@params = params | |
end | |
def data | |
@_data ||= to_ostruct(@data) | |
end | |
def env | |
@env ||= to_ostruct(ENV) | |
end | |
def render(path, options = {}) | |
full = File.expand_path(File.join(@params[:template], '..', path)) | |
file = File.read(full) | |
data = YAML.load(::ERB.new(file).result(self.send(:__binding__))) | |
data.to_json | |
end | |
private | |
def to_ostruct(hash) | |
result = OpenStruct.new(hash) | |
hash.each.with_object(result) do |(key, value), result| | |
result.send(:"#{key}=", to_ostruct(value)) if value.is_a?(Hash) | |
end | |
result | |
end | |
def __binding__ | |
binding.taint | |
end | |
end | |
class Template | |
def initialize(path) | |
@file = File.read(path) | |
end | |
def render(context) | |
::ERB.new(@file).result(context) | |
end | |
end | |
class Arguments < Struct.new(:tmpl, :data) | |
def valid? | |
File.exist?(tmpl) && (data.nil? || File.exist?(data)) | |
end | |
end | |
class Parser | |
def self.parse(options) | |
args = Arguments.new | |
input = OptionParser.new do |opts| | |
opts.banner = "Usage: render [options]" | |
opts.on '-t', '--tmpl=<path>', "[required] A path to ERB template" do |value| | |
args.tmpl = value | |
end | |
opts.on '-d', '--data=<path>', "[optional] A path to YAML data" do |value| | |
args.data = value | |
end | |
opts.on_tail '-h', '--help', "Prints this help" do |value| | |
puts opts ; exit | |
end | |
end | |
input.parse!(options) | |
if args.valid? | |
return args | |
else | |
puts input.help ; exit 1 | |
end | |
end | |
end | |
end | |
arguments = GCP::Parser.parse(ARGV) | |
template = GCP::Template.new arguments.tmpl | |
context = GCP::Context.for arguments.data, template: arguments.tmpl | |
puts template.render(context) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- | |
something: | |
nested: has a value |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- | |
key: <%= data.something.nested %> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- | |
# render this as: | |
# `VARIABLE=value ./render -t example-tmpl.yml -d example-data.yml` | |
thing: <%= data.something.nested %> | |
other: <%= env.VARIABLE %> | |
partial: <%= render('example-part.yml') %> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment