stdlib/fileutils/0/fileutils.rbs in rbs-3.0.0.dev.2 vs stdlib/fileutils/0/fileutils.rbs in rbs-3.0.0.dev.3
- old
+ new
@@ -1,103 +1,200 @@
# <!-- rdoc-file=lib/fileutils.rb -->
-# # fileutils.rb
+# Namespace for file utility methods for copying, moving, removing, etc.
#
-# Copyright (c) 2000-2007 Minero Aoki
+# ## What's Here
#
-# This program is free software. You can distribute/modify this program under
-# the same terms of ruby.
+# First, what’s elsewhere. Module FileUtils:
#
-# ## module FileUtils
+# * Inherits from [class Object](rdoc-ref:Object).
+# * Supplements [class File](rdoc-ref:File) (but is not included or extended
+# there).
#
-# Namespace for several file utility methods for copying, moving, removing, etc.
#
-# ### Module Functions
+# Here, module FileUtils provides methods that are useful for:
#
-# require 'fileutils'
+# * [Creating](rdoc-ref:FileUtils@Creating).
+# * [Deleting](rdoc-ref:FileUtils@Deleting).
+# * [Querying](rdoc-ref:FileUtils@Querying).
+# * [Setting](rdoc-ref:FileUtils@Setting).
+# * [Comparing](rdoc-ref:FileUtils@Comparing).
+# * [Copying](rdoc-ref:FileUtils@Copying).
+# * [Moving](rdoc-ref:FileUtils@Moving).
+# * [Options](rdoc-ref:FileUtils@Options).
#
-# FileUtils.cd(dir, **options)
-# FileUtils.cd(dir, **options) {|dir| block }
-# FileUtils.pwd()
-# FileUtils.mkdir(dir, **options)
-# FileUtils.mkdir(list, **options)
-# FileUtils.mkdir_p(dir, **options)
-# FileUtils.mkdir_p(list, **options)
-# FileUtils.rmdir(dir, **options)
-# FileUtils.rmdir(list, **options)
-# FileUtils.ln(target, link, **options)
-# FileUtils.ln(targets, dir, **options)
-# FileUtils.ln_s(target, link, **options)
-# FileUtils.ln_s(targets, dir, **options)
-# FileUtils.ln_sf(target, link, **options)
-# FileUtils.cp(src, dest, **options)
-# FileUtils.cp(list, dir, **options)
-# FileUtils.cp_r(src, dest, **options)
-# FileUtils.cp_r(list, dir, **options)
-# FileUtils.mv(src, dest, **options)
-# FileUtils.mv(list, dir, **options)
-# FileUtils.rm(list, **options)
-# FileUtils.rm_r(list, **options)
-# FileUtils.rm_rf(list, **options)
-# FileUtils.install(src, dest, **options)
-# FileUtils.chmod(mode, list, **options)
-# FileUtils.chmod_R(mode, list, **options)
-# FileUtils.chown(user, group, list, **options)
-# FileUtils.chown_R(user, group, list, **options)
-# FileUtils.touch(list, **options)
#
-# Possible `options` are:
+# ### Creating
#
-# `:force`
-# : forced operation (rewrite files if exist, remove directories if not empty,
-# etc.);
-# `:verbose`
-# : print command to be run, in bash syntax, before performing it;
-# `:preserve`
-# : preserve object's group, user and modification time on copying;
-# `:noop`
-# : no changes are made (usable in combination with `:verbose` which will
-# print the command to run)
+# * ::mkdir: Creates directories.
+# * ::mkdir_p, ::makedirs, ::mkpath: Creates directories, also creating
+# ancestor directories as needed.
+# * ::link_entry: Creates a hard link.
+# * ::ln, ::link: Creates hard links.
+# * ::ln_s, ::symlink: Creates symbolic links.
+# * ::ln_sf: Creates symbolic links, overwriting if necessary.
+# * ::ln_sr: Creates symbolic links relative to targets
#
#
-# Each method documents the options that it honours. See also ::commands,
-# ::options and ::options_of methods to introspect which command have which
-# options.
+# ### Deleting
#
-# All methods that have the concept of a "source" file or directory can take
-# either one file or a list of files in that argument. See the method
-# documentation for examples.
+# * ::remove_dir: Removes a directory and its descendants.
+# * ::remove_entry: Removes an entry, including its descendants if it is a
+# directory.
+# * ::remove_entry_secure: Like ::remove_entry, but removes securely.
+# * ::remove_file: Removes a file entry.
+# * ::rm, ::remove: Removes entries.
+# * ::rm_f, ::safe_unlink: Like ::rm, but removes forcibly.
+# * ::rm_r: Removes entries and their descendants.
+# * ::rm_rf, ::rmtree: Like ::rm_r, but removes forcibly.
+# * ::rmdir: Removes directories.
#
-# There are some `low level' methods, which do not accept keyword arguments:
#
-# FileUtils.copy_entry(src, dest, preserve = false, dereference_root = false, remove_destination = false)
-# FileUtils.copy_file(src, dest, preserve = false, dereference = true)
-# FileUtils.copy_stream(srcstream, deststream)
-# FileUtils.remove_entry(path, force = false)
-# FileUtils.remove_entry_secure(path, force = false)
-# FileUtils.remove_file(path, force = false)
-# FileUtils.compare_file(path_a, path_b)
-# FileUtils.compare_stream(stream_a, stream_b)
-# FileUtils.uptodate?(file, cmp_list)
+# ### Querying
#
-# ## module FileUtils::Verbose
+# * ::pwd, ::getwd: Returns the path to the working directory.
+# * ::uptodate?: Returns whether a given entry is newer than given other
+# entries.
#
-# This module has all methods of FileUtils module, but it outputs messages
-# before acting. This equates to passing the `:verbose` flag to methods in
-# FileUtils.
#
-# ## module FileUtils::NoWrite
+# ### Setting
#
-# This module has all methods of FileUtils module, but never changes
-# files/directories. This equates to passing the `:noop` flag to methods in
-# FileUtils.
+# * ::cd, ::chdir: Sets the working directory.
+# * ::chmod: Sets permissions for an entry.
+# * ::chmod_R: Sets permissions for an entry and its descendants.
+# * ::chown: Sets the owner and group for entries.
+# * ::chown_R: Sets the owner and group for entries and their descendants.
+# * ::touch: Sets modification and access times for entries, creating if
+# necessary.
#
-# ## module FileUtils::DryRun
#
-# This module has all methods of FileUtils module, but never changes
-# files/directories. This equates to passing the `:noop` and `:verbose` flags
-# to methods in FileUtils.
+# ### Comparing
#
+# * ::compare_file, ::cmp, ::identical?: Returns whether two entries are
+# identical.
+# * ::compare_stream: Returns whether two streams are identical.
+#
+#
+# ### Copying
+#
+# * ::copy_entry: Recursively copies an entry.
+# * ::copy_file: Copies an entry.
+# * ::copy_stream: Copies a stream.
+# * ::cp, ::copy: Copies files.
+# * ::cp_lr: Recursively creates hard links.
+# * ::cp_r: Recursively copies files, retaining mode, owner, and group.
+# * ::install: Recursively copies files, optionally setting mode, owner, and
+# group.
+#
+#
+# ### Moving
+#
+# * ::mv, ::move: Moves entries.
+#
+#
+# ### Options
+#
+# * ::collect_method: Returns the names of methods that accept a given option.
+# * ::commands: Returns the names of methods that accept options.
+# * ::have_option?: Returns whether a given method accepts a given option.
+# * ::options: Returns all option names.
+# * ::options_of: Returns the names of the options for a given method.
+#
+#
+# ## Path Arguments
+#
+# Some methods in FileUtils accept *path* arguments, which are interpreted as
+# paths to filesystem entries:
+#
+# * If the argument is a string, that value is the path.
+# * If the argument has method `:to_path`, it is converted via that method.
+# * If the argument has method `:to_str`, it is converted via that method.
+#
+#
+# ## About the Examples
+#
+# Some examples here involve trees of file entries. For these, we sometimes
+# display trees using the [tree command-line
+# utility](https://en.wikipedia.org/wiki/Tree_(command)), which is a recursive
+# directory-listing utility that produces a depth-indented listing of files and
+# directories.
+#
+# We use a helper method to launch the command and control the format:
+#
+# def tree(dirpath = '.')
+# command = "tree --noreport --charset=ascii #{dirpath}"
+# system(command)
+# end
+#
+# To illustrate:
+#
+# tree('src0')
+# # => src0
+# # |-- sub0
+# # | |-- src0.txt
+# # | `-- src1.txt
+# # `-- sub1
+# # |-- src2.txt
+# # `-- src3.txt
+#
+# ## Avoiding the TOCTTOU Vulnerability
+#
+# For certain methods that recursively remove entries, there is a potential
+# vulnerability called the [Time-of-check to
+# time-of-use](https://en.wikipedia.org/wiki/Time-of-check_to_time-of-use), or
+# TOCTTOU, vulnerability that can exist when:
+#
+# * An ancestor directory of the entry at the target path is world writable;
+# such directories include `/tmp`.
+# * The directory tree at the target path includes:
+#
+# * A world-writable descendant directory.
+# * A symbolic link.
+#
+#
+#
+# To avoid that vulnerability, you can use this method to remove entries:
+#
+# * FileUtils.remove_entry_secure: removes recursively if the target path
+# points to a directory.
+#
+#
+# Also available are these methods, each of which calls
+# FileUtils.remove_entry_secure:
+#
+# * FileUtils.rm_r with keyword argument `secure: true`.
+# * FileUtils.rm_rf with keyword argument `secure: true`.
+#
+#
+# Finally, this method for moving entries calls FileUtils.remove_entry_secure if
+# the source and destination are on different file systems (which means that the
+# "move" is really a copy and remove):
+#
+# * FileUtils.mv with keyword argument `secure: true`.
+#
+#
+# Method FileUtils.remove_entry_secure removes securely by applying a special
+# pre-process:
+#
+# * If the target path points to a directory, this method uses methods
+# [File#chown](rdoc-ref:File#chown) and [File#chmod](rdoc-ref:File#chmod) in
+# removing directories.
+# * The owner of the target directory should be either the current process or
+# the super user (root).
+#
+#
+# WARNING: You must ensure that **ALL** parent directories cannot be moved by
+# other untrusted users. For example, parent directories should not be owned by
+# untrusted users, and should not be world writable except when the sticky bit
+# is set.
+#
+# For details of this security vulnerability, see Perl cases:
+#
+# * [CVE-2005-0448](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2005-04
+# 48).
+# * [CVE-2004-0452](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2004-04
+# 52).
+#
module FileUtils
VERSION: String
type mode = Integer | String
@@ -107,23 +204,46 @@
# <!--
# rdoc-file=lib/fileutils.rb
# - cd(dir, verbose: nil) { |dir| ... }
# -->
- # Changes the current directory to the directory `dir`.
+ # Changes the working directory to the given `dir`, which should be
+ # [interpretable as a path](rdoc-ref:FileUtils@Path+Arguments):
#
- # If this method is called with block, resumes to the previous working directory
- # after the block execution has finished.
+ # With no block given, changes the current directory to the directory at `dir`;
+ # returns zero:
#
- # FileUtils.cd('/') # change directory
+ # FileUtils.pwd # => "/rdoc/fileutils"
+ # FileUtils.cd('..')
+ # FileUtils.pwd # => "/rdoc"
+ # FileUtils.cd('fileutils')
#
- # FileUtils.cd('/', verbose: true) # change directory and report it
+ # With a block given, changes the current directory to the directory at `dir`,
+ # calls the block with argument `dir`, and restores the original current
+ # directory; returns the block's value:
#
- # FileUtils.cd('/') do # change directory
- # # ... # do something
- # end # return to original directory
+ # FileUtils.pwd # => "/rdoc/fileutils"
+ # FileUtils.cd('..') { |arg| [arg, FileUtils.pwd] } # => ["..", "/rdoc"]
+ # FileUtils.pwd # => "/rdoc/fileutils"
#
+ # Keyword arguments:
+ #
+ # * `verbose: true` - prints an equivalent command:
+ #
+ # FileUtils.cd('..')
+ # FileUtils.cd('fileutils')
+ #
+ # Output:
+ #
+ # cd ..
+ # cd fileutils
+ #
+ #
+ # FileUtils.chdir is an alias for FileUtils.cd.
+ #
+ # Related: FileUtils.pwd.
+ #
def self?.cd: (path dir, ?verbose: boolish) -> void
| [X] (path dir, ?verbose: boolish) { (String) -> X } -> X
# <!--
# rdoc-file=lib/fileutils.rb
@@ -141,125 +261,212 @@
# <!--
# rdoc-file=lib/fileutils.rb
# - chmod(mode, list, noop: nil, verbose: nil)
# -->
- # Changes permission bits on the named files (in `list`) to the bit pattern
- # represented by `mode`.
+ # Changes permissions on the entries at the paths given in `list` (a single path
+ # or an array of paths) to the permissions given by `mode`; returns `list` if it
+ # is an array, `[list]` otherwise:
#
- # `mode` is the symbolic and absolute mode can be used.
+ # * Modifies each entry that is a regular file using
+ # [File.chmod](rdoc-ref:File.chmod).
+ # * Modifies each entry that is a symbolic link using
+ # [File.lchmod](rdoc-ref:File.lchmod).
#
- # Absolute mode is
- # FileUtils.chmod 0755, 'somecommand'
- # FileUtils.chmod 0644, %w(my.rb your.rb his.rb her.rb)
- # FileUtils.chmod 0755, '/usr/bin/ruby', verbose: true
#
- # Symbolic mode is
- # FileUtils.chmod "u=wrx,go=rx", 'somecommand'
- # FileUtils.chmod "u=wr,go=rr", %w(my.rb your.rb his.rb her.rb)
- # FileUtils.chmod "u=wrx,go=rx", '/usr/bin/ruby', verbose: true
+ # Argument `list` or its elements should be [interpretable as
+ # paths](rdoc-ref:FileUtils@Path+Arguments).
#
- # "a"
- # : is user, group, other mask.
- # "u"
- # : is user's mask.
- # "g"
- # : is group's mask.
- # "o"
- # : is other's mask.
- # "w"
- # : is write permission.
- # "r"
- # : is read permission.
- # "x"
- # : is execute permission.
- # "X"
- # : is execute permission for directories only, must be used in conjunction
- # with "+"
- # "s"
- # : is uid, gid.
- # "t"
- # : is sticky bit.
- # "+"
- # : is added to a class given the specified mode.
- # "-"
- # : Is removed from a given class given mode.
- # "="
- # : Is the exact nature of the class will be given a specified mode.
+ # Argument `mode` may be either an integer or a string:
#
+ # * Integer `mode`: represents the permission bits to be set:
+ #
+ # FileUtils.chmod(0755, 'src0.txt')
+ # FileUtils.chmod(0644, ['src0.txt', 'src0.dat'])
+ #
+ # * String `mode`: represents the permissions to be set:
+ #
+ # The string is of the form `[targets][[operator][perms[,perms]]`, where:
+ #
+ # * `targets` may be any combination of these letters:
+ #
+ # * `'u'`: permissions apply to the file's owner.
+ # * `'g'`: permissions apply to users in the file's group.
+ # * `'o'`: permissions apply to other users not in the file's group.
+ # * `'a'` (the default): permissions apply to all users.
+ #
+ #
+ # * `operator` may be one of these letters:
+ #
+ # * `'+'`: adds permissions.
+ # * `'-'`: removes permissions.
+ # * `'='`: sets (replaces) permissions.
+ #
+ #
+ # * `perms` (may be repeated, with separating commas) may be any
+ # combination of these letters:
+ #
+ # * `'r'`: Read.
+ # * `'w'`: Write.
+ # * `'x'`: Execute (search, for a directory).
+ # * `'X'`: Search (for a directories only; must be used with `'+'`)
+ # * `'s'`: Uid or gid.
+ # * `'t'`: Sticky bit.
+ #
+ #
+ #
+ # Examples:
+ #
+ # FileUtils.chmod('u=wrx,go=rx', 'src1.txt')
+ # FileUtils.chmod('u=wrx,go=rx', '/usr/bin/ruby')
+ #
+ #
+ # Keyword arguments:
+ #
+ # * `noop: true` - does not change permissions; returns `nil`.
+ # * `verbose: true` - prints an equivalent command:
+ #
+ # FileUtils.chmod(0755, 'src0.txt', noop: true, verbose: true)
+ # FileUtils.chmod(0644, ['src0.txt', 'src0.dat'], noop: true, verbose: true)
+ # FileUtils.chmod('u=wrx,go=rx', 'src1.txt', noop: true, verbose: true)
+ # FileUtils.chmod('u=wrx,go=rx', '/usr/bin/ruby', noop: true, verbose: true)
+ #
+ # Output:
+ #
+ # chmod 755 src0.txt
+ # chmod 644 src0.txt src0.dat
+ # chmod u=wrx,go=rx src1.txt
+ # chmod u=wrx,go=rx /usr/bin/ruby
+ #
+ #
+ # Related: FileUtils.chmod_R.
+ #
def self?.chmod: (mode mode, pathlist list, ?noop: boolish, ?verbose: boolish) -> void
# <!--
# rdoc-file=lib/fileutils.rb
# - chmod_R(mode, list, noop: nil, verbose: nil, force: nil)
# -->
- # Changes permission bits on the named files (in `list`) to the bit pattern
- # represented by `mode`.
+ # Like FileUtils.chmod, but changes permissions recursively.
#
- # FileUtils.chmod_R 0700, "/tmp/app.#{$$}"
- # FileUtils.chmod_R "u=wrx", "/tmp/app.#{$$}"
- #
def self?.chmod_R: (mode mode, pathlist list, ?noop: boolish, ?verbose: boolish, ?force: boolish) -> void
# <!--
# rdoc-file=lib/fileutils.rb
# - chown(user, group, list, noop: nil, verbose: nil)
# -->
- # Changes owner and group on the named files (in `list`) to the user `user` and
- # the group `group`. `user` and `group` may be an ID (Integer/String) or a name
- # (String). If `user` or `group` is nil, this method does not change the
- # attribute.
+ # Changes the owner and group on the entries at the paths given in `list` (a
+ # single path or an array of paths) to the given `user` and `group`; returns
+ # `list` if it is an array, `[list]` otherwise:
#
- # FileUtils.chown 'root', 'staff', '/usr/local/bin/ruby'
- # FileUtils.chown nil, 'bin', Dir.glob('/usr/bin/*'), verbose: true
+ # * Modifies each entry that is a regular file using
+ # [File.chown](rdoc-ref:File.chown).
+ # * Modifies each entry that is a symbolic link using
+ # [File.lchown](rdoc-ref:File.lchown).
#
+ #
+ # Argument `list` or its elements should be [interpretable as
+ # paths](rdoc-ref:FileUtils@Path+Arguments).
+ #
+ # User and group:
+ #
+ # * Argument `user` may be a user name or a user id; if `nil` or `-1`, the
+ # user is not changed.
+ # * Argument `group` may be a group name or a group id; if `nil` or `-1`, the
+ # group is not changed.
+ # * The user must be a member of the group.
+ #
+ #
+ # Examples:
+ #
+ # # One path.
+ # # User and group as string names.
+ # File.stat('src0.txt').uid # => 1004
+ # File.stat('src0.txt').gid # => 1004
+ # FileUtils.chown('user2', 'group1', 'src0.txt')
+ # File.stat('src0.txt').uid # => 1006
+ # File.stat('src0.txt').gid # => 1005
+ #
+ # # User and group as uid and gid.
+ # FileUtils.chown(1004, 1004, 'src0.txt')
+ # File.stat('src0.txt').uid # => 1004
+ # File.stat('src0.txt').gid # => 1004
+ #
+ # # Array of paths.
+ # FileUtils.chown(1006, 1005, ['src0.txt', 'src0.dat'])
+ #
+ # # Directory (not recursive).
+ # FileUtils.chown('user2', 'group1', '.')
+ #
+ # Keyword arguments:
+ #
+ # * `noop: true` - does not change permissions; returns `nil`.
+ # * `verbose: true` - prints an equivalent command:
+ #
+ # FileUtils.chown('user2', 'group1', 'src0.txt', noop: true, verbose: true)
+ # FileUtils.chown(1004, 1004, 'src0.txt', noop: true, verbose: true)
+ # FileUtils.chown(1006, 1005, ['src0.txt', 'src0.dat'], noop: true, verbose: true)
+ # FileUtils.chown('user2', 'group1', path, noop: true, verbose: true)
+ # FileUtils.chown('user2', 'group1', '.', noop: true, verbose: true)
+ #
+ # Output:
+ #
+ # chown user2:group1 src0.txt
+ # chown 1004:1004 src0.txt
+ # chown 1006:1005 src0.txt src0.dat
+ # chown user2:group1 src0.txt
+ # chown user2:group1 .
+ #
+ #
+ # Related: FileUtils.chown_R.
+ #
def self?.chown: (String? user, String? group, pathlist list, ?noop: boolish, ?verbose: boolish) -> void
# <!--
# rdoc-file=lib/fileutils.rb
# - chown_R(user, group, list, noop: nil, verbose: nil, force: nil)
# -->
- # Changes owner and group on the named files (in `list`) to the user `user` and
- # the group `group` recursively. `user` and `group` may be an ID
- # (Integer/String) or a name (String). If `user` or `group` is nil, this method
- # does not change the attribute.
+ # Like FileUtils.chown, but changes owner and group recursively.
#
- # FileUtils.chown_R 'www', 'www', '/var/www/htdocs'
- # FileUtils.chown_R 'cvs', 'cvs', '/var/cvs', verbose: true
- #
def self?.chown_R: (String? user, String? group, pathlist list, ?noop: boolish, ?verbose: boolish, ?force: boolish) -> void
# <!--
# rdoc-file=lib/fileutils.rb
# - collect_method(opt)
# -->
- # Returns an Array of methods names which have the option `opt`.
+ # Returns an array of the string method names of the methods that accept the
+ # given keyword option `opt`; the argument must be a symbol:
#
- # p FileUtils.collect_method(:preserve) #=> ["cp", "cp_r", "copy", "install"]
+ # FileUtils.collect_method(:preserve) # => ["cp", "copy", "cp_r", "install"]
#
def self.collect_method: (Symbol opt) -> Array[String]
# <!--
# rdoc-file=lib/fileutils.rb
# - commands()
# -->
- # Returns an Array of names of high-level methods that accept any keyword
- # arguments.
+ # Returns an array of the string names of FileUtils methods that accept one or
+ # more keyword arguments:
#
- # p FileUtils.commands #=> ["chmod", "cp", "cp_r", "install", ...]
+ # FileUtils.commands.sort.take(3) # => ["cd", "chdir", "chmod"]
#
def self.commands: () -> Array[String]
# <!--
# rdoc-file=lib/fileutils.rb
# - compare_file(a, b)
# -->
- # Returns true if the contents of a file `a` and a file `b` are identical.
+ # Returns `true` if the contents of files `a` and `b` are identical, `false`
+ # otherwise.
#
- # FileUtils.compare_file('somefile', 'somefile') #=> true
- # FileUtils.compare_file('/dev/null', '/dev/urandom') #=> false
+ # Arguments `a` and `b` should be [interpretable as a
+ # path](rdoc-ref:FileUtils@Path+Arguments).
#
+ # FileUtils.identical? and FileUtils.cmp are aliases for FileUtils.compare_file.
+ #
+ # Related: FileUtils.compare_stream.
+ #
def self?.compare_file: (path a, path b) -> bool
# <!--
# rdoc-file=lib/fileutils.rb
# - cmp(a, b)
@@ -290,67 +497,167 @@
# <!--
# rdoc-file=lib/fileutils.rb
# - compare_stream(a, b)
# -->
- # 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.
#
+ # Arguments `a` and `b` should be [interpretable as a
+ # path](rdoc-ref:FileUtils@Path+Arguments).
+ #
+ # Related: FileUtils.compare_file.
+ #
def self?.compare_stream: (IO a, IO b) -> bool
# <!--
# rdoc-file=lib/fileutils.rb
# - copy_entry(src, dest, preserve = false, dereference_root = false, remove_destination = false)
# -->
- # Copies a file system entry `src` to `dest`. If `src` is a directory, this
- # method copies its contents recursively. This method preserves file types, c.f.
- # symlink, directory... (FIFO, device files and etc. are not supported yet)
+ # Recursively copies files from `src` to `dest`.
#
- # Both of `src` and `dest` must be a path name. `src` must exist, `dest` must
- # not exist.
+ # Arguments `src` and `dest` should be [interpretable as
+ # paths](rdoc-ref:FileUtils@Path+Arguments).
#
- # If `preserve` is true, this method preserves owner, group, and modified time.
- # Permissions are copied regardless `preserve`.
+ # If `src` is the path to a file, copies `src` to `dest`:
#
- # If `dereference_root` is true, this method dereference tree root.
+ # FileUtils.touch('src0.txt')
+ # File.exist?('dest0.txt') # => false
+ # FileUtils.copy_entry('src0.txt', 'dest0.txt')
+ # File.file?('dest0.txt') # => true
#
- # If `remove_destination` is true, this method removes each destination file
- # before copy.
+ # If `src` is a directory, recursively copies `src` to `dest`:
#
+ # tree('src1')
+ # # => src1
+ # # |-- dir0
+ # # | |-- src0.txt
+ # # | `-- src1.txt
+ # # `-- dir1
+ # # |-- src2.txt
+ # # `-- src3.txt
+ # FileUtils.copy_entry('src1', 'dest1')
+ # tree('dest1')
+ # # => dest1
+ # # |-- dir0
+ # # | |-- src0.txt
+ # # | `-- src1.txt
+ # # `-- dir1
+ # # |-- src2.txt
+ # # `-- src3.txt
+ #
+ # The recursive copying preserves file types for regular files, directories, and
+ # symbolic links; other file types (FIFO streams, device files, etc.) are not
+ # supported.
+ #
+ # Keyword arguments:
+ #
+ # * `dereference_root: true` - if `src` is a symbolic link, follows the link.
+ # * `preserve: true` - preserves file times.
+ # * `remove_destination: true` - removes `dest` before copying files.
+ #
+ #
+ # Related: [methods for copying](rdoc-ref:FileUtils@Copying).
+ #
def self?.copy_entry: (path src, path dest, ?boolish preserve, ?boolish dereference_root, ?boolish remove_destination) -> void
# <!--
# rdoc-file=lib/fileutils.rb
# - copy_file(src, dest, preserve = false, dereference = true)
# -->
- # Copies file contents of `src` to `dest`. Both of `src` and `dest` must be a
- # path name.
+ # Copies file from `src` to `dest`, which should not be directories.
#
+ # Arguments `src` and `dest` should be [interpretable as
+ # paths](rdoc-ref:FileUtils@Path+Arguments).
+ #
+ # Examples:
+ #
+ # FileUtils.touch('src0.txt')
+ # FileUtils.copy_file('src0.txt', 'dest0.txt')
+ # File.file?('dest0.txt') # => true
+ #
+ # Keyword arguments:
+ #
+ # * `dereference: false` - if `src` is a symbolic link, does not follow the
+ # link.
+ # * `preserve: true` - preserves file times.
+ # * `remove_destination: true` - removes `dest` before copying files.
+ #
+ #
+ # Related: [methods for copying](rdoc-ref:FileUtils@Copying).
+ #
def self?.copy_file: (path src, path dest, ?boolish preserve, ?boolish dereference) -> void
# <!--
# rdoc-file=lib/fileutils.rb
# - copy_stream(src, dest)
# -->
- # Copies stream `src` to `dest`. `src` must respond to #read(n) and `dest` must
- # respond to #write(str).
+ # Copies IO stream `src` to IO stream `dest` via
+ # [IO.copy_stream](rdoc-ref:IO.copy_stream).
#
+ # Related: [methods for copying](rdoc-ref:FileUtils@Copying).
+ #
def self?.copy_stream: (_Reader src, _Writer dest) -> void
# <!--
# rdoc-file=lib/fileutils.rb
# - cp(src, dest, preserve: nil, noop: nil, verbose: nil)
# -->
- # Copies a file content `src` to `dest`. If `dest` is a directory, copies `src`
- # to `dest/src`.
+ # Copies files.
#
- # If `src` is a list of files, then `dest` must be a directory.
+ # Arguments `src` (a single path or an array of paths) and `dest` (a single
+ # path) should be [interpretable as paths](rdoc-ref:FileUtils@Path+Arguments).
#
- # FileUtils.cp 'eval.c', 'eval.c.org'
- # FileUtils.cp %w(cgi.rb complex.rb date.rb), '/usr/lib/ruby/1.6'
- # FileUtils.cp %w(cgi.rb complex.rb date.rb), '/usr/lib/ruby/1.6', verbose: true
- # FileUtils.cp 'symlink', 'dest' # copy content, "dest" is not a symlink
+ # If `src` is the path to a file and `dest` is not the path to a directory,
+ # copies `src` to `dest`:
#
+ # FileUtils.touch('src0.txt')
+ # File.exist?('dest0.txt') # => false
+ # FileUtils.cp('src0.txt', 'dest0.txt')
+ # File.file?('dest0.txt') # => true
+ #
+ # If `src` is the path to a file and `dest` is the path to a directory, copies
+ # `src` to `dest/src`:
+ #
+ # FileUtils.touch('src1.txt')
+ # FileUtils.mkdir('dest1')
+ # FileUtils.cp('src1.txt', 'dest1')
+ # File.file?('dest1/src1.txt') # => true
+ #
+ # If `src` is an array of paths to files and `dest` is the path to a directory,
+ # copies from each `src` to `dest`:
+ #
+ # src_file_paths = ['src2.txt', 'src2.dat']
+ # FileUtils.touch(src_file_paths)
+ # FileUtils.mkdir('dest2')
+ # FileUtils.cp(src_file_paths, 'dest2')
+ # File.file?('dest2/src2.txt') # => true
+ # File.file?('dest2/src2.dat') # => true
+ #
+ # Keyword arguments:
+ #
+ # * `preserve: true` - preserves file times.
+ # * `noop: true` - does not copy files.
+ # * `verbose: true` - prints an equivalent command:
+ #
+ # FileUtils.cp('src0.txt', 'dest0.txt', noop: true, verbose: true)
+ # FileUtils.cp('src1.txt', 'dest1', noop: true, verbose: true)
+ # FileUtils.cp(src_file_paths, 'dest2', noop: true, verbose: true)
+ #
+ # Output:
+ #
+ # cp src0.txt dest0.txt
+ # cp src1.txt dest1
+ # cp src2.txt src2.dat dest2
+ #
+ #
+ # Raises an exception if `src` is a directory.
+ #
+ # FileUtils.copy is an alias for FileUtils.cp.
+ #
+ # Related: [methods for copying](rdoc-ref:FileUtils@Copying).
+ #
def self?.cp: (pathlist src, path dest, ?preserve: boolish, ?noop: boolish, ?verbose: boolish) -> void
# <!--
# rdoc-file=lib/fileutils.rb
# - copy(src, dest, preserve: nil, noop: nil, verbose: nil)
@@ -367,126 +674,404 @@
# <!--
# rdoc-file=lib/fileutils.rb
# - cp_lr(src, dest, noop: nil, verbose: nil, dereference_root: true, remove_destination: false)
# -->
- # Hard link `src` to `dest`. If `src` is a directory, this method links all its
- # contents recursively. If `dest` is a directory, links `src` to `dest/src`.
+ # Creates [hard links](https://en.wikipedia.org/wiki/Hard_link).
#
- # `src` can be a list of files.
+ # Arguments `src` (a single path or an array of paths) and `dest` (a single
+ # path) should be [interpretable as paths](rdoc-ref:FileUtils@Path+Arguments).
#
- # If `dereference_root` is true, this method dereference tree root.
+ # If `src` is the path to a directory and `dest` does not exist, creates links
+ # `dest` and descendents pointing to `src` and its descendents:
#
- # If `remove_destination` is true, this method removes each destination file
- # before copy.
+ # tree('src0')
+ # # => src0
+ # # |-- sub0
+ # # | |-- src0.txt
+ # # | `-- src1.txt
+ # # `-- sub1
+ # # |-- src2.txt
+ # # `-- src3.txt
+ # File.exist?('dest0') # => false
+ # FileUtils.cp_lr('src0', 'dest0')
+ # tree('dest0')
+ # # => dest0
+ # # |-- sub0
+ # # | |-- src0.txt
+ # # | `-- src1.txt
+ # # `-- sub1
+ # # |-- src2.txt
+ # # `-- src3.txt
#
- # FileUtils.rm_r site_ruby + '/mylib', force: true
- # FileUtils.cp_lr 'lib/', site_ruby + '/mylib'
+ # If `src` and `dest` are both paths to directories, creates links `dest/src`
+ # and descendents pointing to `src` and its descendents:
#
- # # Examples of linking several files to target directory.
- # FileUtils.cp_lr %w(mail.rb field.rb debug/), site_ruby + '/tmail'
- # FileUtils.cp_lr Dir.glob('*.rb'), '/home/aamine/lib/ruby', noop: true, verbose: true
+ # tree('src1')
+ # # => src1
+ # # |-- sub0
+ # # | |-- src0.txt
+ # # | `-- src1.txt
+ # # `-- sub1
+ # # |-- src2.txt
+ # # `-- src3.txt
+ # FileUtils.mkdir('dest1')
+ # FileUtils.cp_lr('src1', 'dest1')
+ # tree('dest1')
+ # # => dest1
+ # # `-- src1
+ # # |-- sub0
+ # # | |-- src0.txt
+ # # | `-- src1.txt
+ # # `-- sub1
+ # # |-- src2.txt
+ # # `-- src3.txt
#
- # # If you want to link all contents of a directory instead of the
- # # directory itself, c.f. src/x -> dest/x, src/y -> dest/y,
- # # use the following code.
- # FileUtils.cp_lr 'src/.', 'dest' # cp_lr('src', 'dest') makes dest/src, but this doesn't.
+ # If `src` is an array of paths to entries and `dest` is the path to a
+ # directory, for each path `filepath` in `src`, creates a link at
+ # `dest/filepath` pointing to that path:
#
+ # tree('src2')
+ # # => src2
+ # # |-- sub0
+ # # | |-- src0.txt
+ # # | `-- src1.txt
+ # # `-- sub1
+ # # |-- src2.txt
+ # # `-- src3.txt
+ # FileUtils.mkdir('dest2')
+ # FileUtils.cp_lr(['src2/sub0', 'src2/sub1'], 'dest2')
+ # tree('dest2')
+ # # => dest2
+ # # |-- sub0
+ # # | |-- src0.txt
+ # # | `-- src1.txt
+ # # `-- sub1
+ # # |-- src2.txt
+ # # `-- src3.txt
+ #
+ # Keyword arguments:
+ #
+ # * `dereference_root: false` - if `src` is a symbolic link, does not
+ # dereference it.
+ # * `noop: true` - does not create links.
+ # * `remove_destination: true` - removes `dest` before creating links.
+ # * `verbose: true` - prints an equivalent command:
+ #
+ # FileUtils.cp_lr('src0', 'dest0', noop: true, verbose: true)
+ # FileUtils.cp_lr('src1', 'dest1', noop: true, verbose: true)
+ # FileUtils.cp_lr(['src2/sub0', 'src2/sub1'], 'dest2', noop: true, verbose: true)
+ #
+ # Output:
+ #
+ # cp -lr src0 dest0
+ # cp -lr src1 dest1
+ # cp -lr src2/sub0 src2/sub1 dest2
+ #
+ #
+ # Raises an exception if `dest` is the path to an existing file or directory and
+ # keyword argument `remove_destination: true` is not given.
+ #
+ # Related: [methods for copying](rdoc-ref:FileUtils@Copying).
+ #
def self?.cp_lr: (pathlist src, path dest, ?noop: boolish, ?verbose: boolish, ?dereference_root: boolish, ?remove_destination: boolish) -> void
# <!--
# rdoc-file=lib/fileutils.rb
# - cp_r(src, dest, preserve: nil, noop: nil, verbose: nil, dereference_root: true, remove_destination: nil)
# -->
- # Copies `src` to `dest`. If `src` is a directory, this method copies all its
- # contents recursively. If `dest` is a directory, copies `src` to `dest/src`.
+ # Recursively copies files.
#
- # `src` can be a list of files.
+ # Arguments `src` (a single path or an array of paths) and `dest` (a single
+ # path) should be [interpretable as paths](rdoc-ref:FileUtils@Path+Arguments).
#
- # If `dereference_root` is true, this method dereference tree root.
+ # The mode, owner, and group are retained in the copy; to change those, use
+ # FileUtils.install instead.
#
- # If `remove_destination` is true, this method removes each destination file
- # before copy.
+ # If `src` is the path to a file and `dest` is not the path to a directory,
+ # copies `src` to `dest`:
#
- # # Installing Ruby library "mylib" under the site_ruby
- # FileUtils.rm_r site_ruby + '/mylib', force: true
- # FileUtils.cp_r 'lib/', site_ruby + '/mylib'
+ # FileUtils.touch('src0.txt')
+ # File.exist?('dest0.txt') # => false
+ # FileUtils.cp_r('src0.txt', 'dest0.txt')
+ # File.file?('dest0.txt') # => true
#
- # # Examples of copying several files to target directory.
- # FileUtils.cp_r %w(mail.rb field.rb debug/), site_ruby + '/tmail'
- # FileUtils.cp_r Dir.glob('*.rb'), '/home/foo/lib/ruby', noop: true, verbose: true
+ # If `src` is the path to a file and `dest` is the path to a directory, copies
+ # `src` to `dest/src`:
#
- # # If you want to copy all contents of a directory instead of the
- # # directory itself, c.f. src/x -> dest/x, src/y -> dest/y,
- # # use following code.
- # FileUtils.cp_r 'src/.', 'dest' # cp_r('src', 'dest') makes dest/src,
- # # but this doesn't.
+ # FileUtils.touch('src1.txt')
+ # FileUtils.mkdir('dest1')
+ # FileUtils.cp_r('src1.txt', 'dest1')
+ # File.file?('dest1/src1.txt') # => true
#
+ # If `src` is the path to a directory and `dest` does not exist, recursively
+ # copies `src` to `dest`:
+ #
+ # tree('src2')
+ # # => src2
+ # # |-- dir0
+ # # | |-- src0.txt
+ # # | `-- src1.txt
+ # # `-- dir1
+ # # |-- src2.txt
+ # # `-- src3.txt
+ # FileUtils.exist?('dest2') # => false
+ # FileUtils.cp_r('src2', 'dest2')
+ # tree('dest2')
+ # # => dest2
+ # # |-- dir0
+ # # | |-- src0.txt
+ # # | `-- src1.txt
+ # # `-- dir1
+ # # |-- src2.txt
+ # # `-- src3.txt
+ #
+ # If `src` and `dest` are paths to directories, recursively copies `src` to
+ # `dest/src`:
+ #
+ # tree('src3')
+ # # => src3
+ # # |-- dir0
+ # # | |-- src0.txt
+ # # | `-- src1.txt
+ # # `-- dir1
+ # # |-- src2.txt
+ # # `-- src3.txt
+ # FileUtils.mkdir('dest3')
+ # FileUtils.cp_r('src3', 'dest3')
+ # tree('dest3')
+ # # => dest3
+ # # `-- src3
+ # # |-- dir0
+ # # | |-- src0.txt
+ # # | `-- src1.txt
+ # # `-- dir1
+ # # |-- src2.txt
+ # # `-- src3.txt
+ #
+ # If `src` is an array of paths and `dest` is a directory, recursively copies
+ # from each path in `src` to `dest`; the paths in `src` may point to files
+ # and/or directories.
+ #
+ # Keyword arguments:
+ #
+ # * `dereference_root: false` - if `src` is a symbolic link, does not
+ # dereference it.
+ # * `noop: true` - does not copy files.
+ # * `preserve: true` - preserves file times.
+ # * `remove_destination: true` - removes `dest` before copying files.
+ # * `verbose: true` - prints an equivalent command:
+ #
+ # FileUtils.cp_r('src0.txt', 'dest0.txt', noop: true, verbose: true)
+ # FileUtils.cp_r('src1.txt', 'dest1', noop: true, verbose: true)
+ # FileUtils.cp_r('src2', 'dest2', noop: true, verbose: true)
+ # FileUtils.cp_r('src3', 'dest3', noop: true, verbose: true)
+ #
+ # Output:
+ #
+ # cp -r src0.txt dest0.txt
+ # cp -r src1.txt dest1
+ # cp -r src2 dest2
+ # cp -r src3 dest3
+ #
+ #
+ # Raises an exception of `src` is the path to a directory and `dest` is the path
+ # to a file.
+ #
+ # Related: [methods for copying](rdoc-ref:FileUtils@Copying).
+ #
def self?.cp_r: (pathlist src, path dest, ?preserve: boolish, ?noop: boolish, ?verbose: boolish, ?dereference_root: boolish, ?remove_destination: boolish) -> void
# <!--
# rdoc-file=lib/fileutils.rb
# - have_option?(mid, opt)
# -->
- # Returns true if the method `mid` have an option `opt`.
+ # Returns `true` if method `mid` accepts the given option `opt`, `false`
+ # otherwise; the arguments may be strings or symbols:
#
- # p FileUtils.have_option?(:cp, :noop) #=> true
- # p FileUtils.have_option?(:rm, :force) #=> true
- # p FileUtils.have_option?(:rm, :preserve) #=> false
+ # FileUtils.have_option?(:chmod, :noop) # => true
+ # FileUtils.have_option?('chmod', 'secure') # => false
#
def self.have_option?: (Symbol mid, Symbol opt) -> bool
# <!--
# rdoc-file=lib/fileutils.rb
# - install(src, dest, mode: nil, owner: nil, group: nil, preserve: nil, noop: nil, verbose: nil)
# -->
- # 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.
+ # Copies a file entry. See
+ # [install(1)](https://man7.org/linux/man-pages/man1/install.1.html).
#
- # FileUtils.install 'ruby', '/usr/local/bin/ruby', mode: 0755, verbose: true
- # FileUtils.install 'lib.rb', '/usr/local/lib/ruby/site_ruby', verbose: true
+ # Arguments `src` (a single path or an array of paths) and `dest` (a single
+ # path) should be [interpretable as paths](rdoc-ref:FileUtils@Path+Arguments);
#
+ # 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:
+ #
+ # 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 `dest/src`, 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"
+ #
+ # If `src` is an array of paths and `dest` points to a directory, copies each
+ # path `path` in `src` to `dest/path`:
+ #
+ # File.file?('src3.txt') # => true
+ # File.file?('src3.dat') # => true
+ # FileUtils.mkdir('dest3')
+ # FileUtils.install(['src3.txt', 'src3.dat'], 'dest3')
+ # File.file?('dest3/src3.txt') # => true
+ # File.file?('dest3/src3.dat') # => true
+ #
+ # Keyword arguments:
+ #
+ # * `group: *group`* - changes the group if not `nil`, using
+ # [File.chown](rdoc-ref:File.chown).
+ # * `mode: *permissions`* - changes the permissions. using
+ # [File.chmod](rdoc-ref:File.chmod).
+ # * `noop: true` - does not copy entries; returns `nil`.
+ # * `owner: *owner`* - changes the owner if not `nil`, using
+ # [File.chown](rdoc-ref:File.chown).
+ # * `preserve: true` - preserve timestamps using
+ # [File.utime](rdoc-ref:File.utime).
+ # * `verbose: true` - 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:
+ #
+ # install -c src0.txt dest0.txt
+ # install -c src1.txt dest1.txt
+ # install -c src2.txt dest2
+ #
+ #
+ # Related: [methods for copying](rdoc-ref:FileUtils@Copying).
+ #
def self?.install: (path src, path dest, ?mode: mode?, ?owner: String?, ?group: String?, ?preserve: boolish, ?noop: boolish, ?verbose: boolish) -> void
# <!--
# rdoc-file=lib/fileutils.rb
# - link_entry(src, dest, dereference_root = false, remove_destination = false)
# -->
- # Hard links a file system entry `src` to `dest`. If `src` is a directory, this
- # method links its contents recursively.
+ # Creates [hard links](https://en.wikipedia.org/wiki/Hard_link); returns `nil`.
#
- # Both of `src` and `dest` must be a path name. `src` must exist, `dest` must
- # not exist.
+ # Arguments `src` and `dest` should be [interpretable as
+ # paths](rdoc-ref:FileUtils@Path+Arguments).
#
- # If `dereference_root` is true, this method dereferences the tree root.
+ # If `src` is the path to a file and `dest` does not exist, creates a hard link
+ # at `dest` pointing to `src`:
#
- # If `remove_destination` is true, this method removes each destination file
- # before copy.
+ # FileUtils.touch('src0.txt')
+ # File.exist?('dest0.txt') # => false
+ # FileUtils.link_entry('src0.txt', 'dest0.txt')
+ # File.file?('dest0.txt') # => true
#
+ # If `src` is the path to a directory and `dest` does not exist, recursively
+ # creates hard links at `dest` pointing to paths in `src`:
+ #
+ # FileUtils.mkdir_p(['src1/dir0', 'src1/dir1'])
+ # src_file_paths = [
+ # 'src1/dir0/t0.txt',
+ # 'src1/dir0/t1.txt',
+ # 'src1/dir1/t2.txt',
+ # 'src1/dir1/t3.txt',
+ # ]
+ # FileUtils.touch(src_file_paths)
+ # File.directory?('dest1') # => true
+ # FileUtils.link_entry('src1', 'dest1')
+ # File.file?('dest1/dir0/t0.txt') # => true
+ # File.file?('dest1/dir0/t1.txt') # => true
+ # File.file?('dest1/dir1/t2.txt') # => true
+ # File.file?('dest1/dir1/t3.txt') # => true
+ #
+ # Keyword arguments:
+ #
+ # * `dereference_root: true` - dereferences `src` if it is a symbolic link.
+ # * `remove_destination: true` - removes `dest` before creating links.
+ #
+ #
+ # Raises an exception if `dest` is the path to an existing file or directory and
+ # keyword argument `remove_destination: true` is not given.
+ #
+ # Related: FileUtils.ln (has different options).
+ #
def self?.link_entry: (path src, path dest, ?boolish dereference_root, ?boolish remove_destination) -> void
# <!--
# rdoc-file=lib/fileutils.rb
- # - FileUtils.ln(target, link, force: nil, noop: nil, verbose: nil)
- # - FileUtils.ln(target, dir, force: nil, noop: nil, verbose: nil)
- # - FileUtils.ln(targets, dir, force: nil, noop: nil, verbose: nil)
+ # - ln(src, dest, force: nil, noop: nil, verbose: nil)
# -->
- # In the first form, creates a hard link `link` which points to `target`. If
- # `link` already exists, raises Errno::EEXIST. But if the `force` option is set,
- # overwrites `link`.
+ # Creates [hard links](https://en.wikipedia.org/wiki/Hard_link).
#
- # FileUtils.ln 'gcc', 'cc', verbose: true
- # FileUtils.ln '/usr/bin/emacs21', '/usr/bin/emacs'
+ # Arguments `src` (a single path or an array of paths) and `dest` (a single
+ # path) should be [interpretable as paths](rdoc-ref:FileUtils@Path+Arguments).
#
- # In the second form, creates a link `dir/target` pointing to `target`. In the
- # third form, creates several hard links in the directory `dir`, pointing to
- # each item in `targets`. If `dir` is not a directory, raises Errno::ENOTDIR.
+ # When `src` is the path to an existing file and `dest` is the path to a
+ # non-existent file, creates a hard link at `dest` pointing to `src`; returns
+ # zero:
#
- # FileUtils.cd '/sbin'
- # FileUtils.ln %w(cp mv mkdir), '/bin' # Now /sbin/cp and /bin/cp are linked.
+ # Dir.children('tmp0/') # => ["t.txt"]
+ # Dir.children('tmp1/') # => []
+ # FileUtils.ln('tmp0/t.txt', 'tmp1/t.lnk') # => 0
+ # Dir.children('tmp1/') # => ["t.lnk"]
#
+ # When `src` is the path to an existing file and `dest` is the path to an
+ # existing directory, creates a hard link at `dest/src` pointing to `src`;
+ # returns zero:
+ #
+ # Dir.children('tmp2') # => ["t.dat"]
+ # Dir.children('tmp3') # => []
+ # FileUtils.ln('tmp2/t.dat', 'tmp3') # => 0
+ # Dir.children('tmp3') # => ["t.dat"]
+ #
+ # When `src` is an array of paths to existing files and `dest` is the path to an
+ # existing directory, then for each path `target` in `src`, creates a hard link
+ # at `dest/target` pointing to `target`; returns `src`:
+ #
+ # Dir.children('tmp4/') # => []
+ # FileUtils.ln(['tmp0/t.txt', 'tmp2/t.dat'], 'tmp4/') # => ["tmp0/t.txt", "tmp2/t.dat"]
+ # Dir.children('tmp4/') # => ["t.dat", "t.txt"]
+ #
+ # Keyword arguments:
+ #
+ # * `force: true` - overwrites `dest` if it exists.
+ # * `noop: true` - does not create links.
+ # * `verbose: true` - prints an equivalent command:
+ #
+ # FileUtils.ln('tmp0/t.txt', 'tmp1/t.lnk', verbose: true)
+ # FileUtils.ln('tmp2/t.dat', 'tmp3', verbose: true)
+ # FileUtils.ln(['tmp0/t.txt', 'tmp2/t.dat'], 'tmp4/', verbose: true)
+ #
+ # Output:
+ #
+ # ln tmp0/t.txt tmp1/t.lnk
+ # ln tmp2/t.dat tmp3
+ # ln tmp0/t.txt tmp2/t.dat tmp4/
+ #
+ #
+ # Raises an exception if `dest` is the path to an existing file and keyword
+ # argument `force` is not `true`.
+ #
+ # FileUtils#link is an alias for FileUtils#ln.
+ #
+ # Related: FileUtils.link_entry (has different options).
+ #
def self?.ln: (pathlist src, path dest, ?force: boolish, ?noop: boolish, ?verbose: boolish) -> void
# <!--
# rdoc-file=lib/fileutils.rb
# - link(src, dest, force: nil, noop: nil, verbose: nil)
@@ -501,84 +1086,194 @@
#
alias link ln
# <!--
# rdoc-file=lib/fileutils.rb
- # - FileUtils.ln_s(target, link, force: nil, noop: nil, verbose: nil)
- # - FileUtils.ln_s(target, dir, force: nil, noop: nil, verbose: nil)
- # - FileUtils.ln_s(targets, dir, force: nil, noop: nil, verbose: nil)
+ # - ln_s(src, dest, force: nil, relative: false, target_directory: true, noop: nil, verbose: nil)
# -->
- # In the first form, creates a symbolic link `link` which points to `target`. If
- # `link` already exists, raises Errno::EEXIST. But if the `force` option is set,
- # overwrites `link`.
+ # Creates [symbolic links](https://en.wikipedia.org/wiki/Symbolic_link).
#
- # FileUtils.ln_s '/usr/bin/ruby', '/usr/local/bin/ruby'
- # FileUtils.ln_s 'verylongsourcefilename.c', 'c', force: true
+ # Arguments `src` (a single path or an array of paths) and `dest` (a single
+ # path) should be [interpretable as paths](rdoc-ref:FileUtils@Path+Arguments).
#
- # In the second form, creates a link `dir/target` pointing to `target`. In the
- # third form, creates several symbolic links in the directory `dir`, pointing to
- # each item in `targets`. If `dir` is not a directory, raises Errno::ENOTDIR.
+ # If `src` is the path to an existing file:
#
- # FileUtils.ln_s Dir.glob('/bin/*.rb'), '/home/foo/bin'
+ # * When `dest` is the path to a non-existent file, creates a symbolic link at
+ # `dest` pointing to `src`:
#
- def self?.ln_s: (pathlist src, path dest, ?force: boolish, ?noop: boolish, ?verbose: boolish) -> void
+ # FileUtils.touch('src0.txt')
+ # File.exist?('dest0.txt') # => false
+ # FileUtils.ln_s('src0.txt', 'dest0.txt')
+ # File.symlink?('dest0.txt') # => true
+ #
+ # * When `dest` is the path to an existing file, creates a symbolic link at
+ # `dest` pointing to `src` if and only if keyword argument `force: true` is
+ # given (raises an exception otherwise):
+ #
+ # FileUtils.touch('src1.txt')
+ # FileUtils.touch('dest1.txt')
+ # FileUtils.ln_s('src1.txt', 'dest1.txt', force: true)
+ # FileTest.symlink?('dest1.txt') # => true
+ #
+ # FileUtils.ln_s('src1.txt', 'dest1.txt') # Raises Errno::EEXIST.
+ #
+ #
+ # If `dest` is the path to a directory, creates a symbolic link at `dest/src`
+ # pointing to `src`:
+ #
+ # FileUtils.touch('src2.txt')
+ # FileUtils.mkdir('destdir2')
+ # FileUtils.ln_s('src2.txt', 'destdir2')
+ # File.symlink?('destdir2/src2.txt') # => true
+ #
+ # If `src` is an array of paths to existing files and `dest` is a directory, for
+ # each child `child` in `src` creates a symbolic link `dest/child` pointing to
+ # `child`:
+ #
+ # FileUtils.mkdir('srcdir3')
+ # FileUtils.touch('srcdir3/src0.txt')
+ # FileUtils.touch('srcdir3/src1.txt')
+ # FileUtils.mkdir('destdir3')
+ # FileUtils.ln_s(['srcdir3/src0.txt', 'srcdir3/src1.txt'], 'destdir3')
+ # File.symlink?('destdir3/src0.txt') # => true
+ # File.symlink?('destdir3/src1.txt') # => true
+ #
+ # Keyword arguments:
+ #
+ # * `force: true` - overwrites `dest` if it exists.
+ # * `relative: false` - create links relative to `dest`.
+ # * `noop: true` - does not create links.
+ # * `verbose: true` - prints an equivalent command:
+ #
+ # FileUtils.ln_s('src0.txt', 'dest0.txt', noop: true, verbose: true)
+ # FileUtils.ln_s('src1.txt', 'destdir1', noop: true, verbose: true)
+ # FileUtils.ln_s('src2.txt', 'dest2.txt', force: true, noop: true, verbose: true)
+ # FileUtils.ln_s(['srcdir3/src0.txt', 'srcdir3/src1.txt'], 'destdir3', noop: true, verbose: true)
+ #
+ # Output:
+ #
+ # ln -s src0.txt dest0.txt
+ # ln -s src1.txt destdir1
+ # ln -sf src2.txt dest2.txt
+ # ln -s srcdir3/src0.txt srcdir3/src1.txt destdir3
+ #
+ #
+ # FileUtils.symlink is an alias for FileUtils.ln_s.
+ #
+ # Related: FileUtils.ln_sf.
+ #
+ def self?.ln_s: (pathlist src, path dest, ?force: boolish, ?relative: boolish, ?target_directory: boolish, ?noop: boolish, ?verbose: boolish) -> void
# <!--
# rdoc-file=lib/fileutils.rb
- # - symlink(src, dest, force: nil, noop: nil, verbose: nil)
+ # - symlink(src, dest, force: nil, relative: false, target_directory: true, noop: nil, verbose: nil)
# -->
#
alias self.symlink self.ln_s
# <!--
# rdoc-file=lib/fileutils.rb
- # - symlink(src, dest, force: nil, noop: nil, verbose: nil)
+ # - symlink(src, dest, force: nil, relative: false, target_directory: true, noop: nil, verbose: nil)
# -->
#
alias symlink ln_s
# <!--
# rdoc-file=lib/fileutils.rb
- # - FileUtils.ln_sf(*args)
+ # - ln_sf(src, dest, noop: nil, verbose: nil)
# -->
- # Same as
+ # Like FileUtils.ln_s, but always with keyword argument `force: true` given.
#
- # FileUtils.ln_s(*args, force: true)
- #
def self?.ln_sf: (pathlist src, path dest, ?noop: boolish, ?verbose: boolish) -> void
# <!--
# rdoc-file=lib/fileutils.rb
+ # - ln_sr(src, dest, target_directory: true, force: nil, noop: nil, verbose: nil)
+ # -->
+ # Like FileUtils.ln_s, but create links relative to `dest`.
+ #
+ def self?.ln_sr: (pathlist src, path dest, ?target_directory: boolish, ?noop: boolish, ?verbose: boolish) -> void
+
+ # <!--
+ # rdoc-file=lib/fileutils.rb
# - mkdir(list, mode: nil, noop: nil, verbose: nil)
# -->
- # Creates one or more directories.
+ # Creates directories at the paths in the given `list` (a single path or an
+ # array of paths); returns `list` if it is an array, `[list]` otherwise.
#
- # FileUtils.mkdir 'test'
- # FileUtils.mkdir %w(tmp data)
- # FileUtils.mkdir 'notexist', noop: true # Does not really create.
- # FileUtils.mkdir 'tmp', mode: 0700
+ # Argument `list` or its elements should be [interpretable as
+ # paths](rdoc-ref:FileUtils@Path+Arguments).
#
+ # With no keyword arguments, creates a directory at each `path` in `list` by
+ # calling: `Dir.mkdir(path, mode)`; see [Dir.mkdir](rdoc-ref:Dir.mkdir):
+ #
+ # FileUtils.mkdir(%w[tmp0 tmp1]) # => ["tmp0", "tmp1"]
+ # FileUtils.mkdir('tmp4') # => ["tmp4"]
+ #
+ # Keyword arguments:
+ #
+ # * `mode: *mode`* - also calls `File.chmod(mode, path)`; see
+ # [File.chmod](rdoc-ref:File.chmod).
+ # * `noop: true` - does not create directories.
+ # * `verbose: true` - prints an equivalent command:
+ #
+ # FileUtils.mkdir(%w[tmp0 tmp1], verbose: true)
+ # FileUtils.mkdir(%w[tmp2 tmp3], mode: 0700, verbose: true)
+ #
+ # Output:
+ #
+ # mkdir tmp0 tmp1
+ # mkdir -m 700 tmp2 tmp3
+ #
+ #
+ # Raises an exception if any path points to an existing file or directory, or if
+ # for any reason a directory cannot be created.
+ #
+ # Related: FileUtils.mkdir_p.
+ #
def self?.mkdir: (pathlist list, ?mode: Integer?, ?noop: boolish, ?verbose: boolish) -> void
# <!--
# rdoc-file=lib/fileutils.rb
# - mkdir_p(list, mode: nil, noop: nil, verbose: nil)
# -->
- # Creates a directory and all its parent directories. For example,
+ # Creates directories at the paths in the given `list` (a single path or an
+ # array of paths), also creating ancestor directories as needed; returns `list`
+ # if it is an array, `[list]` otherwise.
#
- # FileUtils.mkdir_p '/usr/local/lib/ruby'
+ # Argument `list` or its elements should be [interpretable as
+ # paths](rdoc-ref:FileUtils@Path+Arguments).
#
- # causes to make following directories, if they do not exist.
+ # With no keyword arguments, creates a directory at each `path` in `list`, along
+ # with any needed ancestor directories, by calling: `Dir.mkdir(path, mode)`; see
+ # [Dir.mkdir](rdoc-ref:Dir.mkdir):
#
- # * /usr
- # * /usr/local
- # * /usr/local/lib
- # * /usr/local/lib/ruby
+ # FileUtils.mkdir_p(%w[tmp0/tmp1 tmp2/tmp3]) # => ["tmp0/tmp1", "tmp2/tmp3"]
+ # FileUtils.mkdir_p('tmp4/tmp5') # => ["tmp4/tmp5"]
#
+ # Keyword arguments:
#
- # You can pass several directories at a time in a list.
+ # * `mode: *mode`* - also calls `File.chmod(mode, path)`; see
+ # [File.chmod](rdoc-ref:File.chmod).
+ # * `noop: true` - does not create directories.
+ # * `verbose: true` - prints an equivalent command:
#
+ # FileUtils.mkdir_p(%w[tmp0 tmp1], verbose: true)
+ # FileUtils.mkdir_p(%w[tmp2 tmp3], mode: 0700, verbose: true)
+ #
+ # Output:
+ #
+ # mkdir -p tmp0 tmp1
+ # mkdir -p -m 700 tmp2 tmp3
+ #
+ #
+ # Raises an exception if for any reason a directory cannot be created.
+ #
+ # FileUtils.mkpath and FileUtils.makedirs are aliases for FileUtils.mkdir_p.
+ #
+ # Related: FileUtils.mkdir.
+ #
def self?.mkdir_p: (pathlist list, ?mode: mode?, ?noop: boolish, ?verbose: boolish) -> void
# <!--
# rdoc-file=lib/fileutils.rb
# - makedirs(list, mode: nil, noop: nil, verbose: nil)
@@ -609,19 +1304,75 @@
# <!--
# rdoc-file=lib/fileutils.rb
# - mv(src, dest, force: nil, noop: nil, verbose: nil, secure: nil)
# -->
- # Moves file(s) `src` to `dest`. If `file` and `dest` exist on the different
- # disk partition, the file is copied then the original file is removed.
+ # Moves entries.
#
- # FileUtils.mv 'badname.rb', 'goodname.rb'
- # FileUtils.mv 'stuff.rb', '/notexist/lib/ruby', force: true # no error
+ # Arguments `src` (a single path or an array of paths) and `dest` (a single
+ # path) should be [interpretable as paths](rdoc-ref:FileUtils@Path+Arguments).
#
- # FileUtils.mv %w(junk.txt dust.txt), '/home/foo/.trash/'
- # FileUtils.mv Dir.glob('test*.rb'), 'test', noop: true, verbose: true
+ # If `src` and `dest` are on different file systems, first copies, then removes
+ # `src`.
#
+ # May cause a local vulnerability if not called with keyword argument `secure:
+ # true`; see [Avoiding the TOCTTOU
+ # Vulnerability](rdoc-ref:FileUtils@Avoiding+the+TOCTTOU+Vulnerability).
+ #
+ # If `src` is the path to a single file or directory and `dest` does not exist,
+ # moves `src` to `dest`:
+ #
+ # tree('src0')
+ # # => src0
+ # # |-- src0.txt
+ # # `-- src1.txt
+ # File.exist?('dest0') # => false
+ # FileUtils.mv('src0', 'dest0')
+ # File.exist?('src0') # => false
+ # tree('dest0')
+ # # => dest0
+ # # |-- src0.txt
+ # # `-- src1.txt
+ #
+ # If `src` is an array of paths to files and directories and `dest` is the path
+ # to a directory, copies from each path in the array to `dest`:
+ #
+ # File.file?('src1.txt') # => true
+ # tree('src1')
+ # # => src1
+ # # |-- src.dat
+ # # `-- src.txt
+ # Dir.empty?('dest1') # => true
+ # FileUtils.mv(['src1.txt', 'src1'], 'dest1')
+ # tree('dest1')
+ # # => dest1
+ # # |-- src1
+ # # | |-- src.dat
+ # # | `-- src.txt
+ # # `-- src1.txt
+ #
+ # Keyword arguments:
+ #
+ # * `force: true` - if the move includes removing `src` (that is, if `src` and
+ # `dest` are on different file systems), ignores raised exceptions of
+ # StandardError and its descendants.
+ # * `noop: true` - does not move files.
+ # * `secure: true` - removes `src` securely; see details at
+ # FileUtils.remove_entry_secure.
+ # * `verbose: true` - prints an equivalent command:
+ #
+ # FileUtils.mv('src0', 'dest0', noop: true, verbose: true)
+ # FileUtils.mv(['src1.txt', 'src1'], 'dest1', noop: true, verbose: true)
+ #
+ # Output:
+ #
+ # mv src0 dest0
+ # mv src1.txt src1 dest1
+ #
+ #
+ # FileUtils.move is an alias for FileUtils.mv.
+ #
def self?.mv: (pathlist src, path dest, ?force: boolish, ?noop: boolish, ?verbose: boolish, ?secure: boolish) -> void
# <!--
# rdoc-file=lib/fileutils.rb
# - move(src, dest, force: nil, noop: nil, verbose: nil, secure: nil)
@@ -638,32 +1389,40 @@
# <!--
# rdoc-file=lib/fileutils.rb
# - options()
# -->
- # Returns an Array of option names.
+ # Returns an array of the string keyword names:
#
- # p FileUtils.options #=> ["noop", "force", "verbose", "preserve", "mode"]
+ # FileUtils.options.take(3) # => ["noop", "verbose", "force"]
#
def self.options: () -> Array[String]
# <!--
# rdoc-file=lib/fileutils.rb
# - options_of(mid)
# -->
- # Returns an Array of option names of the method `mid`.
+ # Returns an array of the string keyword name for method `mid`; the argument may
+ # be a string or a symbol:
#
- # p FileUtils.options_of(:rm) #=> ["noop", "verbose", "force"]
+ # FileUtils.options_of(:rm) # => ["force", "noop", "verbose"]
+ # FileUtils.options_of('mv') # => ["force", "noop", "verbose", "secure"]
#
def self.options_of: (Symbol mid) -> Array[String]
# <!--
# rdoc-file=lib/fileutils.rb
# - pwd()
# -->
- # Returns the name of the current directory.
+ # Returns a string containing the path to the current directory:
#
+ # FileUtils.pwd # => "/rdoc/fileutils"
+ #
+ # FileUtils.getwd is an alias for FileUtils.pwd.
+ #
+ # Related: FileUtils.cd.
+ #
def self?.pwd: () -> String
# <!--
# rdoc-file=lib/fileutils.rb
# - getwd()
@@ -680,84 +1439,111 @@
# <!--
# rdoc-file=lib/fileutils.rb
# - remove_dir(path, force = false)
# -->
- # Removes a directory `dir` and its contents recursively. This method ignores
- # StandardError if `force` is true.
+ # Recursively removes the directory entry given by `path`, which should be the
+ # entry for a regular file, a symbolic link, or a directory.
#
+ # Argument `path` should be [interpretable as a
+ # path](rdoc-ref:FileUtils@Path+Arguments).
+ #
+ # Optional argument `force` specifies whether to ignore raised exceptions of
+ # StandardError and its descendants.
+ #
+ # Related: [methods for deleting](rdoc-ref:FileUtils@Deleting).
+ #
def self?.remove_dir: (path path, ?boolish force) -> void
# <!--
# rdoc-file=lib/fileutils.rb
# - remove_entry(path, force = false)
# -->
- # 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.
+ # Removes the entry given by `path`, which should be the entry for a regular
+ # file, a symbolic link, or a directory.
#
- # See also remove_entry_secure.
+ # Argument `path` should be [interpretable as a
+ # path](rdoc-ref:FileUtils@Path+Arguments).
#
+ # Optional argument `force` specifies whether to ignore raised exceptions of
+ # StandardError and its descendants.
+ #
+ # Related: FileUtils.remove_entry_secure.
+ #
def self?.remove_entry: (path path, ?boolish force) -> void
# <!--
# rdoc-file=lib/fileutils.rb
# - remove_entry_secure(path, force = false)
# -->
- # This method removes a file system entry `path`. `path` shall be a regular
- # file, a directory, or something. If `path` is a directory, remove it
- # recursively. This method is required to avoid TOCTTOU
- # (time-of-check-to-time-of-use) local security vulnerability of rm_r. #rm_r
- # causes security hole when:
+ # Securely removes the entry given by `path`, which should be the entry for a
+ # regular file, a symbolic link, or a directory.
#
- # * Parent directory is world writable (including /tmp).
- # * Removing directory tree includes world writable directory.
- # * The system has symbolic link.
+ # Argument `path` should be [interpretable as a
+ # path](rdoc-ref:FileUtils@Path+Arguments).
#
+ # Avoids a local vulnerability that can exist in certain circumstances; see
+ # [Avoiding the TOCTTOU
+ # Vulnerability](rdoc-ref:FileUtils@Avoiding+the+TOCTTOU+Vulnerability).
#
- # To avoid this security hole, this method applies special preprocess. If `path`
- # is a directory, this method chown(2) and chmod(2) all removing directories.
- # This requires the current process is the owner of the removing whole directory
- # tree, or is the super user (root).
+ # Optional argument `force` specifies whether to ignore raised exceptions of
+ # StandardError and its descendants.
#
- # WARNING: You must ensure that **ALL** parent directories cannot be moved by
- # other untrusted users. For example, parent directories should not be owned by
- # untrusted users, and should not be world writable except when the sticky bit
- # set.
+ # Related: [methods for deleting](rdoc-ref:FileUtils@Deleting).
#
- # WARNING: Only the owner of the removing directory tree, or Unix super user
- # (root) should invoke this method. Otherwise this method does not work.
- #
- # For details of this security vulnerability, see Perl's case:
- #
- # * https://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2005-0448
- # * https://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2004-0452
- #
- #
- # For fileutils.rb, this vulnerability is reported in [ruby-dev:26100].
- #
def self?.remove_entry_secure: (path path, ?boolish force) -> void
# <!--
# rdoc-file=lib/fileutils.rb
# - remove_file(path, force = false)
# -->
- # Removes a file `path`. This method ignores StandardError if `force` is true.
+ # Removes the file entry given by `path`, which should be the entry for a
+ # regular file or a symbolic link.
#
+ # Argument `path` should be [interpretable as a
+ # path](rdoc-ref:FileUtils@Path+Arguments).
+ #
+ # Optional argument `force` specifies whether to ignore raised exceptions of
+ # StandardError and its descendants.
+ #
+ # Related: [methods for deleting](rdoc-ref:FileUtils@Deleting).
+ #
def self?.remove_file: (path path, ?void force) -> void
# <!--
# rdoc-file=lib/fileutils.rb
# - rm(list, force: nil, noop: nil, verbose: nil)
# -->
- # Remove file(s) specified in `list`. This method cannot remove directories.
- # All StandardErrors are ignored when the :force option is set.
+ # Removes entries at the paths in the given `list` (a single path or an array of
+ # paths) returns `list`, if it is an array, `[list]` otherwise.
#
- # FileUtils.rm %w( junk.txt dust.txt )
- # FileUtils.rm Dir.glob('*.so')
- # FileUtils.rm 'NotExistFile', force: true # never raises exception
+ # Argument `list` or its elements should be [interpretable as
+ # paths](rdoc-ref:FileUtils@Path+Arguments).
#
+ # With no keyword arguments, removes files at the paths given in `list`:
+ #
+ # FileUtils.touch(['src0.txt', 'src0.dat'])
+ # FileUtils.rm(['src0.dat', 'src0.txt']) # => ["src0.dat", "src0.txt"]
+ #
+ # Keyword arguments:
+ #
+ # * `force: true` - ignores raised exceptions of StandardError and its
+ # descendants.
+ # * `noop: true` - does not remove files; returns `nil`.
+ # * `verbose: true` - prints an equivalent command:
+ #
+ # FileUtils.rm(['src0.dat', 'src0.txt'], noop: true, verbose: true)
+ #
+ # Output:
+ #
+ # rm src0.dat src0.txt
+ #
+ #
+ # FileUtils.remove is an alias for FileUtils.rm.
+ #
+ # Related: [methods for deleting](rdoc-ref:FileUtils@Deleting).
+ #
def self?.rm: (pathlist list, ?force: boolish, ?noop: boolish, ?verbose: boolish) -> void
# <!--
# rdoc-file=lib/fileutils.rb
# - remove(list, force: nil, noop: nil, verbose: nil)
@@ -774,14 +1560,23 @@
# <!--
# rdoc-file=lib/fileutils.rb
# - rm_f(list, noop: nil, verbose: nil)
# -->
- # Equivalent to
+ # Equivalent to:
#
- # FileUtils.rm(list, force: true)
+ # FileUtils.rm(list, force: true, **kwargs)
#
+ # Argument `list` (a single path or an array of paths) should be [interpretable
+ # as paths](rdoc-ref:FileUtils@Path+Arguments).
+ #
+ # See FileUtils.rm for keyword arguments.
+ #
+ # FileUtils.safe_unlink is an alias for FileUtils.rm_f.
+ #
+ # Related: [methods for deleting](rdoc-ref:FileUtils@Deleting).
+ #
def self?.rm_f: (pathlist list, ?noop: boolish, ?verbose: boolish) -> void
# <!--
# rdoc-file=lib/fileutils.rb
# - safe_unlink(list, noop: nil, verbose: nil)
@@ -798,40 +1593,83 @@
# <!--
# rdoc-file=lib/fileutils.rb
# - rm_r(list, force: nil, noop: nil, verbose: nil, secure: nil)
# -->
- # remove files `list`[0] `list`[1]... If `list`[n] is a directory, removes its
- # all contents recursively. This method ignores StandardError when :force option
- # is set.
+ # Removes entries at the paths in the given `list` (a single path or an array of
+ # paths); returns `list`, if it is an array, `[list]` otherwise.
#
- # FileUtils.rm_r Dir.glob('/tmp/*')
- # FileUtils.rm_r 'some_dir', force: true
+ # Argument `list` or its elements should be [interpretable as
+ # paths](rdoc-ref:FileUtils@Path+Arguments).
#
- # WARNING: This method causes local vulnerability if one of parent directories
- # or removing directory tree are world writable (including /tmp, whose
- # permission is 1777), and the current process has strong privilege such as Unix
- # super user (root), and the system has symbolic link. For secure removing,
- # read the documentation of remove_entry_secure carefully, and set :secure
- # option to true. Default is `secure: false`.
+ # May cause a local vulnerability if not called with keyword argument `secure:
+ # true`; see [Avoiding the TOCTTOU
+ # Vulnerability](rdoc-ref:FileUtils@Avoiding+the+TOCTTOU+Vulnerability).
#
- # NOTE: This method calls remove_entry_secure if :secure option is set. See also
- # remove_entry_secure.
+ # For each file path, removes the file at that path:
#
+ # FileUtils.touch(['src0.txt', 'src0.dat'])
+ # FileUtils.rm_r(['src0.dat', 'src0.txt'])
+ # File.exist?('src0.txt') # => false
+ # File.exist?('src0.dat') # => false
+ #
+ # For each directory path, recursively removes files and directories:
+ #
+ # tree('src1')
+ # # => src1
+ # # |-- dir0
+ # # | |-- src0.txt
+ # # | `-- src1.txt
+ # # `-- dir1
+ # # |-- src2.txt
+ # # `-- src3.txt
+ # FileUtils.rm_r('src1')
+ # File.exist?('src1') # => false
+ #
+ # Keyword arguments:
+ #
+ # * `force: true` - ignores raised exceptions of StandardError and its
+ # descendants.
+ # * `noop: true` - does not remove entries; returns `nil`.
+ # * `secure: true` - removes `src` securely; see details at
+ # FileUtils.remove_entry_secure.
+ # * `verbose: true` - prints an equivalent command:
+ #
+ # FileUtils.rm_r(['src0.dat', 'src0.txt'], noop: true, verbose: true)
+ # FileUtils.rm_r('src1', noop: true, verbose: true)
+ #
+ # Output:
+ #
+ # rm -r src0.dat src0.txt
+ # rm -r src1
+ #
+ #
+ # Related: [methods for deleting](rdoc-ref:FileUtils@Deleting).
+ #
def self?.rm_r: (pathlist list, ?force: boolish, ?noop: boolish, ?verbose: boolish, ?secure: boolish) -> void
# <!--
# rdoc-file=lib/fileutils.rb
# - rm_rf(list, noop: nil, verbose: nil, secure: nil)
# -->
- # Equivalent to
+ # Equivalent to:
#
- # FileUtils.rm_r(list, force: true)
+ # FileUtils.rm_r(list, force: true, **kwargs)
#
- # WARNING: This method causes local vulnerability. Read the documentation of
- # rm_r first.
+ # Argument `list` or its elements should be [interpretable as
+ # paths](rdoc-ref:FileUtils@Path+Arguments).
#
+ # May cause a local vulnerability if not called with keyword argument `secure:
+ # true`; see [Avoiding the TOCTTOU
+ # Vulnerability](rdoc-ref:FileUtils@Avoiding+the+TOCTTOU+Vulnerability).
+ #
+ # See FileUtils.rm_r for keyword arguments.
+ #
+ # FileUtils.rmtree is an alias for FileUtils.rm_rf.
+ #
+ # Related: [methods for deleting](rdoc-ref:FileUtils@Deleting).
+ #
def self?.rm_rf: (pathlist list, ?noop: boolish, ?verbose: boolish, ?secure: boolish) -> void
# <!--
# rdoc-file=lib/fileutils.rb
# - rmtree(list, noop: nil, verbose: nil, secure: nil)
@@ -848,38 +1686,109 @@
# <!--
# rdoc-file=lib/fileutils.rb
# - rmdir(list, parents: nil, noop: nil, verbose: nil)
# -->
- # Removes one or more directories.
+ # Removes directories at the paths in the given `list` (a single path or an
+ # array of paths); returns `list`, if it is an array, `[list]` otherwise.
#
- # FileUtils.rmdir 'somedir'
- # FileUtils.rmdir %w(somedir anydir otherdir)
- # # Does not really remove directory; outputs message.
- # FileUtils.rmdir 'somedir', verbose: true, noop: true
+ # Argument `list` or its elements should be [interpretable as
+ # paths](rdoc-ref:FileUtils@Path+Arguments).
#
+ # With no keyword arguments, removes the directory at each `path` in `list`, by
+ # calling: `Dir.rmdir(path)`; see [Dir.rmdir](rdoc-ref:Dir.rmdir):
+ #
+ # FileUtils.rmdir(%w[tmp0/tmp1 tmp2/tmp3]) # => ["tmp0/tmp1", "tmp2/tmp3"]
+ # FileUtils.rmdir('tmp4/tmp5') # => ["tmp4/tmp5"]
+ #
+ # Keyword arguments:
+ #
+ # * `parents: true` - removes successive ancestor directories if empty.
+ # * `noop: true` - does not remove directories.
+ # * `verbose: true` - prints an equivalent command:
+ #
+ # FileUtils.rmdir(%w[tmp0/tmp1 tmp2/tmp3], parents: true, verbose: true)
+ # FileUtils.rmdir('tmp4/tmp5', parents: true, verbose: true)
+ #
+ # Output:
+ #
+ # rmdir -p tmp0/tmp1 tmp2/tmp3
+ # rmdir -p tmp4/tmp5
+ #
+ #
+ # Raises an exception if a directory does not exist or if for any reason a
+ # directory cannot be removed.
+ #
+ # Related: [methods for deleting](rdoc-ref:FileUtils@Deleting).
+ #
def self?.rmdir: (pathlist list, ?parents: boolish, ?noop: boolish, ?verbose: boolish) -> void
# <!--
# rdoc-file=lib/fileutils.rb
# - touch(list, noop: nil, verbose: nil, mtime: nil, nocreate: nil)
# -->
- # Updates modification time (mtime) and access time (atime) of file(s) in
- # `list`. Files are created if they don't exist.
+ # Updates modification times (mtime) and access times (atime) of the entries
+ # given by the paths in `list` (a single path or an array of paths); returns
+ # `list` if it is an array, `[list]` otherwise.
#
- # FileUtils.touch 'timestamp'
- # FileUtils.touch Dir.glob('*.c'); system 'make'
+ # By default, creates an empty file for any path to a non-existent entry; use
+ # keyword argument `nocreate` to raise an exception instead.
#
+ # Argument `list` or its elements should be [interpretable as
+ # paths](rdoc-ref:FileUtils@Path+Arguments).
+ #
+ # Examples:
+ #
+ # # Single path.
+ # f = File.new('src0.txt') # Existing file.
+ # f.atime # => 2022-06-10 11:11:21.200277 -0700
+ # f.mtime # => 2022-06-10 11:11:21.200277 -0700
+ # FileUtils.touch('src0.txt')
+ # f = File.new('src0.txt')
+ # f.atime # => 2022-06-11 08:28:09.8185343 -0700
+ # f.mtime # => 2022-06-11 08:28:09.8185343 -0700
+ #
+ # # Array of paths.
+ # FileUtils.touch(['src0.txt', 'src0.dat'])
+ #
+ # Keyword arguments:
+ #
+ # * `mtime: *time`* - sets the entry's mtime to the given time, instead of the
+ # current time.
+ # * `nocreate: true` - raises an exception if the entry does not exist.
+ # * `noop: true` - does not touch entries; returns `nil`.
+ # * `verbose: true` - prints an equivalent command:
+ #
+ # FileUtils.touch('src0.txt', noop: true, verbose: true)
+ # FileUtils.touch(['src0.txt', 'src0.dat'], noop: true, verbose: true)
+ # FileUtils.touch(path, noop: true, verbose: true)
+ #
+ # Output:
+ #
+ # touch src0.txt
+ # touch src0.txt src0.dat
+ # touch src0.txt
+ #
+ #
+ # Related: FileUtils.uptodate?.
+ #
def self?.touch: (pathlist list, ?noop: boolish, ?verbose: boolish, ?mtime: (Time | Numeric)?, ?nocreate: boolish) -> void
# <!--
# rdoc-file=lib/fileutils.rb
# - uptodate?(new, old_list)
# -->
- # Returns true if `new` is newer than all `old_list`. Non-existent files are
- # older than any file.
+ # Returns `true` if the file at path `new` is newer than all the files at paths
+ # in array `old_list`; `false` otherwise.
#
- # FileUtils.uptodate?('hello.o', %w(hello.c hello.h)) or \
- # system 'make hello.o'
+ # Argument `new` and the elements of `old_list` should be [interpretable as
+ # paths](rdoc-ref:FileUtils@Path+Arguments):
+ #
+ # FileUtils.uptodate?('Rakefile', ['Gemfile', 'README.md']) # => true
+ # FileUtils.uptodate?('Gemfile', ['Rakefile', 'README.md']) # => false
+ #
+ # A non-existent file is considered to be infinitely old.
+ #
+ # Related: FileUtils.touch.
#
def self?.uptodate?: (path new, pathlist old_list) -> bool
end