diff options
Diffstat (limited to 'lib/dslkeywords/directory.rb')
| -rw-r--r-- | lib/dslkeywords/directory.rb | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/lib/dslkeywords/directory.rb b/lib/dslkeywords/directory.rb new file mode 100644 index 0000000..402bead --- /dev/null +++ b/lib/dslkeywords/directory.rb @@ -0,0 +1,104 @@ +require 'fileutils' + +require_relative 'file' + +module RCM + # Manages directories: create, delete/purge, or recursively copy from + # a source directory. Backup is performed before destructive operations. + class Directory < BaseFile + def recursively = @recursively = true + + def evaluate! + return unless super + + case @is + when :present + evaluate_present! + when :absent, :purged + evaluate_absent! + end + ensure + permissions! + end + + private + + def evaluate_present! + if ::File.directory?(@file_path) + return @recursively ? evaluate_present_recursively! : nil + end + + create_parent_directory! if @manage_directory + + do? "Creating directory #{@file_path}" do + Dir.mkdir(@file_path) + end + end + + def evaluate_absent! + return unless ::File.directory?(@file_path) + + backup!(@file_path) + @recursively = true if @is == :purged + what = @is == :purged ? 'Purging' : 'Deleting' + + do? "#{what} directory #{@file_path}" do + if ::File.directory?(@file_path) + @recursively ? FileUtils.rm_r(@file_path) : Dir.delete(@file_path) + end + end + cleanup_parent_directory! if @manage_directory + end + + def evaluate_present_recursively! + source_path = content + raise "Source #{source_path} is not a directory!" unless ::File.directory?(source_path) + + if ::File.exist?(@file_path) + raise "Destination #{@file_path} is not a directory!" unless ::File.directory?(@file_path) + + backup_recursively!(source_path, @file_path) unless @without_backup + end + + do? "Copying #{source_path} -> #{@file_path} recursively" do + if ::File.directory?(@file_path) + Dir["#{source_path}/*"].each { FileUtils.cp_r(_1, @file_path) } + else + FileUtils.cp_r(source_path, @file_path) + end + end + end + + # TODO: Unit test this + def backup_recursively!(source, dest) + Dir.foreach(source) do |entry| + next if ['.', '..'].include?(entry) + + source_path = ::File.join(source, entry) + dest_path = ::File.join(dest, entry) + + if ::File.directory?(source_path) && !::File.directory?(dest_path) + raise "Unable to copy directory #{source_path} into non-directory #{dest_path}" + elsif !::File.directory?(source_path) && ::File.directory?(dest_path) + raise "Unable to copy non-directory #{source_path} into directory #{dest_path}" + elsif ::File.directory?(source_path) && ::File.directory?(dest_path) + backup_recursively!(source_path, dest_path) + else + backup!(dest_path) + end + end + end + end + + class DSL + def directory(file_path = nil, &block) + return :directory if file_path.nil? + return unless @conds_met + + d = Directory.new(file_path) + d.content(d.instance_eval(&block)) + self << d + d + end + end +end |
