Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 76 additions & 22 deletions lib/fileutils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ def remove_trailing_slash(dir) #:nodoc:
#
# Keyword arguments:
#
# - <tt>mode: <i>integer</i></tt> - also calls <tt>File.chmod(mode, path)</tt>;
# - <tt>mode: <i>mode</i></tt> - also calls <tt>File.chmod(mode, path)</tt>;
# see {File.chmod}[https://docs.ruby-lang.org/en/master/File.html#method-c-chmod].
# - <tt>noop: true</tt> - does not create directories.
# - <tt>verbose: true</tt> - prints an equivalent command:
Expand Down Expand Up @@ -334,7 +334,7 @@ def mkdir(list, mode: nil, noop: nil, verbose: nil)
#
# Keyword arguments:
#
# - <tt>mode: <i>integer</i></tt> - also calls <tt>File.chmod(mode, path)</tt>;
# - <tt>mode: <i>mode</i></tt> - also calls <tt>File.chmod(mode, path)</tt>;
# see {File.chmod}[https://docs.ruby-lang.org/en/master/File.html#method-c-chmod].
# - <tt>noop: true</tt> - does not create directories.
# - <tt>verbose: true</tt> - prints an equivalent command:
Expand Down Expand Up @@ -1177,6 +1177,9 @@ def rm_rf(list, noop: nil, verbose: nil, secure: nil)
# Avoids a local vulnerability that can exist in certain circumstances;
# see {Avoiding the TOCTTOU Vulnerability}[rdoc-ref:FileUtils@Avoiding+the+TOCTTOU+Vulnerability].
#
# Optional argument +force+ specifies whether to ignore
# raised exceptions of StandardError and its descendants.
#
def remove_entry_secure(path, force = false)
unless fu_have_symlink?
remove_entry path, force
Expand Down Expand Up @@ -1263,12 +1266,14 @@ def fu_stat_identical_entry?(a, b) #:nodoc:
end
private_module_function :fu_stat_identical_entry?

# Removes the entry given by +path+,
# which should be the entry for a regular file, a symbolic link,
# or a directory.
#
# This method removes a file system entry +path+.
# +path+ might be a regular file, a directory, or something.
# If +path+ is a directory, remove it recursively.
# Optional argument +force+ specifies whether to ignore
# raised exceptions of StandardError and its descendants.
#
# See also remove_entry_secure.
# Related: FileUtils.remove_entry_secure.
#
def remove_entry(path, force = false)
Entry_.new(path).postorder_traverse do |ent|
Expand All @@ -1283,9 +1288,11 @@ def remove_entry(path, force = false)
end
module_function :remove_entry

# Removes the file entry given by +path+,
# which should be the entry for a regular file or a symbolic link.
#
# Removes a file +path+.
# This method ignores StandardError if +force+ is true.
# Optional argument +force+ specifies whether to ignore
# raised exceptions of StandardError and its descendants.
#
def remove_file(path, force = false)
Entry_.new(path).remove_file
Expand All @@ -1294,20 +1301,20 @@ def remove_file(path, force = false)
end
module_function :remove_file

# Recursively removes the directory entry given by +path+,
# which should be the entry for a regular file, a symbolic link,
# or a directory.
#
# Removes a directory +dir+ and its contents recursively.
# This method ignores StandardError if +force+ is true.
# Optional argument +force+ specifies whether to ignore
# raised exceptions of StandardError and its descendants.
#
def remove_dir(path, force = false)
remove_entry path, force # FIXME?? check if it is a directory
end
module_function :remove_dir

#
# Returns true if the contents of a file +a+ and a file +b+ are identical.
#
# FileUtils.compare_file('somefile', 'somefile') #=> true
# FileUtils.compare_file('/dev/null', '/dev/urandom') #=> false
# Returns +true+ if the contents of files +a+ and +b+ are identical,
# +false+ otherwise.
#
def compare_file(a, b)
return false unless File.size(a) == File.size(b)
Expand All @@ -1324,8 +1331,8 @@ def compare_file(a, b)
module_function :identical?
module_function :cmp

#
# Returns true if the contents of a stream +a+ and +b+ are identical.
# Returns +true+ if the contents of streams +a+ and +b+ are identical,
# +false+ otherwise.
#
def compare_stream(a, b)
bsize = fu_stream_blksize(a, b)
Expand All @@ -1342,13 +1349,60 @@ def compare_stream(a, b)
end
module_function :compare_stream

# Copies the file entry at path +src+ to the entry at path +dest+;
# each of +src+ and +dest+ may be a string or a
# {Pathname}[https://docs.ruby-lang.org/en/master/Pathname.html].
#
# See {install(1)}[https://man7.org/linux/man-pages/man1/install.1.html].
#
# If the entry at +dest+ does not exist, copies from +src+ to +dest+:
#
# File.read('src0.txt') # => "aaa\n"
# File.exist?('dest0.txt') # => false
# FileUtils.install('src0.txt', 'dest0.txt')
# File.read('dest0.txt') # => "aaa\n"
#
# If +dest+ is a file entry, copies from +src+ to +dest+, overwriting:
#
# If +src+ is not same as +dest+, copies it and changes the permission
# mode to +mode+. If +dest+ is a directory, destination is +dest+/+src+.
# This method removes destination before copy.
# File.read('src1.txt') # => "aaa\n"
# File.read('dest1.txt') # => "bbb\n"
# FileUtils.install('src1.txt', 'dest1.txt')
# File.read('dest1.txt') # => "aaa\n"
#
# If +dest+ is a directory entry, copies from +src+ to <tt>dest/src</tt>,
# overwriting if necessary:
#
# File.read('src2.txt') # => "aaa\n"
# File.read('dest2/src2.txt') # => "bbb\n"
# FileUtils.install('src2.txt', 'dest2')
# File.read('dest2/src2.txt') # => "aaa\n"
#
# Keyword arguments:
#
# {chown(2)}[https://man7.org/linux/man-pages/man2/chown.2.html]
# and {chmod(2)}[https://man7.org/linux/man-pages/man2/chmod.2.html]
#
#
# - <tt>group: <i>group</i></tt> - changes the group if not +nil+,
# using {File.chown}[https://docs.ruby-lang.org/en/master/File.html#method-c-chown].
# - <tt>mode: <i>permissions</i></tt> - changes the permissions.
# using {File.chmod}[https://docs.ruby-lang.org/en/master/File.html#method-c-chmod].
# - <tt>noop: true</tt> - does not remove entries; returns +nil+.
# - <tt>owner: <i>owner</i></tt> - changes the owner if not +nil+,
# using {File.chown}[https://docs.ruby-lang.org/en/master/File.html#method-c-chown].
# - <tt>preserve: true</tt> - preserve timestamps
# using {File.utime}[https://docs.ruby-lang.org/en/master/File.html#method-c-utime].
# - <tt>verbose: true</tt> - prints an equivalent command:
#
# FileUtils.install('src0.txt', 'dest0.txt', noop: true, verbose: true)
# FileUtils.install('src1.txt', 'dest1.txt', noop: true, verbose: true)
# FileUtils.install('src2.txt', 'dest2', noop: true, verbose: true)
#
# Output:
#
# FileUtils.install 'ruby', '/usr/local/bin/ruby', mode: 0755, verbose: true
# FileUtils.install 'lib.rb', '/usr/local/lib/ruby/site_ruby', verbose: true
# install -c src0.txt dest0.txt
# install -c src1.txt dest1.txt
# install -c src2.txt dest2
#
def install(src, dest, mode: nil, owner: nil, group: nil, preserve: nil,
noop: nil, verbose: nil)
Expand Down