mirror of
https://github.com/inspec/inspec
synced 2024-12-30 06:53:22 +00:00
80 lines
3 KiB
Ruby
80 lines
3 KiB
Ruby
|
require 'fileutils'
|
||
|
require 'erb'
|
||
|
|
||
|
module Init
|
||
|
class Renderer
|
||
|
# Creates a renderer able to render the given template type
|
||
|
# 1. iterate over all files
|
||
|
# 2. read content in erb
|
||
|
# 3. write to full_destination_root_path
|
||
|
|
||
|
attr_reader :overwrite_mode, :ui
|
||
|
def initialize(cli_ui, cli_options = {})
|
||
|
@ui = cli_ui
|
||
|
@overwrite_mode = cli_options['overwrite']
|
||
|
end
|
||
|
|
||
|
# rubocop: disable Metrics/AbcSize
|
||
|
def render_with_values(template_type, template_values = {})
|
||
|
# look for template directory
|
||
|
base_dir = File.join(File.dirname(__FILE__), 'templates', template_type)
|
||
|
# prepare glob for all subdirectories and files
|
||
|
template_glob = File.join(base_dir, '**', '{*,.*}')
|
||
|
# Use the name attribute to define the path to the profile.
|
||
|
profile_path = template_values[:name]
|
||
|
# Use slashes (\, /) to split up the name into an Array then use the last entry
|
||
|
# to reset the name of the profile.
|
||
|
template_values[:name] = template_values[:name].split(%r{\\|\/}).last
|
||
|
# Generate the full full_destination_root_path path on disk
|
||
|
full_destination_root_path = Pathname.new(Dir.pwd).join(profile_path)
|
||
|
ui.plain_text "Create new #{template_type} at #{ui.mark_text(full_destination_root_path)}"
|
||
|
|
||
|
# check that the directory does not exist
|
||
|
if File.exist?(full_destination_root_path) && !overwrite_mode
|
||
|
ui.plain_text "#{ui.mark_text(full_destination_root_path)} exists already, use --overwrite"
|
||
|
ui.exit(1)
|
||
|
end
|
||
|
|
||
|
# ensure that full_destination_root_path directory is available
|
||
|
FileUtils.mkdir_p(full_destination_root_path)
|
||
|
|
||
|
# iterate over files and write to full_destination_root_path
|
||
|
Dir.glob(template_glob) do |file|
|
||
|
relative_destination_item_path = Pathname.new(file).relative_path_from(Pathname.new(base_dir))
|
||
|
full_destination_item_path = Pathname.new(full_destination_root_path).join(relative_destination_item_path)
|
||
|
if File.directory?(file)
|
||
|
ui.li "Create directory #{ui.mark_text(relative_destination_item_path)}"
|
||
|
FileUtils.mkdir_p(full_destination_item_path)
|
||
|
elsif File.file?(file)
|
||
|
ui.li "Create file #{ui.mark_text(relative_destination_item_path)}"
|
||
|
# read & render content
|
||
|
content = render(File.read(file), template_values)
|
||
|
# write file content
|
||
|
File.write(full_destination_item_path, content)
|
||
|
else
|
||
|
ui.plain_text "Ignore #{file}, because its not an file or directoy"
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
# rubocop: enable Metrics/AbcSize
|
||
|
|
||
|
# This is a render helper to bind hash values to a ERB template
|
||
|
# ERB provides result_with_hash in ruby 2.5.0+, which does exactly this
|
||
|
def render(template_content, hash)
|
||
|
# create a new binding class
|
||
|
cls = Class.new do
|
||
|
hash.each do |key, value|
|
||
|
define_method key.to_sym do
|
||
|
value
|
||
|
end
|
||
|
end
|
||
|
# expose binding
|
||
|
define_method :bind do
|
||
|
binding
|
||
|
end
|
||
|
end
|
||
|
ERB.new(template_content).result(cls.new.bind)
|
||
|
end
|
||
|
end
|
||
|
end
|