123456789_123456789_123456789_123456789_123456789_

Class: FileUtils::Entry_

Do not use. This class is for internal use only.
Relationships & Source Files
Super Chains via Extension / Inclusion / Inheritance
Instance Chain:
self, StreamUtils_
Inherits: Object
Defined in: lib/fileutils.rb

Overview

internal use only

Constant Summary

Class Method Summary

Instance Attribute Summary

Instance Method Summary

Constructor Details

.new(a, b = nil, deref = false) ⇒ Entry_

[ GitHub ]

  
# File 'lib/fileutils.rb', line 2074

def initialize(a, b = nil, deref = false)
  @prefix = @rel = @path = nil
  if b
    @prefix = a
    @rel = b
  else
    @path = a
  end
  @deref = deref
  @stat = nil
  @lstat = nil
end

Instance Attribute Details

#blockdev?Boolean (readonly)

[ GitHub ]

  
# File 'lib/fileutils.rb', line 2140

def blockdev?
  s = lstat!
  s and s.blockdev?
end

#chardev?Boolean (readonly)

[ GitHub ]

  
# File 'lib/fileutils.rb', line 2135

def chardev?
  s = lstat!
  s and s.chardev?
end

#check_have_lchmod?Boolean (readonly, private)

[ GitHub ]

  
# File 'lib/fileutils.rb', line 2408

def check_have_lchmod?
  return false unless File.respond_to?(:lchmod)
  File.lchmod 0
  return true
rescue NotImplementedError
  return false
end

#check_have_lchown?Boolean (readonly, private)

[ GitHub ]

  
# File 'lib/fileutils.rb', line 2426

def check_have_lchown?
  return false unless File.respond_to?(:lchown)
  File.lchown nil, nil
  return true
rescue NotImplementedError
  return false
end

#dereference?Boolean (readonly)

[ GitHub ]

  
# File 'lib/fileutils.rb', line 2107

def dereference?
  @deref
end

#directory?Boolean (readonly)

[ GitHub ]

  
# File 'lib/fileutils.rb', line 2125

def directory?
  s = lstat!
  s and s.directory?
end

#door?Boolean (readonly)

[ GitHub ]

  
# File 'lib/fileutils.rb', line 2157

def door?
  s = lstat!
  s and (s.mode & 0xF000 == S_IF_DOOR)
end

#exist?Boolean (readonly)

[ GitHub ]

  
# File 'lib/fileutils.rb', line 2111

def exist?
  begin
    lstat
    true
  rescue Errno::ENOENT
    false
  end
end

#file?Boolean (readonly)

[ GitHub ]

  
# File 'lib/fileutils.rb', line 2120

def file?
  s = lstat!
  s and s.file?
end

#have_lchmod?Boolean (readonly, private)

[ GitHub ]

  
# File 'lib/fileutils.rb', line 2400

def have_lchmod?
  # This is not MT-safe, but it does not matter.
  if @@fileutils_rb_have_lchmod == nil
    @@fileutils_rb_have_lchmod = check_have_lchmod?
  end
  @@fileutils_rb_have_lchmod
end

#have_lchown?Boolean (readonly, private)

[ GitHub ]

  
# File 'lib/fileutils.rb', line 2418

def have_lchown?
  # This is not MT-safe, but it does not matter.
  if @@fileutils_rb_have_lchown == nil
    @@fileutils_rb_have_lchown = check_have_lchown?
  end
  @@fileutils_rb_have_lchown
end

#pipe?Boolean (readonly)

[ GitHub ]

  
# File 'lib/fileutils.rb', line 2150

def pipe?
  s = lstat!
  s and s.pipe?
end

#socket?Boolean (readonly)

[ GitHub ]

  
# File 'lib/fileutils.rb', line 2145

def socket?
  s = lstat!
  s and s.socket?
end

#symlink?Boolean (readonly)

[ GitHub ]

  
# File 'lib/fileutils.rb', line 2130

def symlink?
  s = lstat!
  s and s.symlink?
end

Instance Method Details

#chmod(mode)

[ GitHub ]

  
# File 'lib/fileutils.rb', line 2208

def chmod(mode)
  if symlink?
    File.lchmod mode, path() if have_lchmod?
  else
    File.chmod mode, path()
  end
rescue Errno::EOPNOTSUPP
end

#chown(uid, gid)

[ GitHub ]

  
# File 'lib/fileutils.rb', line 2217

def chown(uid, gid)
  if symlink?
    File.lchown uid, gid, path() if have_lchown?
  else
    File.chown uid, gid, path()
  end
end

#copy(dest)

[ GitHub ]

  
# File 'lib/fileutils.rb', line 2241

def copy(dest)
  lstat
  case
  when file?
    copy_file dest
  when directory?
    if !File.exist?(dest) and descendant_directory?(dest, path)
      raise ArgumentError, "cannot copy directory %s to itself %s" % [path, dest]
    end
    begin
      Dir.mkdir dest
    rescue
      raise unless File.directory?(dest)
    end
  when symlink?
    File.symlink File.readlink(path()), dest
  when chardev?, blockdev?
    raise "cannot handle device file"
  when socket?
    begin
      require 'socket'
    rescue LoadError
      raise "cannot handle socket"
    else
      raise "cannot handle socket" unless defined?(UNIXServer)
    end
    UNIXServer.new(dest).close
    File.chmod lstat().mode, dest
  when pipe?
    raise "cannot handle FIFO" unless File.respond_to?(:mkfifo)
    File.mkfifo dest, lstat().mode
  when door?
    raise "cannot handle door: #{path()}"
  else
    raise "unknown file type: #{path()}"
  end
end

#copy_file(dest)

[ GitHub ]

  
# File 'lib/fileutils.rb', line 2279

def copy_file(dest)
  File.open(path()) do |s|
    File.open(dest, 'wb', s.stat.mode) do |f|
      IO.copy_stream(s, f)
    end
  end
end

#copy_metadata(path)

[ GitHub ]

  
# File 'lib/fileutils.rb', line 2287

def (path)
  st = lstat()
  if !st.symlink?
    File.utime st.atime, st.mtime, path
  end
  mode = st.mode
  begin
    if st.symlink?
      begin
        File.lchown st.uid, st.gid, path
      rescue NotImplementedError
      end
    else
      File.chown st.uid, st.gid, path
    end
  rescue Errno::EPERM, Errno::EACCES
    # clear setuid/setgid
    mode &= 01777
  end
  if st.symlink?
    begin
      File.lchmod mode, path
    rescue NotImplementedError, Errno::EOPNOTSUPP
    end
  else
    File.chmod mode, path
  end
end

#descendant_directory?(descendant, ascendant) ⇒ Boolean (private)

[ GitHub ]

  
# File 'lib/fileutils.rb', line 2454

def descendant_directory?(descendant, ascendant)
  if File::FNM_SYSCASE.nonzero?
    File.expand_path(File.dirname(descendant)).casecmp(File.expand_path(ascendant)) == 0
  else
    File.expand_path(File.dirname(descendant)) == File.expand_path(ascendant)
  end
end

#entries

[ GitHub ]

  
# File 'lib/fileutils.rb', line 2162

def entries
  opts = {}
  opts[:encoding] = fu_windows? ? ::Encoding::UTF_8 : path.encoding

  files = Dir.children(path, **opts)

  untaint = RUBY_VERSION < '2.7'
  files.map {|n| Entry_.new(prefix(), join(rel(), untaint ? n.untaint : n)) }
end

#inspect

[ GitHub ]

  
# File 'lib/fileutils.rb', line 2087

def inspect
  "\#<#{self.class} #{path()}>"
end

#join(dir, base) (private)

[ GitHub ]

  
# File 'lib/fileutils.rb', line 2434

def join(dir, base)
  return File.path(dir) if not base or base == '.'
  return File.path(base) if not dir or dir == '.'
  begin
    File.join(dir, base)
  rescue EncodingError
    if fu_windows?
      File.join(dir.encode(::Encoding::UTF_8), base.encode(::Encoding::UTF_8))
    else
      raise
    end
  end
end

#lstat

[ GitHub ]

  
# File 'lib/fileutils.rb', line 2194

def lstat
  if dereference?
    @lstat ||= File.stat(path())
  else
    @lstat ||= File.lstat(path())
  end
end

#lstat!

[ GitHub ]

  
# File 'lib/fileutils.rb', line 2202

def lstat!
  lstat()
rescue SystemCallError
  nil
end

#path

[ GitHub ]

  
# File 'lib/fileutils.rb', line 2091

def path
  if @path
    File.path(@path)
  else
    join(@prefix, @rel)
  end
end

#platform_support

[ GitHub ]

  
# File 'lib/fileutils.rb', line 2336

def platform_support
  return yield unless fu_windows?
  first_time_p = true
  begin
    yield
  rescue Errno::ENOENT
    raise
  rescue => err
    if first_time_p
      first_time_p = false
      begin
        File.chmod 0700, path()   # Windows does not have symlink
        retry
      rescue SystemCallError
      end
    end
    raise err
  end
end

#postorder_traverse {|_self| ... }

Yields:

  • (_self)

Yield Parameters:

  • _self (Entry_)

    the object that the method was called on

[ GitHub ]

  
# File 'lib/fileutils.rb', line 2366

def postorder_traverse
  if directory?
    begin
      children = entries()
    rescue Errno::EACCES
      # Failed to get the list of children.
      # Assuming there is no children, try to process the parent directory.
      yield self
      return
    end

    children.each do |ent|
      ent.postorder_traverse do |e|
        yield e
      end
    end
  end
  yield self
end

#prefix

[ GitHub ]

  
# File 'lib/fileutils.rb', line 2099

def prefix
  @prefix || @path
end

#preorder_traverse Also known as: #traverse

[ GitHub ]

  
# File 'lib/fileutils.rb', line 2356

def preorder_traverse
  stack = [self]
  while ent = stack.pop
    yield ent
    stack.concat ent.entries.reverse if ent.directory?
  end
end

#rel

[ GitHub ]

  
# File 'lib/fileutils.rb', line 2103

def rel
  @rel
end

#remove

[ GitHub ]

  
# File 'lib/fileutils.rb', line 2316

def remove
  if directory?
    remove_dir1
  else
    remove_file
  end
end

#remove_dir1

[ GitHub ]

  
# File 'lib/fileutils.rb', line 2324

def remove_dir1
  platform_support {
    Dir.rmdir path().chomp(?/)
  }
end

#remove_file

[ GitHub ]

  
# File 'lib/fileutils.rb', line 2330

def remove_file
  platform_support {
    File.unlink path
  }
end

#stat

[ GitHub ]

  
# File 'lib/fileutils.rb', line 2172

def stat
  return @stat if @stat
  if lstat() and lstat().symlink?
    @stat = File.stat(path())
  else
    @stat = lstat()
  end
  @stat
end

#stat!

[ GitHub ]

  
# File 'lib/fileutils.rb', line 2182

def stat!
  return @stat if @stat
  if lstat! and lstat!.symlink?
    @stat = File.stat(path())
  else
    @stat = lstat!
  end
  @stat
rescue SystemCallError
  nil
end

#traverse

Alias for #preorder_traverse.

[ GitHub ]

  
# File 'lib/fileutils.rb', line 2364

alias traverse preorder_traverse

#wrap_traverse(pre, post)

[ GitHub ]

  
# File 'lib/fileutils.rb', line 2386

def wrap_traverse(pre, post)
  pre.call self
  if directory?
    entries.each do |ent|
      ent.wrap_traverse pre, post
    end
  end
  post.call self
end