summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO.md2
-rw-r--r--lib/dslkeywords/file.rb58
-rw-r--r--test/lib/dslkeywords/directory_test.rb68
3 files changed, 116 insertions, 12 deletions
diff --git a/TODO.md b/TODO.md
index 385f2e2..66609a2 100644
--- a/TODO.md
+++ b/TODO.md
@@ -1,6 +1,6 @@
# TODO
-* Recursively install a directory (rsync? custom file copier?)
+* Recursively change file permissions (for files and dirs)
* Change permissions of a directory recursively
* CRON jobs
* Fedora
diff --git a/lib/dslkeywords/file.rb b/lib/dslkeywords/file.rb
index 1c62790..0c6ab9a 100644
--- a/lib/dslkeywords/file.rb
+++ b/lib/dslkeywords/file.rb
@@ -8,6 +8,7 @@ require_relative '../chained'
module RCM
# Backup the file on change
module FileBackup
+ # TODO: Make protected?
def backup!(file_path, checksum = nil)
return if @without_backup
@@ -19,6 +20,12 @@ module RCM
make_backup!(file_path, suffix)
end
+ def different?(file_a, file_b)
+ checksum_a = Digest::SHA256.file(file_a).hexdigest
+ checksum_b = Digest::SHA256.file(file_b).hexdigest
+ [checksum_a == checksum_b, checksum_a, cecksum_b]
+ end
+
private
def make_backup!(file_path, suffix)
@@ -208,10 +215,8 @@ module RCM
::File.write(tmp_path, text)
if ::File.file?(@file_path)
- checksum = Digest::SHA256.file(@file_path).hexdigest
- tmp_checksum = Digest::SHA256.file(tmp_path).hexdigest
-
- if tmp_checksum == checksum
+ different, checksum, = different?(@file_path, tmp_path)
+ unless different
::File.delete(tmp_path) # File has not changed, not doing anything
return
end
@@ -260,6 +265,8 @@ module RCM
end
class Directory < BaseFile
+ def recursively = @recursively = true
+
def evaluate!
return unless super
@@ -273,8 +280,12 @@ module RCM
permissions!
end
+ private
+
def evaluate_present!
- return if ::File.directory?(@file_path)
+ if ::File.directory?(@file_path)
+ return @recursively ? evaluate_present_recursively! : nil
+ end
create_parent_directory! if @manage_directory
@@ -287,15 +298,50 @@ module RCM
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)
- @is == :purged ? FileUtils.rm_r(@file_path) : Dir.delete(@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_resursively!(source_path, @file_path) unless @without_backup
+ end
+
+ do? "Copying #{source_path} -> #{@file_path} resursively" do
+ Dir["#{source_path}/*"].each { FileUtils.cp_r(_1, @file_path) }
+ end
+ end
+
+ 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
diff --git a/test/lib/dslkeywords/directory_test.rb b/test/lib/dslkeywords/directory_test.rb
index 9fd249f..3245603 100644
--- a/test/lib/dslkeywords/directory_test.rb
+++ b/test/lib/dslkeywords/directory_test.rb
@@ -6,9 +6,9 @@ require_relative '../../../lib/dsl'
class RCMDirectoryTest < Minitest::Test
DIR_PATH = './.directory_test.rcmtmp'.freeze
- Minitest.after_run do
- FileUtils.rm_r(DIR_PATH) if File.directory?(DIR_PATH)
- end
+ # Minitest.after_run do
+ # FileUtils.rm_r(DIR_PATH) if File.directory?(DIR_PATH)
+ # end
def test_create_directory
configure_from_scratch do
@@ -28,7 +28,6 @@ class RCMDirectoryTest < Minitest::Test
directory delete do
path DIR_PATH
is absent
- requires directory create
end
end
refute File.directory?(DIR_PATH)
@@ -42,11 +41,70 @@ class RCMDirectoryTest < Minitest::Test
end
directory purge do
path DIR_PATH
- requires touch create
is purged
without backup
end
end
refute File.directory?(DIR_PATH)
end
+
+ def test_copy_directory_recursively
+ expected_files = {}
+
+ configure_from_scratch do
+ 2.times do |i|
+ file "file_#{i + 10}_dest" do
+ path "#{DIR_PATH}/dest_dir/file_#{i + 10}.txt"
+ manage directory
+ expected_files["file_#{i + 10}.txt"] = "file_#{i + 10}_dest"
+ "file_#{i + 10}_dest"
+ end
+ file "file_#{i}_dest" do
+ path "#{DIR_PATH}/dest_dir/file_#{i}.txt"
+ manage directory
+ expected_files["file_#{i}.txt"] = "file_#{i}_dest"
+ "file_#{i}_dest"
+ end
+ file "file_#{i}_sub_dest" do
+ path "#{DIR_PATH}/dest_dir/sub/file_#{i}.txt"
+ expected_files["sub/file_#{i}.txt"] = "sub_file_#{i}_dest"
+ manage directory
+ "sub_file_#{i}_dest"
+ end
+ end
+
+ 4.times do |i|
+ file "file_#{i}_source" do
+ path "#{DIR_PATH}/source_dir/file_#{i}.txt"
+ manage directory
+ expected_files["file_#{i}.txt"] = "file_#{i}_source"
+ "file_#{i}_source"
+ end
+ file "file_#{i}_sub_source" do
+ path "#{DIR_PATH}/source_dir/sub/file_#{i}.txt"
+ manage directory
+ expected_files["sub/file_#{i}.txt"] = "sub_file_#{i}_source"
+ "sub_file_#{i}_source"
+ end
+ end
+
+ directory "#{DIR_PATH}/dest_dir" do
+ recursively
+ without backup
+ "#{DIR_PATH}/source_dir"
+ end
+ end
+
+ expected_files.each do |file_path, content|
+ assert File.file?("#{DIR_PATH}/dest_dir/#{file_path}")
+ assert_equal content, File.read("#{DIR_PATH}/dest_dir/#{file_path}")
+ end
+
+ actual_files = (Dir["#{DIR_PATH}/dest_dir/*"] + Dir["#{DIR_PATH}/dest_dir/*/*"]).select { File.file?(_1) }
+ actual_files.each do |file_path|
+ key = file_path.sub("#{DIR_PATH}/dest_dir/", '')
+ assert expected_files.key?(key)
+ assert_equal File.read(file_path), expected_files[key]
+ end
+ end
end