1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
|
# frozen_string_literal: true
require 'English'
require 'puppet'
require 'fileutils'
begin
require 'win32/dir'
rescue LoadError
nil
end
module RSpec::Puppet
class Setup
def self.run(module_name = nil)
unless is_module_dir?
warn 'Does not appear to be a Puppet module. Aborting'
return false
end
if control_repo?
warn <<~END
Unable to find a metadata.json file. If this is a module, please create a
metadata.json file and try again.
END
return false
end
safe_setup_directories(module_name)
safe_touch(File.join('spec', 'fixtures', 'manifests', 'site.pp'))
safe_create_spec_helper
safe_create_rakefile
end
def self.safe_setup_directories(module_name = nil, verbose = true)
if control_repo?
warn 'Unable to setup rspec-puppet automatically in a control repo' if verbose
return false
end
if module_name.nil?
module_name = get_module_name
if module_name.nil?
warn 'Unable to determine module name. Aborting' if verbose
return false
end
end
[
'spec',
File.join('spec', 'classes'),
File.join('spec', 'defines'),
File.join('spec', 'functions'),
File.join('spec', 'hosts'),
File.join('spec', 'fixtures'),
File.join('spec', 'fixtures', 'manifests'),
File.join('spec', 'fixtures', 'modules')
].each { |dir| safe_mkdir(dir, verbose) }
target = File.join('spec', 'fixtures', 'modules', module_name)
safe_make_link('.', target, verbose)
end
def self.safe_teardown_links(module_name = nil)
if module_name.nil?
module_name = get_module_name
if module_name.nil?
warn 'Unable to determine module name. Aborting'
return false
end
end
target = File.join('spec', 'fixtures', 'modules', module_name)
return unless File.symlink?(target) && File.readlink(target) == File.expand_path('.')
File.unlink(target)
end
def self.control_repo?
!File.exist?('metadata.json')
end
def self.get_module_name
module_name = nil
Dir['manifests/*.pp'].entries.each do |manifest|
module_name = get_module_name_from_file(manifest)
break unless module_name.nil?
end
module_name
end
def self.get_module_name_from_file(file)
require 'puppet/pops'
p = Puppet::Pops::Parser::Lexer2.new
module_name = nil
p.string = File.read(file)
tokens = p.fullscan
i = tokens.index { |token| %i[CLASS DEFINE].include? token.first }
module_name = tokens[i + 1].last[:value].split('::').first unless i.nil?
module_name
end
def self.is_module_dir?
Dir['*'].entries.include? 'manifests'
end
def self.safe_mkdir(dir, verbose = true)
if File.exist? dir
warn "!! #{dir} already exists and is not a directory" unless File.directory? dir
else
begin
FileUtils.mkdir dir
rescue Errno::EEXIST => e
raise e unless File.directory? dir
end
puts " + #{dir}/" if verbose
end
end
def self.safe_touch(file)
if File.exist? file
warn "!! #{file} already exists and is not a regular file" unless File.file? file
else
FileUtils.touch file
puts " + #{file}"
end
end
def self.safe_create_file(filename, content)
if File.exist? filename
old_content = File.read(filename)
warn "!! #{filename} already exists and differs from template" if old_content != content
else
File.open(filename, 'w') do |f|
f.puts content
end
puts " + #{filename}"
end
end
def self.safe_create_spec_helper
content = File.read(File.expand_path(File.join(__FILE__, '..', 'spec_helper.rb')))
safe_create_file('spec/spec_helper.rb', content)
end
def self.link_to_source?(target, source)
return false unless link?(target)
link_target = Dir.respond_to?(:read_junction) ? Dir.read_junction(target) : File.readlink(target)
link_target == File.expand_path(source)
end
def self.link?(target)
Dir.respond_to?(:junction?) ? Dir.junction?(target) : File.symlink?(target)
end
def self.safe_make_link(source, target, verbose = true)
if File.exist?(target) && !link?(target)
warn "!! #{target} already exists and is not a symlink"
return
end
return if link_to_source?(target, source)
if Puppet::Util::Platform.windows?
output = `call mklink /J "#{target.tr('/', '\\')}" "#{source}"`
unless $CHILD_STATUS.success?
puts output
abort
end
else
begin
FileUtils.ln_s(File.expand_path(source), target)
rescue Errno::EEXIST => e
raise e unless link_to_source?(target, source)
end
end
puts " + #{target}" if verbose
end
def self.safe_create_rakefile
content = <<~EOF
require 'rspec-puppet/rake_task'
begin
if Gem::Specification::find_by_name('puppet-lint')
require 'puppet-lint/tasks/puppet-lint'
PuppetLint.configuration.ignore_paths = ["spec/**/*.pp", "vendor/**/*.pp"]
task :default => [:rspec, :lint]
end
rescue Gem::LoadError
task :default => :rspec
end
EOF
safe_create_file('Rakefile', content)
end
end
end
|