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 2072

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 2138

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

#chardev?Boolean (readonly)

[ GitHub ]

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

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

#check_have_lchmod?Boolean (readonly, private)

[ GitHub ]

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

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 2424

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 2105

def dereference?
  @deref
end

#directory?Boolean (readonly)

[ GitHub ]

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

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

#door?Boolean (readonly)

[ GitHub ]

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

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

#exist?Boolean (readonly)

[ GitHub ]

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

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

#file?Boolean (readonly)

[ GitHub ]

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

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

#have_lchmod?Boolean (readonly, private)

[ GitHub ]

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

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 2416

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 2148

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

#socket?Boolean (readonly)

[ GitHub ]

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

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

#symlink?Boolean (readonly)

[ GitHub ]

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

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

Instance Method Details

#chmod(mode)

[ GitHub ]

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

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 2215

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 2239

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 2277

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 2285

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 2452

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 2160

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 2085

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

#join(dir, base) (private)

[ GitHub ]

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

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 2192

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

#lstat!

[ GitHub ]

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

def lstat!
  lstat()
rescue SystemCallError
  nil
end

#path

[ GitHub ]

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

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

#platform_support

[ GitHub ]

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

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 2364

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 2097

def prefix
  @prefix || @path
end

#preorder_traverse Also known as: #traverse

[ GitHub ]

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

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 2101

def rel
  @rel
end

#remove

[ GitHub ]

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

def remove
  if directory?
    remove_dir1
  else
    remove_file
  end
end

#remove_dir1

[ GitHub ]

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

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

#remove_file

[ GitHub ]

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

def remove_file
  platform_support {
    File.unlink path
  }
end

#stat

[ GitHub ]

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

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 2180

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 2362

alias traverse preorder_traverse

#wrap_traverse(pre, post)

[ GitHub ]

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

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