mirror of
https://github.com/inspec/inspec
synced 2025-01-02 00:09:01 +00:00
a084187b21
profile name. eg "with/slash" would result in a profile created in the "with" directory named "slash" Add test for inspec init, and updated other for new output. Clean up profiles created during testing and place them in temporary directories. Describe our test a bit better. Check that the profile was created in the right location. Check that the profile is named correctly. Signed-off-by: Miah Johnson <miah@chia-pet.org>
101 lines
3.4 KiB
Ruby
101 lines
3.4 KiB
Ruby
# encoding: utf-8
|
|
|
|
require 'pathname'
|
|
|
|
module Init
|
|
class CLI < Inspec::BaseCLI
|
|
namespace 'init'
|
|
|
|
# TODO: find another solution, once https://github.com/erikhuda/thor/issues/261 is fixed
|
|
def self.banner(command, _namespace = nil, _subcommand = false)
|
|
"#{basename} #{subcommand_prefix} #{command.usage}"
|
|
end
|
|
|
|
def self.subcommand_prefix
|
|
namespace
|
|
end
|
|
|
|
# read template directoy
|
|
template_dir = File.join(File.dirname(__FILE__), 'templates')
|
|
Dir.glob(File.join(template_dir, '*')) do |template|
|
|
relative = Pathname.new(template).relative_path_from(Pathname.new(template_dir))
|
|
|
|
# register command for the template
|
|
desc "#{relative} NAME", "Create a new #{relative}"
|
|
option :overwrite, type: :boolean, default: false,
|
|
desc: 'Overwrites existing directory'
|
|
define_method relative.to_s.to_sym do |name|
|
|
generator(relative.to_s, { name: name }, options)
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
# 1. iterate over all files
|
|
# 2. read content in erb
|
|
# 3. write to target
|
|
def generator(type, attributes = {}, options = {}) # rubocop:disable Metrics/AbcSize
|
|
# path of this script
|
|
dir = File.dirname(__FILE__)
|
|
# look for template directory
|
|
base_dir = File.join(dir, 'templates', type)
|
|
# prepare glob for all subdirectories and files
|
|
template = File.join(base_dir, '**', '{*,.*}')
|
|
# Use the name attribute to define the path to the profile.
|
|
profile_path = attributes[:name]
|
|
# Use slashes (\, /) to split up the name into an Array then use the last entry
|
|
# to reset the name of the profile.
|
|
attributes[:name] = attributes[:name].split(%r{\\|\/}).last
|
|
# Generate the full target path on disk
|
|
target = Pathname.new(Dir.pwd).join(profile_path)
|
|
puts "Create new #{type} at #{mark_text(target)}"
|
|
|
|
# check that the directory does not exist
|
|
if File.exist?(target) && !options['overwrite']
|
|
error "#{mark_text(target)} exists already, use --overwrite"
|
|
exit 1
|
|
end
|
|
|
|
# ensure that target directory is available
|
|
FileUtils.mkdir_p(target)
|
|
|
|
# iterate over files and write to target path
|
|
Dir.glob(template) do |file|
|
|
relative = Pathname.new(file).relative_path_from(Pathname.new(base_dir))
|
|
destination = Pathname.new(target).join(relative)
|
|
if File.directory?(file)
|
|
li "Create directory #{mark_text(relative)}"
|
|
FileUtils.mkdir_p(destination)
|
|
elsif File.file?(file)
|
|
li "Create file #{mark_text(relative)}"
|
|
# read & render content
|
|
content = render(File.read(file), attributes)
|
|
# write file content
|
|
File.write(destination, content)
|
|
else
|
|
puts "Ignore #{file}, because its not an file or directoy"
|
|
end
|
|
end
|
|
end
|
|
|
|
# This is a render helper to bind hash values to a ERB template
|
|
def render(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(content).result(cls.new.bind)
|
|
end
|
|
end
|
|
|
|
# register the subcommand to Inspec CLI registry
|
|
Inspec::Plugins::CLI.add_subcommand(Init::CLI, 'init', 'init TEMPLATE ...', 'Scaffolds a new project', {})
|
|
end
|