class Listen::DirectoryRecord

The directory record stores information about a directory and keeps track of changes to the structure of its childs.

Constants

DEFAULT_IGNORED_DIRECTORIES
DEFAULT_IGNORED_EXTENSIONS
HIGH_PRECISION_SUPPORTED

Defines the used precision based on the type of mtime returned by the system (whether its in milliseconds or just seconds)

MetaData

Data structure used to save meta data about a path

Attributes

directory[R]
paths[R]
sha1_checksums[R]

Public Class Methods

generate_default_ignoring_patterns() click to toggle source

Creates the ignoring patterns from the default ignored directories and extensions. It memoizes the generated patterns to avoid unnecessary computation.

# File lib/listen/directory_record.rb, line 35
def generate_default_ignoring_patterns
  @@default_ignoring_patterns ||= Array.new.tap do |default_patterns|
    # Add directories
    ignored_directories = DEFAULT_IGNORED_DIRECTORIES.map { |d| Regexp.escape(d) }
    default_patterns << %r{^(?:#{ignored_directories.join('|')})/}

    # Add extensions
    ignored_extensions = DEFAULT_IGNORED_EXTENSIONS.map { |e| Regexp.escape(e) }
    default_patterns << %r{(?:#{ignored_extensions.join('|')})$}
  end
end
new(directory) click to toggle source

Initializes a directory record.

@option [String] directory the directory to keep track of

# File lib/listen/directory_record.rb, line 52
def initialize(directory)
  raise ArgumentError, "The path '#{directory}' is not a directory!" unless File.directory?(directory)

  @directory          = directory
  @ignoring_patterns  = Set.new
  @filtering_patterns = Set.new
  @sha1_checksums     = Hash.new

  @ignoring_patterns.merge(DirectoryRecord.generate_default_ignoring_patterns)
end

Public Instance Methods

build() click to toggle source

Finds the paths that should be stored and adds them to the paths' hash.

# File lib/listen/directory_record.rb, line 130
def build
  @paths = Hash.new { |h, k| h[k] = Hash.new }
  important_paths { |path| insert_path(path) }
end
fetch_changes(directories, options = {}) click to toggle source

Detects changes in the passed directories, updates the record with the new changes and returns the changes

@param [Array] directories the list of directories scan for changes @param [Hash] options @option options [Boolean] recursive scan all sub-directories recursively @option options [Boolean] relative_paths whether or not to use relative paths for changes

@return [Hash<Array>] the changes

# File lib/listen/directory_record.rb, line 145
def fetch_changes(directories, options = {})
  @changes    = { :modified => [], :added => [], :removed => [] }
  directories = directories.sort_by { |el| el.length }.reverse # diff sub-dir first

  directories.each do |directory|
    next unless directory[@directory] # Path is or inside directory
    detect_modifications_and_removals(directory, options)
    detect_additions(directory, options)
  end

  @changes
end
filter(*regexps) click to toggle source

Adds filtering patterns to the listener.

@example Filter some files

ignore /\.txt$/, /.*\.zip/

@param [Regexp] regexp a pattern for filtering paths

# File lib/listen/directory_record.rb, line 98
def filter(*regexps)
  @filtering_patterns.merge(regexps)
end
filtered?(path) click to toggle source

Returns whether a path should be filtered or not.

@param [String] path the path to test.

@return [Boolean]

# File lib/listen/directory_record.rb, line 119
def filtered?(path)
  # When no filtering patterns are set, ALL files are stored.
  return true if @filtering_patterns.empty?

  path = relative_to_base(path)
  @filtering_patterns.any? { |pattern| pattern =~ path }
end
filtering_patterns() click to toggle source

Returns the filtering patterns used in the record to know which paths should be stored.

@return [Array<Regexp>] the filtering patterns

# File lib/listen/directory_record.rb, line 76
def filtering_patterns
  @filtering_patterns.to_a
end
ignore(*regexps) click to toggle source

Adds ignoring patterns to the record.

@example Ignore some paths

ignore %r{^ignored/path/}, /man/

@param [Regexp] regexp a pattern for ignoring paths

# File lib/listen/directory_record.rb, line 87
def ignore(*regexps)
  @ignoring_patterns.merge(regexps)
end
ignored?(path) click to toggle source

Returns whether a path should be ignored or not.

@param [String] path the path to test.

@return [Boolean]

# File lib/listen/directory_record.rb, line 108
def ignored?(path)
  path = relative_to_base(path)
  @ignoring_patterns.any? { |pattern| pattern =~ path }
end
ignoring_patterns() click to toggle source

Returns the ignoring patterns in the record

@return [Array<Regexp>] the ignoring patterns

# File lib/listen/directory_record.rb, line 67
def ignoring_patterns
  @ignoring_patterns.to_a
end
relative_to_base(path) click to toggle source

Converts an absolute path to a path that's relative to the base directory.

@param [String] path the path to convert

@return [String] the relative path

# File lib/listen/directory_record.rb, line 164
def relative_to_base(path)
  return nil unless path[@directory]
  path.sub(%r{^#{Regexp.quote(@directory)}#{File::SEPARATOR}?}, '')
end