diff options
| author | Paul Buetow <paul@buetow.org> | 2025-02-26 12:04:16 +0200 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2025-02-26 12:04:16 +0200 |
| commit | 90ddeff0cf134240659003796e28708f046a5030 (patch) | |
| tree | 2ba2cf44f94acba559397f6f0734163be0bc3a45 | |
| parent | b394011ce33bd6116bb7d27520d5adea27310862 (diff) | |
can change owner of files and dirs
| -rw-r--r-- | TODO.md | 19 | ||||
| -rw-r--r-- | lib/dslkeywords/file.rb | 46 | ||||
| -rw-r--r-- | test/lib/dslkeywords/mode_test.rb | 26 |
3 files changed, 75 insertions, 16 deletions
@@ -1,12 +1,7 @@ # TODO -* Support for file modes (owner, chmod) - Test the mode -* Recursively install a directory (rsync?) -* User and group management - * Fedora - * FreeBSD - * OpenBSD +* Recursively install a directory (rsync? custom file copier?) +* Change permissions of a directory recursively * CRON jobs * Fedora * FreeBSD @@ -22,3 +17,13 @@ * Homebrew (macOS) * Make a gem out of rcm * Use rakelib and split up rakefiles +* User and group management + * Fedora + * add user + * remove user + * add group to user + * remove group from user + * add group + * remove group + * FreeBSD + * OpenBSD diff --git a/lib/dslkeywords/file.rb b/lib/dslkeywords/file.rb index c1f55d3..41fcf16 100644 --- a/lib/dslkeywords/file.rb +++ b/lib/dslkeywords/file.rb @@ -59,6 +59,8 @@ module RCM def path(file_path = nil) = file_path.nil? ? @file_path : @file_path = file_path def without(what) = @without_backup = validate(__method__, what.to_sym, :backup) == :backup def mode(what) = @mode = what + def owner(what) = @owner = what + def group(what) = @group = what def evaluate! unless super @@ -78,12 +80,12 @@ module RCM protected - def mode!(file_path = path) - return if !::File.exist?(file_path) || @mode.nil? + def permissions!(file_path = path) + return unless ::File.exist?(file_path) - dry? "Setting mode of #{file_path} to #{@mode}" do - FileUtils.chmod(@mode, file_path) - end + stat = ::File.stat(file_path) + set_mode!(stat) + set_owner!(stat) end # Validate whether we can use this up in this context or not @@ -112,6 +114,32 @@ module RCM parent_dir = ::File.dirname(parent_dir) end end + + private + + def set_mode!(stat, file_path = path) + return if @mode.nil? + + current_mode = stat.mode.to_s(8).split('')[-4..-1].join.to_i(8) + return unless current_mode != @mode + + dry? "Changing mode of #{file_path} to #{@mode}" do + FileUtils.chmod(@mode, file_path) + end + end + + def set_owner!(stat, file_path = path) + return if @owner.nil? && @group.nil? + + current_owner = Etc.getpwuid(stat.uid) + current_group = Etc.getgrgid(stat.gid) + + return if (@owner.nil? || @owner == current_owner) && (@group.nil? || @group == current_group) + + dry? "Changing owner of #{file_path} to #{@owner || ''}:#{@group || ''}" do + FileUtils.chown(@owner, @group, file_path) + end + end end # Base for File and Symlink @@ -147,7 +175,7 @@ module RCM write!(content) ensure - mode! + permissions! end private @@ -207,7 +235,7 @@ module RCM FileUtils.ln_sf(content, @file_path) end ensure - mode! + permissions! end end @@ -226,7 +254,7 @@ module RCM FileUtils.touch(@file_path) end ensure - mode! + permissions! end end @@ -241,7 +269,7 @@ module RCM evaluate_absent! end ensure - mode! + permissions! end def evaluate_present! diff --git a/test/lib/dslkeywords/mode_test.rb b/test/lib/dslkeywords/mode_test.rb index 4102c74..a4bf099 100644 --- a/test/lib/dslkeywords/mode_test.rb +++ b/test/lib/dslkeywords/mode_test.rb @@ -46,4 +46,30 @@ class RCMModeTest < Minitest::Test assert_equal 0o705, File.stat(DIR_PATH).mode.to_s(8).split('')[-4..-1].join.to_i(8) assert_equal 0o777, File.stat(SYMLINK_TARGET_PATH).mode.to_s(8).split('')[-4..-1].join.to_i(8) end + + def test_chown + configure_from_scratch do + # Well, test only makes sense that it doesn't throw any exception, as test + # can't change files to other owners as test will likely run as non-root. + user_name = Etc.getlogin + group_name = Etc.getgrgid(Process.gid).name + + touch FILE1_PATH do + owner user_name + group group_name + end + directory DIR_PATH do + owner user_name + group group_name + end + + stat = File.stat(FILE1_PATH) + assert_equal user_name, Etc.getpwuid(stat.uid) + assert_equal group_name, Etc.getgrgid(stat.gid) + + stat = File.stat(DIR_PATH) + assert_equal user_name, Etc.getpwuid(stat.uid) + assert_equal group_name, Etc.getgrgid(stat.gid) + end + end end |
