diff options
| author | Paul Buetow <paul@buetow.org> | 2025-02-19 14:45:53 +0200 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2025-02-19 14:45:53 +0200 |
| commit | 79c1e080d47954cfd90e338685f30f1481087922 (patch) | |
| tree | 185187621ffbf8e465cfc1d8730646d5fa42ca44 | |
| parent | bbd4d006e08235c83900f206f7e4e772fbad6bd4 (diff) | |
fix
| -rw-r--r-- | lib/dslkeywords/file.rb | 122 | ||||
| -rw-r--r-- | lib/dslkeywords/resource.rb | 1 | ||||
| -rw-r--r-- | test/lib/dslkeywords/file_test.rb | 23 |
3 files changed, 72 insertions, 74 deletions
diff --git a/lib/dslkeywords/file.rb b/lib/dslkeywords/file.rb index 7bbd587..d9a31fa 100644 --- a/lib/dslkeywords/file.rb +++ b/lib/dslkeywords/file.rb @@ -21,32 +21,72 @@ module RCM end end - # Managing files - class File < Resource - include FileBackup + # Base for File and Symlink + class BaseFile < Resource include Chained - class UnsupportedOperation < StandardError; end - def initialize(file_path) super(file_path) @file_path = file_path - @is = :installed + @is = :present end + class UnsupportedOperation < StandardError; 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 from(what) = @from = validate(__method__, what.to_sym, :sourcefile, :template) + def path(file_path = nil) = file_path.nil? ? @file_path : @file_path = file_path + def content(text = nil) - return @content if text.nil? + if text.nil? + text = @from == :sourcefile ? ::File.read(@content) : @content + return @from == :template ? ERB.new(text).result : text + end @content = text.instance_of?(Array) ? text.join("\n") : text end - def line(line) = @ensure_line = line - def path(file_path = nil) = file_path.nil? ? @file_path : @file_path = file_path + protected - def is(what) = @is = validate(__method__, what.to_sym, :present, :absent, :symlink) - def manage(what) = @manage_directory = validate(__method__, what.to_sym, :directory) == :directory + # Validate whether we can use this up in this context or not + def validate(method, what, *valids) + return what if valids.include?(what) + + raise UnsupportedOperation, + "Unsupported '#{method}' operation #{what} (#{what.class})" + end + + def create_parent_directory! + dirname = ::File.dirname(@file_path) + return if ::File.directory?(dirname) + + info "Creating parent directory #{dirname}" + FileUtils.mkdir_p(dirname) + end + + def evaluate_absent! + if ::File.exist?(@file_path) + info("Deleting #{@file_path}") + ::File.delete(@file_path) + end + return unless @manage_directory + + parent_dir = ::File.dirname(@file_path) + while Dir.empty?(parent_dir) + info("Deleting empty parent directory #{parent_dir}") + Dir.rmdir(parent_dir) + parent_dir = ::File.dirname(parent_dir) + end + end + end + + # 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 - def from(what) = @from = validate(__method__, what.to_sym, :sourcefile, :template) def evaluate! return unless super @@ -54,21 +94,12 @@ module RCM return evaluate_absent! if @is == :absent create_parent_directory! if @manage_directory - return evaluate_symlink! if @is == :symlink - write!(real_content) + write!(content) end private - # Validate whether we can use this up in this context or not - def validate(method, what, *valids) - return what if valids.include?(what) - - raise UnsupportedOperation, - "Unsupported '#{method}' operation #{what} (#{what.class})" - end - def evaluate_ensure_line! return evaluate_ensure_line_absent! if %i[absent].include?(@is) return write!(@ensure_line) unless ::File.file?(@file_path) @@ -87,27 +118,7 @@ module RCM end.join("\n")) end - def evaluate_absent! - if ::File.exist?(@file_path) - info("Deleting #{@file_path}") - ::File.delete(@file_path) - end - return unless @manage_directory - - parent_dir = ::File.dirname(@file_path) - while Dir.empty?(parent_dir) - info("Deleting empty parent directory #{parent_dir}") - Dir.rmdir(parent_dir) - parent_dir = ::File.dirname(parent_dir) - end - end - - def evaluate_symlink! = FileUtils.ln_sf(real_content, @file_path) - def write!(text) - info "Managing file #{@file_path}" - debug text if option :debug - tmp_path = "#{@file_path}.rcmtmp" ::File.write(tmp_path, text) @@ -124,18 +135,16 @@ module RCM ::File.rename(tmp_path, @file_path) end + end - def create_parent_directory! - dirname = ::File.dirname(@file_path) - return if ::File.directory?(dirname) - - info "Creating parent directory #{dirname}" - FileUtils.mkdir_p(dirname) - end + # Manage symlinks + class Symlink < BaseFile + def evaluate! + return unless super + return evaluate_absent! if @is == :absent - def real_content - text = @from == :sourcefile ? ::File.read(@content) : @content - @from == :template ? ERB.new(text).result : text + create_parent_directory! if @manage_directory + FileUtils.ln_sf(content, @file_path) end end @@ -150,12 +159,13 @@ module RCM f end - def symlink(...) + def symlink(file_path, &block) return unless @conds_met - f = file(...) - f.is(:symlink) - f + s = Symlink.new(file_path) + s.content(s.instance_eval(&block)) + self << s + s end end end diff --git a/lib/dslkeywords/resource.rb b/lib/dslkeywords/resource.rb index 2358ff5..aea47cc 100644 --- a/lib/dslkeywords/resource.rb +++ b/lib/dslkeywords/resource.rb @@ -50,6 +50,7 @@ module RCM def evaluate! return false if @evaluated + info 'Evaluating...' raise DependencyLoop, "Dependency loop detected for #{id}" if @loop_detection @loop_detection = true diff --git a/test/lib/dslkeywords/file_test.rb b/test/lib/dslkeywords/file_test.rb index d27ae77..001d272 100644 --- a/test/lib/dslkeywords/file_test.rb +++ b/test/lib/dslkeywords/file_test.rb @@ -162,28 +162,18 @@ class RCMFileTest < Minitest::Test end def test_create_symlink - symlink1_path = "#{DIR_PATH}/the_symlink1" - symlink2_path = "#{DIR_PATH}/the_symlink2" + symlink_path = "#{DIR_PATH}/the_symlink" symlink_target = "#{DIR_PATH}/the_symlink_target" configure_from_scratch do - file symlink1_path do - is symlink - manage directory - symlink_target - end - - symlink symlink2_path do + symlink symlink_path do manage directory symlink_target end end - assert File.symlink?(symlink1_path) - assert_equal symlink_target, File.readlink(symlink1_path) - - assert File.symlink?(symlink2_path) - assert_equal symlink_target, File.readlink(symlink2_path) + assert File.symlink?(symlink_path) + assert_equal symlink_target, File.readlink(symlink_path) end def test_change_symlink @@ -200,10 +190,7 @@ class RCMFileTest < Minitest::Test symlink changed do path symlink_path - # TODO: Make it so that 'requires symlink original' works here, this - # requires to refactor the file class into multiple modules and two - # classes file and symlink - requires file original + requires symlink original symlink_target2 end end |
