Class: Listen::DirectoryRecord

Inherits:
Object
  • Object
show all
Defined in:
lib/listen/directory_record.rb

Overview

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

Constant Summary collapse

DEFAULT_IGNORED_DIRECTORIES =
%w[.rbx .bundle .git .svn log tmp vendor]
DEFAULT_IGNORED_EXTENSIONS =
%w[.DS_Store]

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(directory) ⇒ DirectoryRecord

Initializes a directory record.

Parameters:

  • [String] (Hash)

    a customizable set of options

Raises:

  • (ArgumentError)


43
44
45
46
47
48
49
50
51
52
# File 'lib/listen/directory_record.rb', line 43

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

Instance Attribute Details

#directoryObject (readonly)

Returns the value of attribute directory.



12
13
14
# File 'lib/listen/directory_record.rb', line 12

def directory
  @directory
end

#pathsObject (readonly)

Returns the value of attribute paths.



12
13
14
# File 'lib/listen/directory_record.rb', line 12

def paths
  @paths
end

#sha1_checksumsObject (readonly)

Returns the value of attribute sha1_checksums.



12
13
14
# File 'lib/listen/directory_record.rb', line 12

def sha1_checksums
  @sha1_checksums
end

Class Method Details

.generate_default_ignoring_patternsObject

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



26
27
28
29
30
31
32
33
34
35
36
# File 'lib/listen/directory_record.rb', line 26

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

Instance Method Details

#buildObject

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



123
124
125
126
127
# File 'lib/listen/directory_record.rb', line 123

def build
  @paths = Hash.new { |h, k| h[k] = Hash.new }
  important_paths { |path| insert_path(path) }
  @updated_at = Time.now.to_f
end

#fetch_changes(directories, options = {}) ⇒ Hash<Array>

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

Parameters:

  • directories (Array)

    the list of directories scan for changes

  • options (Hash) (defaults to: {})

Options Hash (options):

  • recursive (Boolean)

    scan all sub-directories recursively

  • relative_paths (Boolean)

    whether or not to use relative paths for changes

Returns:

  • (Hash<Array>)

    the changes



139
140
141
142
143
144
145
146
147
148
149
# File 'lib/listen/directory_record.rb', line 139

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
  @updated_at = Time.now.to_f
  @changes
end

#filter(*regexps) ⇒ Listen::Listener

Adds filtering patterns to the listener.

Examples:

Filter some files

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

Parameters:

  • regexp (Regexp)

    a pattern for filtering paths

Returns:



91
92
93
# File 'lib/listen/directory_record.rb', line 91

def filter(*regexps)
  @filtering_patterns.merge(regexps)
end

#filtered?(path) ⇒ Boolean

Returns whether a path should be filtered or not.

Parameters:

  • path (String)

    the path to test.

Returns:

  • (Boolean)


112
113
114
115
116
117
118
# File 'lib/listen/directory_record.rb', line 112

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_patternsArray<Regexp>

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

Returns:

  • (Array<Regexp>)

    the filtering patterns



67
68
69
# File 'lib/listen/directory_record.rb', line 67

def filtering_patterns
  @filtering_patterns.to_a
end

#ignore(*regexps) ⇒ Object

Adds ignoring patterns to the record.

Examples:

Ignore some paths

ignore ".git", ".svn"

Parameters:

  • regexp (Regexp)

    a pattern for ignoring paths



78
79
80
# File 'lib/listen/directory_record.rb', line 78

def ignore(*regexps)
  @ignoring_patterns.merge(regexps)
end

#ignored?(path) ⇒ Boolean

Returns whether a path should be ignored or not.

Parameters:

  • path (String)

    the path to test.

Returns:

  • (Boolean)


101
102
103
104
# File 'lib/listen/directory_record.rb', line 101

def ignored?(path)
  path = relative_to_base(path)
  @ignoring_patterns.any? { |pattern| pattern =~ path }
end

#ignoring_patternsArray<Regexp>

Returns the ignoring patterns in the record

Returns:

  • (Array<Regexp>)

    the ignoring patterns



58
59
60
# File 'lib/listen/directory_record.rb', line 58

def ignoring_patterns
  @ignoring_patterns.to_a
end

#relative_to_base(path) ⇒ String

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

Parameters:

  • path (String)

    the path to convert

Returns:

  • (String)

    the relative path



157
158
159
160
# File 'lib/listen/directory_record.rb', line 157

def relative_to_base(path)
  return nil unless path[@directory]
  path.sub(%r{^#{@directory}#{File::SEPARATOR}?}, '')
end