Class: Listen::Adapter::BSD

Inherits:
Base
  • Object
show all
Defined in:
lib/listen/adapter/bsd.rb

Constant Summary collapse

OS_REGEXP =
/bsd|dragonfly/i
DEFAULTS =
{
  events: [
    :delete,
    :write,
    :extend,
    :attrib,
    :rename
    # :link, :revoke
  ]
}
BUNDLER_DECLARE_GEM =
"  Please add the following to your Gemfile to avoid polling for changes:\n    require 'rbconfig'\n    if RbConfig::CONFIG['target_os'] =~ \#{OS_REGEXP}\n      gem 'rb-kqueue', '>= 0.2'\n\n      # Base versions have known conflicts/bugs\n      # Even master branches may not work...\n      gem 'ffi', github: 'carpetsmoker/ffi', ref: 'ac63e07f7'\n      gem 'celluloid', github: 'celluloid/celluloid', ref: '7fdef04'\n    end\n".gsub(/^ {6}/, '')
BSD_EXPERIMENTAL =
"  NOTE *BSD SUPPORT IS EXPERIMENTAL!\n\n  In fact, it likely WONT WORK!!!!\n\n  (see: https://github.com/guard/listen/issues/220)\n\n  If you're brave enough, feel free to suggest pull requests and\n  experiment on your own. For help, browse existing issues marked 'bsd'\n  for clues, tips and workaround.\n".gsub(/^ {6}/, '')

Instance Attribute Summary

Attributes inherited from Base

#options

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#_log, _log, #_queue_change, #configure, #initialize, local_fs?, #start

Constructor Details

This class inherits a constructor from Listen::Adapter::Base

Class Method Details

.usable?Boolean

Returns:

  • (Boolean)


46
47
48
49
50
51
52
53
54
55
# File 'lib/listen/adapter/bsd.rb', line 46

def self.usable?
  return false unless super
  Kernel.warn BSD_EXPERIMENTAL
  require 'rb-kqueue'
  require 'find'
  true
rescue LoadError
  Kernel.warn BUNDLER_DECLARE_GEM
  false
end

Instance Method Details

#_change(event_flags) ⇒ Object (private)



88
89
90
91
92
93
94
95
96
# File 'lib/listen/adapter/bsd.rb', line 88

def _change(event_flags)
  { modified: [:attrib, :extend],
    added:    [:write],
    removed:  [:rename, :delete]
  }.each do |change, flags|
    return change unless (flags & event_flags).empty?
  end
  nil
end

#_configure(directory, &_callback) ⇒ Object (private)



59
60
61
62
63
64
# File 'lib/listen/adapter/bsd.rb', line 59

def _configure(directory, &_callback)
  @worker ||= KQueue::Queue.new
  # use Record to make a snapshot of dir, so we
  # can detect new files
  _find(directory.to_s) { |path| _watch_file(path, @worker) }
end

#_event_path(event) ⇒ Object (private)



98
99
100
# File 'lib/listen/adapter/bsd.rb', line 98

def _event_path(event)
  Pathname.new(event.watcher.path)
end

#_find(*paths) ⇒ Object (private)

Quick rubocop workaround



116
117
118
# File 'lib/listen/adapter/bsd.rb', line 116

def _find(*paths)
  Find.send(:find, *paths)
end

#_process_event(dir, event) ⇒ Object (private)



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/listen/adapter/bsd.rb', line 70

def _process_event(dir, event)
  full_path = _event_path(event)
  if full_path.directory?
    # Force dir content tracking to kick in, or we won't have
    # names of added files
    _queue_change(:dir, dir, '.', recursive: true)
  else
    path = full_path.relative_path_from(dir)
    _queue_change(:file, dir, path, change: _change(event.flags))
  end

  # If it is a directory, and it has a write flag, it means a
  # file has been added so find out which and deal with it.
  # No need to check for removed files, kqueue will forget them
  # when the vfs does.
  _watch_for_new_file(event) if path.directory?
end

#_runObject (private)



66
67
68
# File 'lib/listen/adapter/bsd.rb', line 66

def _run
  @worker.run
end

#_watch_file(path, queue) ⇒ Object (private)



111
112
113
# File 'lib/listen/adapter/bsd.rb', line 111

def _watch_file(path, queue)
  queue.watch_file(path, *options.events, &_worker_callback)
end

#_watch_for_new_file(event) ⇒ Object (private)



102
103
104
105
106
107
108
109
# File 'lib/listen/adapter/bsd.rb', line 102

def _watch_for_new_file(event)
  queue = event.watcher.queue
  _find(_event_path(event).to_s) do |file_path|
    unless queue.watchers.detect { |_, v| v.path == file_path.to_s }
      _watch_file(file_path, queue)
    end
  end
end