listen 3.0.8 → 3.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,16 +1,17 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'listen/options'
2
4
  require 'listen/record'
3
5
  require 'listen/change'
6
+ require 'listen/thread'
4
7
 
5
8
  module Listen
6
9
  module Adapter
7
10
  class Base
8
- attr_reader :options
11
+ attr_reader :options, :config
9
12
 
10
13
  # TODO: only used by tests
11
- DEFAULTS = {}
12
-
13
- attr_reader :config
14
+ DEFAULTS = {}.freeze
14
15
 
15
16
  def initialize(config)
16
17
  @started = false
@@ -28,9 +29,10 @@ module Listen
28
29
  end
29
30
 
30
31
  # TODO: it's a separate method as a temporary workaround for tests
32
+ # rubocop:disable Metrics/MethodLength
31
33
  def configure
32
34
  if @configured
33
- _log(:warn, 'Adapter already configured!')
35
+ Listen.logger.warn('Adapter already configured!')
34
36
  return
35
37
  end
36
38
 
@@ -49,11 +51,12 @@ module Listen
49
51
  # TODO: separate config per directory (some day maybe)
50
52
  change_config = Change::Config.new(config.queue, config.silencer)
51
53
  config.directories.each do |dir|
52
- record = Record.new(dir)
54
+ record = Record.new(dir, config.silencer)
53
55
  snapshot = Change.new(change_config, record)
54
56
  @snapshots[dir] = snapshot
55
57
  end
56
58
  end
59
+ # rubocop:enable Metrics/MethodLength
57
60
 
58
61
  def started?
59
62
  @started
@@ -63,48 +66,39 @@ module Listen
63
66
  configure
64
67
 
65
68
  if started?
66
- _log(:warn, 'Adapter already started!')
69
+ Listen.logger.warn('Adapter already started!')
67
70
  return
68
71
  end
69
72
 
70
73
  @started = true
71
74
 
72
- calling_stack = caller.dup
73
- Listen::Internals::ThreadPool.add do
74
- begin
75
- @snapshots.values.each do |snapshot|
76
- _timed('Record.build()') { snapshot.record.build }
77
- end
78
- _run
79
- rescue
80
- msg = 'run() in thread failed: %s:\n'\
81
- ' %s\n\ncalled from:\n %s'
82
- _log_exception(msg, calling_stack)
83
- raise # for unit tests mostly
75
+ @run_thread = Listen::Thread.new("run_thread") do
76
+ @snapshots.each_value do |snapshot|
77
+ _timed('Record.build()') { snapshot.record.build }
84
78
  end
79
+ _run
85
80
  end
86
81
  end
87
82
 
88
83
  def stop
89
84
  _stop
90
- end
91
-
92
- def self.usable?
93
- const_get('OS_REGEXP') =~ RbConfig::CONFIG['target_os']
85
+ config.queue.close # this causes queue.pop to return `nil` to the front-end
94
86
  end
95
87
 
96
88
  private
97
89
 
98
90
  def _stop
91
+ @run_thread&.kill
92
+ @run_thread = nil
99
93
  end
100
94
 
101
95
  def _timed(title)
102
- start = Time.now.to_f
96
+ start = MonotonicTime.now
103
97
  yield
104
- diff = Time.now.to_f - start
105
- Listen::Logger.info format('%s: %.05f seconds', title, diff)
98
+ diff = MonotonicTime.now - start
99
+ Listen.logger.info format('%s: %.05f seconds', title, diff)
106
100
  rescue
107
- Listen::Logger.warn "#{title} crashed: #{$ERROR_INFO.inspect}"
101
+ Listen.logger.warn "#{title} crashed: #{$ERROR_INFO.inspect}"
108
102
  raise
109
103
  end
110
104
 
@@ -114,10 +108,6 @@ module Listen
114
108
  @snapshots[dir].invalidate(type, rel_path, options)
115
109
  end
116
110
 
117
- def _log(*args, &block)
118
- self.class.send(:_log, *args, &block)
119
- end
120
-
121
111
  def _log_exception(msg, caller_stack)
122
112
  formatted = format(
123
113
  msg,
@@ -126,11 +116,13 @@ module Listen
126
116
  caller_stack * "\n"
127
117
  )
128
118
 
129
- _log(:error, formatted)
119
+ Listen.logger.error(formatted)
130
120
  end
131
121
 
132
- def self._log(*args, &block)
133
- Listen::Logger.send(*args, &block)
122
+ class << self
123
+ def usable?
124
+ const_get('OS_REGEXP') =~ RbConfig::CONFIG['target_os']
125
+ end
134
126
  end
135
127
  end
136
128
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Listener implementation for BSD's `kqueue`.
2
4
  # @see http://www.freebsd.org/cgi/man.cgi?query=kqueue
3
5
  # @see https://github.com/mat813/rb-kqueue/blob/master/lib/rb-kqueue/queue.rb
@@ -5,7 +7,7 @@
5
7
  module Listen
6
8
  module Adapter
7
9
  class BSD < Base
8
- OS_REGEXP = /bsd|dragonfly/i
10
+ OS_REGEXP = /bsd|dragonfly/i.freeze
9
11
 
10
12
  DEFAULTS = {
11
13
  events: [
@@ -16,7 +18,7 @@ module Listen
16
18
  :rename
17
19
  # :link, :revoke
18
20
  ]
19
- }
21
+ }.freeze
20
22
 
21
23
  BUNDLER_DECLARE_GEM = <<-EOS.gsub(/^ {6}/, '')
22
24
  Please add the following to your Gemfile to avoid polling for changes:
@@ -38,9 +40,9 @@ module Listen
38
40
 
39
41
  private
40
42
 
41
- def _configure(directory, &_callback)
43
+ def _configure(directory, &callback)
42
44
  @worker ||= KQueue::Queue.new
43
- @callback = _callback
45
+ @callback = callback
44
46
  # use Record to make a snapshot of dir, so we
45
47
  # can detect new files
46
48
  _find(directory.to_s) { |path| _watch_file(path, @worker) }
@@ -71,8 +73,7 @@ module Listen
71
73
  def _change(event_flags)
72
74
  { modified: [:attrib, :extend],
73
75
  added: [:write],
74
- removed: [:rename, :delete]
75
- }.each do |change, flags|
76
+ removed: [:rename, :delete] }.each do |change, flags|
76
77
  return change unless (flags & event_flags).empty?
77
78
  end
78
79
  nil
@@ -85,7 +86,7 @@ module Listen
85
86
  def _watch_for_new_file(event)
86
87
  queue = event.watcher.queue
87
88
  _find(_event_path(event).to_s) do |file_path|
88
- unless queue.watchers.detect { |_, v| v.path == file_path.to_s }
89
+ unless queue.watchers.find { |_, v| v.path == file_path.to_s }
89
90
  _watch_file(file_path, queue)
90
91
  end
91
92
  end
@@ -94,7 +95,7 @@ module Listen
94
95
  def _watch_file(path, queue)
95
96
  queue.watch_file(path, *options.events, &@callback)
96
97
  rescue Errno::ENOENT => e
97
- _log :warn, "kqueue: watch file failed: #{e.message}"
98
+ Listen.logger.warn "kqueue: watch file failed: #{e.message}"
98
99
  end
99
100
 
100
101
  # Quick rubocop workaround
@@ -1,17 +1,16 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'pathname'
2
4
 
3
5
  module Listen
4
6
  module Adapter
5
7
  class Config
6
- attr_reader :directories
7
- attr_reader :silencer
8
- attr_reader :queue
9
- attr_reader :adapter_options
8
+ attr_reader :directories, :silencer, :queue, :adapter_options
10
9
 
11
10
  def initialize(directories, queue, silencer, adapter_options)
12
11
  # Default to current directory if no directories are supplied
13
12
  directories = [Dir.pwd] if directories.to_a.empty?
14
-
13
+
15
14
  # TODO: fix (flatten, array, compact?)
16
15
  @directories = directories.map do |directory|
17
16
  Pathname.new(directory.to_s).realpath
@@ -1,15 +1,16 @@
1
- require 'thread'
2
- require 'listen/internals/thread_pool'
1
+ # frozen_string_literal: true
2
+
3
+ require 'listen/thread'
3
4
 
4
5
  module Listen
5
6
  module Adapter
6
7
  # Adapter implementation for Mac OS X `FSEvents`.
7
8
  #
8
9
  class Darwin < Base
9
- OS_REGEXP = /darwin(?<major_version>1\d+)/i
10
+ OS_REGEXP = /darwin(?<major_version>(1|2)\d+)/i.freeze
10
11
 
11
12
  # The default delay between checking for changes.
12
- DEFAULTS = { latency: 0.1 }
13
+ DEFAULTS = { latency: 0.1 }.freeze
13
14
 
14
15
  INCOMPATIBLE_GEM_VERSION = <<-EOS.gsub(/^ {8}/, '')
15
16
  rb-fsevent > 0.9.4 no longer supports OS X 10.6 through 10.8.
@@ -22,66 +23,54 @@ module Listen
22
23
  EOS
23
24
 
24
25
  def self.usable?
26
+ version = RbConfig::CONFIG['target_os'][OS_REGEXP, :major_version]
27
+ return false unless version
28
+ return true if version.to_i >= 13 # darwin13 is OS X 10.9
29
+
25
30
  require 'rb-fsevent'
26
- darwin_version = RbConfig::CONFIG['target_os'][OS_REGEXP, :major_version] or return false
27
- return true if darwin_version.to_i >= 13 # darwin13 is OS X 10.9
28
- return true if Gem::Version.new(FSEvent::VERSION) <= Gem::Version.new('0.9.4')
31
+ fsevent_version = Gem::Version.new(FSEvent::VERSION)
32
+ return true if fsevent_version <= Gem::Version.new('0.9.4')
29
33
  Kernel.warn INCOMPATIBLE_GEM_VERSION
30
34
  false
31
35
  end
32
36
 
33
37
  private
34
38
 
35
- # NOTE: each directory gets a DIFFERENT callback!
36
39
  def _configure(dir, &callback)
37
- opts = { latency: options.latency }
38
-
39
- @workers ||= ::Queue.new
40
- @workers << FSEvent.new.tap do |worker|
41
- _log :debug, "fsevent: watching: #{dir.to_s.inspect}"
42
- worker.watch(dir.to_s, opts, &callback)
43
- end
40
+ @callbacks[dir] = callback
44
41
  end
45
42
 
46
43
  def _run
47
- first = @workers.pop
48
-
49
- # NOTE: _run is called within a thread, so run every other
50
- # worker in it's own thread
51
- _run_workers_in_background(_to_array(@workers))
52
- _run_worker(first)
44
+ require 'rb-fsevent'
45
+ worker = FSEvent.new
46
+ dirs_to_watch = @callbacks.keys.map(&:to_s)
47
+ Listen.logger.info { "fsevent: watching: #{dirs_to_watch.inspect}" }
48
+ worker.watch(dirs_to_watch, { latency: options.latency }, &method(:_process_changes))
49
+ @worker_thread = Listen::Thread.new("worker_thread") { worker.run }
53
50
  end
54
51
 
55
- def _process_event(dir, event)
56
- _log :debug, "fsevent: processing event: #{event.inspect}"
57
- event.each do |path|
58
- new_path = Pathname.new(path.sub(/\/$/, ''))
59
- _log :debug, "fsevent: #{new_path}"
60
- # TODO: does this preserve symlinks?
61
- rel_path = new_path.relative_path_from(dir).to_s
62
- _queue_change(:dir, dir, rel_path, recursive: true)
63
- end
64
- end
52
+ def _process_changes(dirs)
53
+ dirs.each do |dir|
54
+ dir = Pathname.new(dir.sub(%r{/$}, ''))
65
55
 
66
- def _run_worker(worker)
67
- _log :debug, "fsevent: running worker: #{worker.inspect}"
68
- worker.run
69
- rescue
70
- _log_exception 'fsevent: running worker failed: %s:%s called from: %s', caller
56
+ @callbacks.each do |watched_dir, callback|
57
+ if watched_dir.eql?(dir) || Listen::Directory.ascendant_of?(watched_dir, dir)
58
+ callback.call(dir)
59
+ end
60
+ end
61
+ end
71
62
  end
72
63
 
73
- def _run_workers_in_background(workers)
74
- workers.each do |worker|
75
- # NOTE: while passing local variables to the block below is not
76
- # thread safe, using 'worker' from the enumerator above is ok
77
- Listen::Internals::ThreadPool.add { _run_worker(worker) }
78
- end
64
+ def _process_event(dir, path)
65
+ Listen.logger.debug { "fsevent: processing path: #{path.inspect}" }
66
+ # TODO: does this preserve symlinks?
67
+ rel_path = path.relative_path_from(dir).to_s
68
+ _queue_change(:dir, dir, rel_path, recursive: true)
79
69
  end
80
70
 
81
- def _to_array(queue)
82
- workers = []
83
- workers << queue.pop until queue.empty?
84
- workers
71
+ def _stop
72
+ @worker_thread&.kill
73
+ super
85
74
  end
86
75
  end
87
76
  end
@@ -1,45 +1,44 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Listen
2
4
  module Adapter
3
5
  # @see https://github.com/nex3/rb-inotify
4
6
  class Linux < Base
5
- OS_REGEXP = /linux/i
7
+ OS_REGEXP = /linux/i.freeze
6
8
 
7
9
  DEFAULTS = {
8
10
  events: [
9
11
  :recursive,
10
12
  :attrib,
11
13
  :create,
14
+ :modify,
12
15
  :delete,
13
16
  :move,
14
17
  :close_write
15
18
  ],
16
19
  wait_for_delay: 0.1
17
- }
20
+ }.freeze
18
21
 
19
22
  private
20
23
 
21
- WIKI_URL = 'https://github.com/guard/listen'\
22
- '/wiki/Increasing-the-amount-of-inotify-watchers'
23
-
24
- INOTIFY_LIMIT_MESSAGE = <<-EOS.gsub(/^\s*/, '')
25
- FATAL: Listen error: unable to monitor directories for changes.
26
- Visit #{WIKI_URL} for info on how to fix this.
27
- EOS
24
+ README_URL = 'https://github.com/guard/listen'\
25
+ '/blob/master/README.md#increasing-the-amount-of-inotify-watchers'
28
26
 
29
27
  def _configure(directory, &callback)
30
28
  require 'rb-inotify'
31
29
  @worker ||= ::INotify::Notifier.new
32
30
  @worker.watch(directory.to_s, *options.events, &callback)
33
31
  rescue Errno::ENOSPC
34
- abort(INOTIFY_LIMIT_MESSAGE)
32
+ raise ::Listen::Error::INotifyMaxWatchesExceeded, <<~EOS
33
+ Unable to monitor directories for changes because iNotify max watches exceeded. See #{README_URL} .
34
+ EOS
35
35
  end
36
36
 
37
37
  def _run
38
- Thread.current[:listen_blocking_read_thread] = true
39
38
  @worker.run
40
- Thread.current[:listen_blocking_read_thread] = false
41
39
  end
42
40
 
41
+ # rubocop:disable Metrics/MethodLength
43
42
  def _process_event(dir, event)
44
43
  # NOTE: avoid using event.absolute_name since new API
45
44
  # will need to have a custom recursion implemented
@@ -47,15 +46,13 @@ module Listen
47
46
  path = Pathname.new(event.watcher.path) + event.name
48
47
  rel_path = path.relative_path_from(dir).to_s
49
48
 
50
- _log(:debug) { "inotify: #{rel_path} (#{event.flags.inspect})" }
49
+ Listen.logger.debug { "inotify: #{rel_path} (#{event.flags.inspect})" }
51
50
 
52
51
  if /1|true/ =~ ENV['LISTEN_GEM_SIMULATE_FSEVENT']
53
52
  if (event.flags & [:moved_to, :moved_from]) || _dir_event?(event)
54
53
  rel_path = path.dirname.relative_path_from(dir).to_s
55
- _queue_change(:dir, dir, rel_path, {})
56
- else
57
- _queue_change(:dir, dir, rel_path, {})
58
54
  end
55
+ _queue_change(:dir, dir, rel_path, {})
59
56
  return
60
57
  end
61
58
 
@@ -74,6 +71,7 @@ module Listen
74
71
 
75
72
  _queue_change(:file, dir, rel_path, params)
76
73
  end
74
+ # rubocop:enable Metrics/MethodLength
77
75
 
78
76
  def _skip_event?(event)
79
77
  # Event on root directory
@@ -101,7 +99,9 @@ module Listen
101
99
  end
102
100
 
103
101
  def _stop
104
- @worker && @worker.close
102
+ @worker&.close
103
+
104
+ super
105
105
  end
106
106
  end
107
107
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Listen
2
4
  module Adapter
3
5
  # Polling Adapter that works cross-platform and
@@ -6,9 +8,9 @@ module Listen
6
8
  # file IO than the other implementations.
7
9
  #
8
10
  class Polling < Base
9
- OS_REGEXP = // # match every OS
11
+ OS_REGEXP = //.freeze # match every OS
10
12
 
11
- DEFAULTS = { latency: 1.0, wait_for_delay: 0.05 }
13
+ DEFAULTS = { latency: 1.0, wait_for_delay: 0.05 }.freeze
12
14
 
13
15
  private
14
16
 
@@ -19,12 +21,13 @@ module Listen
19
21
 
20
22
  def _run
21
23
  loop do
22
- start = Time.now.to_f
24
+ start = MonotonicTime.now
23
25
  @polling_callbacks.each do |callback|
24
26
  callback.call(nil)
25
- nap_time = options.latency - (Time.now.to_f - start)
26
- # TODO: warn if nap_time is negative (polling too slow)
27
- sleep(nap_time) if nap_time > 0
27
+ if (nap_time = options.latency - (MonotonicTime.now - start)) > 0
28
+ # TODO: warn if nap_time is negative (polling too slow)
29
+ sleep(nap_time)
30
+ end
28
31
  end
29
32
  end
30
33
  end
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Listen
2
4
  module Adapter
3
5
  # Adapter implementation for Windows `wdm`.
4
6
  #
5
7
  class Windows < Base
6
- OS_REGEXP = /mswin|mingw|cygwin/i
8
+ OS_REGEXP = /mswin|mingw|cygwin/i.freeze
7
9
 
8
10
  BUNDLER_DECLARE_GEM = <<-EOS.gsub(/^ {6}/, '')
9
11
  Please add the following to your Gemfile to avoid polling for changes:
@@ -15,8 +17,8 @@ module Listen
15
17
  require 'wdm'
16
18
  true
17
19
  rescue LoadError
18
- _log :debug, format('wdm - load failed: %s:%s', $ERROR_INFO,
19
- $ERROR_POSITION * "\n")
20
+ Listen.logger.debug format('wdm - load failed: %s:%s', $ERROR_INFO,
21
+ $ERROR_POSITION * "\n")
20
22
 
21
23
  Kernel.warn BUNDLER_DECLARE_GEM
22
24
  false
@@ -24,21 +26,20 @@ module Listen
24
26
 
25
27
  private
26
28
 
27
- def _configure(dir, &callback)
29
+ def _configure(dir)
28
30
  require 'wdm'
29
- _log :debug, 'wdm - starting...'
31
+ Listen.logger.debug 'wdm - starting...'
30
32
  @worker ||= WDM::Monitor.new
31
33
  @worker.watch_recursively(dir.to_s, :files) do |change|
32
- callback.call([:file, change])
34
+ yield([:file, change])
33
35
  end
34
36
 
35
37
  @worker.watch_recursively(dir.to_s, :directories) do |change|
36
- callback.call([:dir, change])
38
+ yield([:dir, change])
37
39
  end
38
40
 
39
- events = [:attributes, :last_write]
40
- @worker.watch_recursively(dir.to_s, *events) do |change|
41
- callback.call([:attr, change])
41
+ @worker.watch_recursively(dir.to_s, :attributes, :last_write) do |change|
42
+ yield([:attr, change])
42
43
  end
43
44
  end
44
45
 
@@ -46,8 +47,9 @@ module Listen
46
47
  @worker.run!
47
48
  end
48
49
 
50
+ # rubocop:disable Metrics/MethodLength
49
51
  def _process_event(dir, event)
50
- _log :debug, "wdm - callback: #{event.inspect}"
52
+ Listen.logger.debug "wdm - callback: #{event.inspect}"
51
53
 
52
54
  type, change = event
53
55
 
@@ -65,12 +67,12 @@ module Listen
65
67
  _queue_change(:file, dir, rel_path, options)
66
68
  end
67
69
  when :dir
68
- if change.type == :removed
70
+ case change.type
71
+ when :removed
69
72
  # TODO: check if watched dir?
70
73
  _queue_change(:dir, dir, Pathname(rel_path).dirname.to_s, {})
71
- elsif change.type == :added
74
+ when :added
72
75
  _queue_change(:dir, dir, rel_path, {})
73
- else
74
76
  # do nothing - changed directory means either:
75
77
  # - removed subdirs (handled above)
76
78
  # - added subdirs (handled above)
@@ -79,20 +81,15 @@ module Listen
79
81
  # so what's left?
80
82
  end
81
83
  end
82
- rescue
83
- details = event.inspect
84
- _log :error, format('wdm - callback (%): %s:%s', details, $ERROR_INFO,
85
- $ERROR_POSITION * "\n")
86
- raise
87
84
  end
85
+ # rubocop:enable Metrics/MethodLength
88
86
 
89
87
  def _change(type)
90
88
  { modified: [:modified, :attrib], # TODO: is attrib really passed?
91
89
  added: [:added, :renamed_new_file],
92
- removed: [:removed, :renamed_old_file] }.each do |change, types|
93
- return change if types.include?(type)
90
+ removed: [:removed, :renamed_old_file] }.find do |change, types|
91
+ types.include?(type) and break change
94
92
  end
95
- nil
96
93
  end
97
94
  end
98
95
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'listen/adapter/base'
2
4
  require 'listen/adapter/bsd'
3
5
  require 'listen/adapter/darwin'
@@ -7,37 +9,35 @@ require 'listen/adapter/windows'
7
9
 
8
10
  module Listen
9
11
  module Adapter
10
- OPTIMIZED_ADAPTERS = [Darwin, Linux, BSD, Windows]
12
+ OPTIMIZED_ADAPTERS = [Darwin, Linux, BSD, Windows].freeze
11
13
  POLLING_FALLBACK_MESSAGE = 'Listen will be polling for changes.'\
12
14
  'Learn more at https://github.com/guard/listen#listen-adapters.'
13
15
 
14
- def self.select(options = {})
15
- _log :debug, 'Adapter: considering polling ...'
16
- return Polling if options[:force_polling]
17
- _log :debug, 'Adapter: considering optimized backend...'
18
- return _usable_adapter_class if _usable_adapter_class
19
- _log :debug, 'Adapter: falling back to polling...'
20
- _warn_polling_fallback(options)
21
- Polling
22
- rescue
23
- _log :warn, format('Adapter: failed: %s:%s', $ERROR_POSITION.inspect,
24
- $ERROR_POSITION * "\n")
25
- raise
26
- end
16
+ class << self
17
+ def select(options = {})
18
+ Listen.logger.debug 'Adapter: considering polling ...'
19
+ return Polling if options[:force_polling]
20
+ Listen.logger.debug 'Adapter: considering optimized backend...'
21
+ return _usable_adapter_class if _usable_adapter_class
22
+ Listen.logger.debug 'Adapter: falling back to polling...'
23
+ _warn_polling_fallback(options)
24
+ Polling
25
+ rescue
26
+ Listen.logger.warn format('Adapter: failed: %s:%s', $ERROR_POSITION.inspect,
27
+ $ERROR_POSITION * "\n")
28
+ raise
29
+ end
27
30
 
28
- private
31
+ private
29
32
 
30
- def self._usable_adapter_class
31
- OPTIMIZED_ADAPTERS.detect(&:usable?)
32
- end
33
-
34
- def self._warn_polling_fallback(options)
35
- msg = options.fetch(:polling_fallback_message, POLLING_FALLBACK_MESSAGE)
36
- Kernel.warn "[Listen warning]:\n #{msg}" if msg
37
- end
33
+ def _usable_adapter_class
34
+ OPTIMIZED_ADAPTERS.find(&:usable?)
35
+ end
38
36
 
39
- def self._log(type, message)
40
- Listen::Logger.send(type, message)
37
+ def _warn_polling_fallback(options)
38
+ msg = options.fetch(:polling_fallback_message, POLLING_FALLBACK_MESSAGE)
39
+ Kernel.warn "[Listen warning]:\n #{msg}" if msg
40
+ end
41
41
  end
42
42
  end
43
43
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'listen/adapter'
2
4
  require 'listen/adapter/base'
3
5
  require 'listen/adapter/config'
@@ -8,6 +10,8 @@ require 'forwardable'
8
10
  # from exploding with huge test setup blocks
9
11
  module Listen
10
12
  class Backend
13
+ extend Forwardable
14
+
11
15
  def initialize(directories, queue, silencer, config)
12
16
  adapter_select_opts = config.adapter_select_options
13
17
 
@@ -24,17 +28,10 @@ module Listen
24
28
  @adapter = adapter_class.new(aconfig)
25
29
  end
26
30
 
27
- def start
28
- adapter.start
29
- end
30
-
31
- def stop
32
- adapter.stop
33
- end
31
+ delegate start: :adapter
32
+ delegate stop: :adapter
34
33
 
35
- def min_delay_between_events
36
- @min_delay_between_events
37
- end
34
+ attr_reader :min_delay_between_events
38
35
 
39
36
  private
40
37