class File::Visitor

Constants

DIRECTION
FILTER_NS_BASE
VERSION

Attributes

direction[R]
filters[R]
visit_dot_dir[RW]

Public Class Methods

new() click to toggle source
# File lib/file/visitor.rb, line 18
def initialize
  @filters = []

  @visit_dot_dir = false
  @direction = :asc
end

Public Instance Methods

add_filter(*args, &block) click to toggle source

3 ways to register filter

  1. built-in filter filter.add_filter(:mtime, :passed, 30, :days)

  2. custom filter filter.add_filter(my_filter) (my_filter must implements match?(path) method)

  3. block filter filter.add_filter do |path|

    # filter operations
    

    end

# File lib/file/visitor.rb, line 70
def add_filter(*args, &block)
  # 3. block filter
  if block_given?
    filter = File::Visitor::Filter::Proc.new(block)
    @filters.push(filter)
    return true
  end

  # 2. custom filter
  if (1 == args.size)
    custom_filter = args.shift
    unless (custom_filter.respond_to?(:match?))
      raise ArgumentError,
        "custom_filter must implement match?()"
    end
    @filters.push(custom_filter)
    return true
  end

  # 1. built-in filter
  filter_class = File::Visitor::FilterDispatcher.dispatch(args.shift)
  @filters.push(filter_class.new(*args))
  true
end
dir_list(dir) click to toggle source
# File lib/file/visitor.rb, line 50
def dir_list(dir)
  dirs = []
  visit_dir(dir) { |path| dirs << path }
  dirs
end
file_list(dir) click to toggle source
# File lib/file/visitor.rb, line 44
def file_list(dir)
  files = []
  visit(dir) { |path| files << path }
  files
end
set_direction(dir) click to toggle source
# File lib/file/visitor.rb, line 25
def set_direction(dir)
  if dir.nil?
    raise ArgumentError, "direction is nil"
  end
  if !DIRECTION.include?(dir.to_sym)
    raise ArgumentError,
      "invalid direction: " + dir.to_s
  end
  @direction = dir
end
target?(path) click to toggle source
# File lib/file/visitor.rb, line 95
def target?(path)
  # all the paths are target when no filters given
  return true unless @filters

  @filters.each do |filter|
    return false unless filter.match?(path)
  end
  true
end
visit(dir, &handler) click to toggle source
# File lib/file/visitor.rb, line 36
def visit(dir, &handler)
  visit_with_mode(dir, :file, &handler)
end
visit_dir(dir, &handler) click to toggle source
# File lib/file/visitor.rb, line 40
def visit_dir(dir, &handler)
  visit_with_mode(dir, :dir, &handler)
end

Private Instance Methods

assert_directory(dir) click to toggle source
# File lib/file/visitor.rb, line 112
def assert_directory(dir)
  unless dir.is_a?(String) && File.directory?(dir)
    raise ArgumentError, "#{dir} is not directory"
  end
end
dot_dir?(path) click to toggle source
# File lib/file/visitor.rb, line 107
def dot_dir?(path)
  basename = File.basename(path)
  basename == '.' || basename == '..'
end
visit_with_mode(dir, mode, &handler) click to toggle source

dir: target directory mode:

file - visit all files
dir  - visit directory only

handler: proc to call

# File lib/file/visitor.rb, line 124
def visit_with_mode(dir, mode, &handler)
  assert_directory(dir)

  entries = Dir.entries(dir)
    .sort_by { |filename| filename }

  if @direction == :desc
    entries.reverse!
  end

  entries.each do |entry|
    next if (dot_dir?(entry) && !@visit_dot_dir)

    abs_path = File.join(dir, entry)
    if File.directory?(abs_path)
      mode == :dir && handler.call(abs_path)
      visit_with_mode(abs_path, mode, &handler)
    else
      if mode == :file && target?(abs_path)
        handler.call(abs_path) 
      end
    end
  end
end