lib/rodbot/generator.rb
# frozen-string-literal: true
require 'fileutils'
require 'erb'
require 'pastel'
module Rodbot
# Generators for new bots, deployments and such
#
# All files inside the +templates_path+ are honoured provided they match the
# {GLOB}. Files with the extension ".gerb" are parsed like ERB files, however,
# GERB tags must use square brackets.
#
# ERB: <%= 'foobar' %>
# GERB: [%= 'foobar' %]
#
# It's therefore possible to generate ERB files such as +index.erb.gerb+.
#
# Helpers available in GERB templates have to be defined in
# {Rodbot::Generator::Helpers}.
class Generator
# Glob to filter relevant template files
GLOB = "**/{*,.ruby-version*,.gitignore,.keep}"
# Colors used by +info+ to color part of the output
TAG_COLORS = {
create: :green
}.freeze
# @param templates_path [Pathname] root path of the templates to generate from
def initialize(templates_path)
@templates_path = templates_path
@helpers_binding = Helpers.new.instance_eval('binding')
@pastel = Pastel.new
end
# Print the interpolated template to STDOUT
def display
puts
each_template_path do |template_path, target_path, content|
puts "### #{target_path} ###", (content || template_path.read), nil
end
end
# Write the interpolated template to directory
#
# @param directory [Pathname] where to write the files to
def write(directory)
fail(Rodbot::GeneratorError, "cowardly refusing to write to existing #{directory}") if directory.exist?
each_template_path do |template_path, target_path, content|
absolute_target_path = directory.join(target_path)
absolute_target_path.dirname.mkpath
puts tag(:create, target_path)
if content
absolute_target_path.write(content)
else
FileUtils.copy(template_path, absolute_target_path)
end
end
end
private
def each_template_path
@templates_path.glob(GLOB).each do |template_path|
next unless template_path.file?
target_path = template_path.relative_path_from(@templates_path)
content = if template_path.extname == '.gerb'
target_path = target_path.dirname.join(target_path.basename('.gerb'))
eval_gerb(template_path.read)
end
yield(template_path, target_path, content)
end
end
def eval_gerb(string)
ungerbify(ERB.new(gerbify(string), trim_mode: '-').result(@helpers_binding))
end
def gerbify(string)
string.gsub('<%', '{%').gsub('%>', '%}').gsub('[%', '<%').gsub('%]', '%>')
end
def ungerbify(string)
string.gsub('{%', '<%').gsub('%}', '%>')
end
def tag(tag, string)
padded_tag = '[' + tag.to_s.ljust(6, ' ') + '] '
@pastel.decorate(padded_tag, TAG_COLORS[tag]) + string.to_s.strip
end
class Helpers
def time_zone
Rodbot.config(:time_zone)
end
def relay_extensions
Rodbot.plugins.extend_relay
Rodbot.plugins.extensions[:relay].to_h do |name, _|
[name, URI(Rodbot::Services::Relay.url(name)).port]
end
end
end
end
end