Class: EMDirWatcher::Tree

Inherits:
Object
  • Object
show all
Defined in:
lib/em-dir-watcher/tree.rb

Overview

Computes fine-grained (per-file) change events for a given directory tree, using coarse-grained (per-subtree) events for optimization.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(full_path, inclusions = nil, exclusions = []) ⇒ Tree

Returns a new instance of Tree.


168
169
170
171
172
173
174
# File 'lib/em-dir-watcher/tree.rb', line 168

def initialize full_path, inclusions=nil, exclusions=[]
  @full_path = self.class.resolve_real_path_where_possible(File.expand_path(full_path))
  self.inclusions = inclusions
  self.exclusions = exclusions
  @root_entry = Entry.new self, '', false
  @root_entry.refresh! [], true
end

Instance Attribute Details

#exclusionsObject

Returns the value of attribute exclusions


146
147
148
# File 'lib/em-dir-watcher/tree.rb', line 146

def exclusions
  @exclusions
end

#full_pathObject (readonly)

Returns the value of attribute full_path


144
145
146
# File 'lib/em-dir-watcher/tree.rb', line 144

def full_path
  @full_path
end

#inclusionsObject

Returns the value of attribute inclusions


145
146
147
# File 'lib/em-dir-watcher/tree.rb', line 145

def inclusions
  @inclusions
end

Class Method Details

.parse_matchers(matcher_expressions) ⇒ Object


148
149
150
151
152
153
154
155
156
157
158
# File 'lib/em-dir-watcher/tree.rb', line 148

def self.parse_matchers matcher_expressions
  matcher_expressions.collect do |expr|
    if Regexp === expr
      RegexpMatcher.new expr
    elsif expr.include? '/'
      PathGlobMatcher.new expr
    else
      NameGlobMatcher.new expr
    end
  end
end

.resolve_real_path_where_possible(expanded_path) ⇒ Object


160
161
162
163
164
165
166
# File 'lib/em-dir-watcher/tree.rb', line 160

def self.resolve_real_path_where_possible expanded_path
  Pathname.new(expanded_path).realpath().to_s
rescue Errno::ENOENT
  dirname, basename = File.dirname(expanded_path), File.basename(expanded_path)
  return expanded_path if dirname == '/' || dirname == '.'
  return File.join(resolve_real_path_where_possible(dirname), basename)
end

Instance Method Details

#excludes?(relative_path) ⇒ Boolean

Returns:

  • (Boolean)

195
196
197
# File 'lib/em-dir-watcher/tree.rb', line 195

def excludes? relative_path
  @exclusion_matchers.any? { |matcher| matcher.matches? relative_path }
end

#full_file_listObject


199
200
201
# File 'lib/em-dir-watcher/tree.rb', line 199

def full_file_list
  @root_entry.recursive_file_entries.collect { |entry| entry.relative_path }.sort
end

#includes?(relative_path) ⇒ Boolean

Returns:

  • (Boolean)

191
192
193
# File 'lib/em-dir-watcher/tree.rb', line 191

def includes? relative_path
  @inclusion_matchers.nil? || @inclusion_matchers.any? { |matcher| matcher.matches? relative_path }
end

#refresh!(scope = nil, refresh_subtree = true) ⇒ Object


176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/em-dir-watcher/tree.rb', line 176

def refresh! scope=nil, refresh_subtree=true
  scope = self.class.resolve_real_path_where_possible(File.expand_path(scope || @full_path))

  scope_with_slash     = File.join(scope, '')
  full_path_with_slash = File.join(@full_path, '')
  return [] unless scope_with_slash.downcase[0..full_path_with_slash.size-1] == full_path_with_slash.downcase

  relative_scope = (scope[full_path_with_slash.size..-1] || '').split('/')
  relative_scope = relative_scope.reject { |item| item == '' }

  changed_relative_paths = []
  @root_entry.scoped_refresh! changed_relative_paths, relative_scope, refresh_subtree
  changed_relative_paths.sort
end