diff options
| -rw-r--r-- | .gitignore | 2 | ||||
| -rw-r--r-- | TODO.md | 1 | ||||
| -rw-r--r-- | lib/dslkeywords/file.rb | 76 | ||||
| -rw-r--r-- | test/lib/dslkeywords/directory_test.rb | 26 | ||||
| -rw-r--r-- | test/lib/dslkeywords/file_test.rb | 2 |
5 files changed, 87 insertions, 20 deletions
@@ -1 +1 @@ -.rcm +.rcmbackup @@ -1,5 +1,6 @@ # TODO +* Purge a directory * Recursively install a directory * Support for file modes (owner, chmod) * User and group management diff --git a/lib/dslkeywords/file.rb b/lib/dslkeywords/file.rb index bcbe350..e52e41f 100644 --- a/lib/dslkeywords/file.rb +++ b/lib/dslkeywords/file.rb @@ -8,22 +8,45 @@ require_relative '../chained' module RCM # Backup the file on change module FileBackup - def backup!(file_path, checksum = Digest::SHA256.file(file_path).hexdigest) + def backup!(file_path, checksum = nil) return if @without_backup - backup_dir = "#{::File.dirname(file_path)}/.rcm" - Dir.mkdir(backup_dir) unless ::File.directory?(backup_dir) - backup_path = "#{backup_dir}/#{::File.basename(file_path)}.#{checksum}" + suffix = if ::File.file?(file_path) + checksum.nil? ? Digest::SHA256.file(file_path).hexdigest : checksum + else + Time.now.strftime('%s-%L') + end + make_backup!(file_path, suffix) + end + + private + + def make_backup!(file_path, suffix) + backup_dir = create_backup_directory!(file_path) + backup_path = "#{backup_dir}/#{::File.basename(file_path)}.#{suffix}" return if ::File.exist?(backup_path) - info("Backing up #{file_path} -> #{backup_path}") - ::File.rename(file_path, backup_path) + dry? "Backing up #{file_path} -> #{backup_path}" do + ::File.rename(file_path, backup_path) + end + end + + def create_backup_directory!(file_path) + backup_dir = "#{::File.dirname(file_path)}/.rcmbackup" + return backup_dir if ::File.directory?(backup_dir) + + dry? "Creating backup directory #{backup_dir}" do + Dir.mkdir(backup_dir) + end + + backup_dir end end # Base for BaseFile and Directory class BasicFile < Resource include Chained + include FileBackup def initialize(file_path) super(file_path) @@ -32,6 +55,7 @@ module RCM end def is(what) = @is = validate(__method__, what.to_sym, :present, :absent) + def manage(what) = @manage_directory = validate(__method__, what.to_sym, :directory) == :directory def path(file_path = nil) = file_path.nil? ? @file_path : @file_path = file_path def content(text = nil) @@ -76,7 +100,6 @@ module RCM class BaseFile < BasicFile class UnsupportedOperation < StandardError; end - def manage(what) = @manage_directory = validate(__method__, what.to_sym, :directory) == :directory def from(what) = @from = validate(__method__, what.to_sym, :sourcefile, :template) protected @@ -94,8 +117,6 @@ module RCM # Managing files class File < BaseFile - include FileBackup - def line(line) = @ensure_line = line def without(what) = @without_backup = validate(__method__, what.to_sym, :backup) == :backup @@ -136,9 +157,7 @@ module RCM def write!(text) tmp_path = "#{@file_path}.rcmtmp" - dry? "Writing file #{@file_path}" do - ::File.write(tmp_path, text) - end + ::File.write(tmp_path, text) if ::File.file?(@file_path) checksum = Digest::SHA256.file(@file_path).hexdigest @@ -148,11 +167,13 @@ module RCM ::File.delete(tmp_path) # File has not changed, not doing anything return end - # File changed, backup! - backup!(@file_path, checksum) unless option :dry + backup!(@file_path, checksum) # File changed, backup! end - ::File.rename(tmp_path, @file_path) unless option :dry + dry? "Writing #{@file_path}" do + ::File.rename(tmp_path, @file_path) + end + ::File.delete(tmp_path) if ::File.file?(tmp_path) end end @@ -173,12 +194,33 @@ module RCM def evaluate! return unless super - raise 'Not yet implemented' + evaluate_present! if @is == :present + evaluate_absent! if @is == :absent + end + + def evaluate_present! + return if ::File.directory?(@file_path) + + create_parent_directory! if @manage_directory + + dry? "Creating directory #{@file_path}" do + Dir.mkdir(@file_path) + end + end + + def evaluate_absent! + return unless ::File.directory?(@file_path) + + backup!(@file_path) + dry? "Deleting directory #{@file_path}" do + Dir.delete(@file_path) if ::File.directory?(@file_path) + cleanup_parent_directory! if @manage_directory + end end end - # Add file keyword to the DSL class DSL + # Add file keyword to the DSL def file(file_path = nil, &block) return :file if file_path.nil? return unless @conds_met diff --git a/test/lib/dslkeywords/directory_test.rb b/test/lib/dslkeywords/directory_test.rb index 68ce2d4..302db37 100644 --- a/test/lib/dslkeywords/directory_test.rb +++ b/test/lib/dslkeywords/directory_test.rb @@ -4,9 +4,33 @@ require 'fileutils' require_relative '../../../lib/dsl' class RCMDirectoryTest < Minitest::Test - DIR_PATH = './.dir_test.rcmtmp'.freeze + DIR_PATH = './.directory_test.rcmtmp'.freeze Minitest.after_run do FileUtils.rm_r(DIR_PATH) if File.directory?(DIR_PATH) end + + def test_create_directory + configure_from_scratch do + directory DIR_PATH do + is present + end + end + assert File.directory?(DIR_PATH) + end + + def test_delete_directory + configure_from_scratch do + directory create do + path DIR_PATH + is present + end + directory delete do + path DIR_PATH + is absent + requires directory create + end + end + refute File.directory?(DIR_PATH) + end end diff --git a/test/lib/dslkeywords/file_test.rb b/test/lib/dslkeywords/file_test.rb index 7a6116c..e3d76fb 100644 --- a/test/lib/dslkeywords/file_test.rb +++ b/test/lib/dslkeywords/file_test.rb @@ -140,7 +140,7 @@ class RCMFileTest < Minitest::Test def test_backup file_path = "#{DIR_PATH}/foo/backup-me.txt" original_content = 'original_content' - backup_path = "#{DIR_PATH}/foo/.rcm/backup-me.txt.d4c3af73588ce06c32ed04d1b79801286109ea265712a2bd3fdc3ed01c82bb86" + backup_path = "#{DIR_PATH}/foo/.rcmbackup/backup-me.txt.d4c3af73588ce06c32ed04d1b79801286109ea265712a2bd3fdc3ed01c82bb86" configure_from_scratch do file original do |
