class Dle::Filesystem

Attributes

base_dir[R]
index[R]
opts[R]

Public Class Methods

new(base_dir, opts = {}) click to toggle source

# File lib/dle/filesystem.rb, line 23
def initialize base_dir, opts = {}
  raise ArgumentError, "#{base_dir} is not a directory" unless FileTest.directory?(base_dir)
  @base_dir = base_dir.encode('UTF-8','UTF-8-MAC') if RUBY_PLATFORM.downcase["darwin"]
  @base_dir = File.expand_path(@base_dir || base_dir).freeze
  @opts = { dotfiles: true, verbose: true }.merge(opts)
  @opts[:pattern] = Regexp.new(@opts[:pattern]) unless ["dirs", "files", ""].include?(@opts[:pattern].to_s)
  @index = {}
end

Public Instance Methods

c(str, color = :yellow) click to toggle source

Shortcut for logger.colorize

# File lib/dle/filesystem.rb, line 17
def c str, color = :yellow
  logger.colorize? ? logger.colorize(str, color) : str
end
delta(dlfile) click to toggle source
# File lib/dle/filesystem.rb, line 63
def delta dlfile
  abort "cannot delta DLFILE without HD_BASE", 1 unless dlfile[:HD_BASE].present?

  # WARNING: The order of this result hash is important as it defines the order we process things!
  {chown: [], chmod: [], mv: [], cp: [], rm: []}.tap do |r|
    logger.ensure_prefix c("[dFS]\t", :magenta) do
      log "HD-BASE is " << c(dlfile[:HD_BASE], :magenta)
      dlfile.each do |ino, snode|
        begin
          next if ino == :HD_BASE || ino == :HD_DOTFILES
          node = @index[ino]
          unless node
            warn("INODE " << c(ino, :magenta) << c(" not found, ignore...", :red))
            next
          end

          # flagged for removal
          if %w[del delr delf delrf].include?(snode.mode)
            r[:rm] << Softnode.new(node: node, snode: snode, is: node.relative_path)
            next
          end

          # mode changed
          if "#{snode.mode}".present? && "#{snode.mode}" != "cp" && "#{node.mode}" != "#{snode.mode}"
            r[:chmod] << Softnode.new(node: node, snode: snode, is: node.mode, should: snode.mode)
          end

          # uid/gid changed
          if "#{node.owngrp}" != "#{snode.uid}:#{snode.gid}"
            r[:chown] << Softnode.new(node: node, snode: snode, is: node.owngrp, should: "#{snode.uid}:#{snode.gid}")
          end

          # path changed
          if "#{node.relative_path}" != "#{snode.relative_path}"
            r[snode.mode == "cp" ? :cp : :mv] << Softnode.new(node: node, snode: snode, is: node.relative_path, should: snode.relative_path)
          end
        rescue Errno::EPERM
          warn "Operation not permitted - #{snode.relative_path}" if @opts[:verbose]
        rescue Errno::ENOENT
          warn "No such file or directory - #{snode.relative_path}" if @opts[:verbose]
        end
      end
    end

    # sort results to perform actions inside-out
    r.each do |k, v|
      r[k] = v.sort_by{|snode| snode.node.relative_path.length }.reverse
    end
  end
end
index!() click to toggle source
# File lib/dle/filesystem.rb, line 37
def index!
  Find.find(@base_dir) do |path|
    if File.basename(path)[0] == ?. && !@opts[:dotfiles]
      Find.prune
    else
      next if @opts[:pattern] == "files" && !FileTest.file?(path)
      next if @opts[:pattern] == "dirs" && !FileTest.directory?(path)
      next if @opts[:pattern].is_a?(Regexp) && !path.match(@opts[:pattern])
      index_node(path)
    end
  end
end
logger() click to toggle source
# File lib/dle/filesystem.rb, line 12
def logger
  Thread.main.app_logger
end
reindex!() click to toggle source
# File lib/dle/filesystem.rb, line 32
def reindex!
  @index = {}
  index!
end
relative_path(path) click to toggle source
# File lib/dle/filesystem.rb, line 50
def relative_path path
  if path.start_with?(@base_dir)
    p = path[(@base_dir.length+1)..-1]
    p.presence || "."
  else
    path
  end
end
to_dlfile() click to toggle source
# File lib/dle/filesystem.rb, line 59
def to_dlfile
  DlFile.generate(self)
end

Protected Instance Methods

index_node(path) click to toggle source
# File lib/dle/filesystem.rb, line 116
def index_node path
  begin
    Node.new(self, path).tap{|node| @index[node.inode] = node }
  rescue Errno::EPERM
    warn "Operation not permitted - #{path}" if @opts[:verbose]
  rescue Errno::ENOENT
    warn "No such file or directory (broken symlink?) - #{path}" if @opts[:verbose]
  end
end