mirror of
https://github.com/inspec/inspec
synced 2024-12-20 18:13:20 +00:00
02cb93ec23
* Refactor 'inspec init profile' into a reusable component. base_cli.rb had several methods used internally, these are exposed so lib/bundles/inspec-init/profile.rb can act as a library for anything that needs to create new Inspec profiles programatically * Move output methods to be public instance methods; and make Init::Profile into a working renderer. Functional tests pass but could use some refactoring to be easier to use. * Refactor, renaming vars to be clearer * Move puts and exit calls into basecli * Add comment about simplified ERB rendering in ruby 2.5.0+ Signed-off-by: Clinton Wolfe <clintoncwolfe@gmail.com>
79 lines
3 KiB
Ruby
79 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
|