summaryrefslogtreecommitdiff
path: root/lib/dslkeywords/directory.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/dslkeywords/directory.rb')
-rw-r--r--lib/dslkeywords/directory.rb104
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