class Rerun::Watcher

Constants

InvalidDirectoryError

Attributes

directory[R]

def self.default_ignore

Listen::Silencer.new(Listen::Listener.new).send :_default_ignore_patterns

end

pattern[R]

def self.default_ignore

Listen::Silencer.new(Listen::Listener.new).send :_default_ignore_patterns

end

priority[R]

def self.default_ignore

Listen::Silencer.new(Listen::Listener.new).send :_default_ignore_patterns

end

Public Class Methods

new(options = {}, &client_callback) click to toggle source

Create a file system watcher. Start it by calling start.

@param options the directory to watch (default “.”) @param options the glob pattern to search under the watched directory (default “*/”) @param options the priority of the watcher thread (default 0)

# File lib/rerun/watcher.rb, line 29
def initialize(options = {}, &client_callback)
  @client_callback = client_callback

  options = {
      :directory => ".",
      :pattern => "**/*",
      :priority => 0,
  }.merge(options)

  @pattern = options[:pattern]
  @directories = options[:directory]
  @directories = sanitize_dirs(@directories)
  @priority = options[:priority]
  @ignore = [options[:ignore]].flatten.compact
  @thread = nil
end

Public Instance Methods

adapter() click to toggle source
# File lib/rerun/watcher.rb, line 88
def adapter
  @listener.registry[:adapter] || (timeout(4) do
    sleep 1 until adapter = @listener.registry[:adapter]
    adapter
  end)
end
ignoring() click to toggle source
# File lib/rerun/watcher.rb, line 82
def ignoring
  # todo: --no-ignore-dotfiles
  dotfiles = /^\.[^.]/ # at beginning of string, a real dot followed by any other character
  [dotfiles] + @ignore.map { |x| Rerun::Glob.new(x).to_regexp }
end
join() click to toggle source

wait for the file watcher to finish

# File lib/rerun/watcher.rb, line 107
def join
  @thread.join if @thread
rescue Interrupt => e
  # don't care
end
pause() click to toggle source
# File lib/rerun/watcher.rb, line 113
def pause
  @listener.pause if @listener
end
running?() click to toggle source
# File lib/rerun/watcher.rb, line 121
def running?
  @listener && @listener.instance_variable_get(:@adapter)
end
sanitize_dirs(dirs) click to toggle source
# File lib/rerun/watcher.rb, line 46
def sanitize_dirs(dirs)
  dirs = [*dirs]
  dirs.map do |d|
    d.chomp!("/")
    unless FileTest.exists?(d) && FileTest.readable?(d) && FileTest.directory?(d)
      raise InvalidDirectoryError, "Directory '#{d}' either doesnt exist or isn't readable"
    end
    File.expand_path(d)
  end
end
start() click to toggle source
# File lib/rerun/watcher.rb, line 57
def start
  if @thread then
    raise RuntimeError, "already started"
  end

  @thread = Thread.new do
    @listener = Listen.to(*@directories, only: watching, ignore: ignoring, wait_for_delay: 1) do |modified, added, removed|
      if((modified.size + added.size + removed.size) > 0)
        @client_callback.call(:modified => modified, :added => added, :removed => removed)
      end
    end
    @listener.start
  end

  @thread.priority = @priority

  sleep 0.1 until @listener

  at_exit { stop } # try really hard to clean up after ourselves
end
stop() click to toggle source

kill the file watcher thread

# File lib/rerun/watcher.rb, line 96
def stop
  @thread.wakeup rescue ThreadError
  begin
    @listener.stop
  rescue Exception => e
    puts "#{e.class}: #{e.message} stopping listener"
  end
  @thread.kill rescue ThreadError
end
unpause() click to toggle source
# File lib/rerun/watcher.rb, line 117
def unpause
  @listener.unpause if @listener
end
watching() click to toggle source
# File lib/rerun/watcher.rb, line 78
def watching
  Rerun::Glob.new(@pattern).to_regexp
end