listen 3.0.2 → 3.8.0

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,41 +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
- def self.usable?
89
- const_get('OS_REGEXP') =~ RbConfig::CONFIG['target_os']
83
+ def stop
84
+ _stop
85
+ config.queue.close # this causes queue.pop to return `nil` to the front-end
90
86
  end
91
87
 
92
88
  private
93
89
 
90
+ def _stop
91
+ @run_thread&.kill
92
+ @run_thread = nil
93
+ end
94
+
94
95
  def _timed(title)
95
- start = Time.now.to_f
96
+ start = MonotonicTime.now
96
97
  yield
97
- diff = Time.now.to_f - start
98
- Listen::Logger.info format('%s: %.05f seconds', title, diff)
98
+ diff = MonotonicTime.now - start
99
+ Listen.logger.info format('%s: %.05f seconds', title, diff)
99
100
  rescue
100
- Listen::Logger.warn "#{title} crashed: #{$ERROR_INFO.inspect}"
101
+ Listen.logger.warn "#{title} crashed: #{$ERROR_INFO.inspect}"
101
102
  raise
102
103
  end
103
104
 
@@ -107,10 +108,6 @@ module Listen
107
108
  @snapshots[dir].invalidate(type, rel_path, options)
108
109
  end
109
110
 
110
- def _log(*args, &block)
111
- self.class.send(:_log, *args, &block)
112
- end
113
-
114
111
  def _log_exception(msg, caller_stack)
115
112
  formatted = format(
116
113
  msg,
@@ -119,11 +116,13 @@ module Listen
119
116
  caller_stack * "\n"
120
117
  )
121
118
 
122
- _log(:error, formatted)
119
+ Listen.logger.error(formatted)
123
120
  end
124
121
 
125
- def self._log(*args, &block)
126
- Listen::Logger.send(*args, &block)
122
+ class << self
123
+ def usable?
124
+ const_get('OS_REGEXP') =~ RbConfig::CONFIG['target_os']
125
+ end
127
126
  end
128
127
  end
129
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,19 +1,27 @@
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)
11
+ # Default to current directory if no directories are supplied
12
+ directories = [Dir.pwd] if directories.to_a.empty?
13
+
12
14
  # TODO: fix (flatten, array, compact?)
13
15
  @directories = directories.map do |directory|
14
16
  Pathname.new(directory.to_s).realpath
15
17
  end
16
18
 
19
+ @directories.each do |pathname|
20
+ unless pathname.directory?
21
+ fail ArgumentError, "must be a directory: #{pathname}"
22
+ end
23
+ end
24
+
17
25
  @silencer = silencer
18
26
  @queue = queue
19
27
  @adapter_options = adapter_options
@@ -1,52 +1,76 @@
1
- require 'listen/internals/thread_pool'
1
+ # frozen_string_literal: true
2
+
3
+ require 'listen/thread'
2
4
 
3
5
  module Listen
4
6
  module Adapter
5
7
  # Adapter implementation for Mac OS X `FSEvents`.
6
8
  #
7
9
  class Darwin < Base
8
- OS_REGEXP = /darwin(1.+)?$/i
10
+ OS_REGEXP = /darwin(?<major_version>(1|2)\d+)/i.freeze
9
11
 
10
12
  # The default delay between checking for changes.
11
- DEFAULTS = { latency: 0.1 }
13
+ DEFAULTS = { latency: 0.1 }.freeze
12
14
 
13
- private
15
+ INCOMPATIBLE_GEM_VERSION = <<-EOS.gsub(/^ {8}/, '')
16
+ rb-fsevent > 0.9.4 no longer supports OS X 10.6 through 10.8.
17
+
18
+ Please add the following to your Gemfile to avoid polling for changes:
19
+ require 'rbconfig'
20
+ if RbConfig::CONFIG['target_os'] =~ /darwin(1[0-3])/i
21
+ gem 'rb-fsevent', '<= 0.9.4'
22
+ end
23
+ EOS
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
14
29
 
15
- # NOTE: each directory gets a DIFFERENT callback!
16
- def _configure(dir, &callback)
17
30
  require 'rb-fsevent'
18
- opts = { latency: options.latency }
31
+ fsevent_version = Gem::Version.new(FSEvent::VERSION)
32
+ return true if fsevent_version <= Gem::Version.new('0.9.4')
33
+ Kernel.warn INCOMPATIBLE_GEM_VERSION
34
+ false
35
+ end
19
36
 
20
- @workers ||= Queue.new
21
- @workers << FSEvent.new.tap do |worker|
22
- worker.watch(dir.to_s, opts, &callback)
23
- end
37
+ private
38
+
39
+ def _configure(dir, &callback)
40
+ @callbacks[dir] = callback
24
41
  end
25
42
 
26
- # NOTE: _run is called within a thread, so run every other
27
- # worker in it's own thread
28
43
  def _run
29
- first = @workers.pop
30
- until @workers.empty?
31
- Listen::Internals::ThreadPool.add do
32
- begin
33
- @workers.pop.run
34
- rescue
35
- _log_exception 'run() in extra thread(s) failed: %s: %s'
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 }
50
+ end
51
+
52
+ def _process_changes(dirs)
53
+ dirs.each do |dir|
54
+ dir = Pathname.new(dir.sub(%r{/$}, ''))
55
+
56
+ @callbacks.each do |watched_dir, callback|
57
+ if watched_dir.eql?(dir) || Listen::Directory.ascendant_of?(watched_dir, dir)
58
+ callback.call(dir)
36
59
  end
37
60
  end
38
61
  end
39
- first.run
40
62
  end
41
63
 
42
- def _process_event(dir, event)
43
- event.each do |path|
44
- new_path = Pathname.new(path.sub(/\/$/, ''))
45
- _log :debug, "fsevent: #{new_path}"
46
- # TODO: does this preserve symlinks?
47
- rel_path = new_path.relative_path_from(dir).to_s
48
- _queue_change(:dir, dir, rel_path, recursive: true)
49
- 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)
69
+ end
70
+
71
+ def _stop
72
+ @worker_thread&.kill
73
+ super
50
74
  end
51
75
  end
52
76
  end
@@ -1,43 +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
- Kernel.require 'rb-inotify'
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
38
  @worker.run
39
39
  end
40
40
 
41
+ # rubocop:disable Metrics/MethodLength
41
42
  def _process_event(dir, event)
42
43
  # NOTE: avoid using event.absolute_name since new API
43
44
  # will need to have a custom recursion implemented
@@ -45,15 +46,13 @@ module Listen
45
46
  path = Pathname.new(event.watcher.path) + event.name
46
47
  rel_path = path.relative_path_from(dir).to_s
47
48
 
48
- _log(:debug) { "inotify: #{rel_path} (#{event.flags.inspect})" }
49
+ Listen.logger.debug { "inotify: #{rel_path} (#{event.flags.inspect})" }
49
50
 
50
51
  if /1|true/ =~ ENV['LISTEN_GEM_SIMULATE_FSEVENT']
51
52
  if (event.flags & [:moved_to, :moved_from]) || _dir_event?(event)
52
53
  rel_path = path.dirname.relative_path_from(dir).to_s
53
- _queue_change(:dir, dir, rel_path, {})
54
- else
55
- _queue_change(:dir, dir, rel_path, {})
56
54
  end
55
+ _queue_change(:dir, dir, rel_path, {})
57
56
  return
58
57
  end
59
58
 
@@ -72,6 +71,7 @@ module Listen
72
71
 
73
72
  _queue_change(:file, dir, rel_path, params)
74
73
  end
74
+ # rubocop:enable Metrics/MethodLength
75
75
 
76
76
  def _skip_event?(event)
77
77
  # Event on root directory
@@ -97,6 +97,12 @@ module Listen
97
97
  def _dir_event?(event)
98
98
  event.flags.include?(:isdir)
99
99
  end
100
+
101
+ def _stop
102
+ @worker&.close
103
+
104
+ super
105
+ end
100
106
  end
101
107
  end
102
108
  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,11 +1,17 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'listen/adapter'
2
4
  require 'listen/adapter/base'
3
5
  require 'listen/adapter/config'
4
6
 
7
+ require 'forwardable'
8
+
5
9
  # This class just aggregates configuration object to avoid Listener specs
6
10
  # from exploding with huge test setup blocks
7
11
  module Listen
8
12
  class Backend
13
+ extend Forwardable
14
+
9
15
  def initialize(directories, queue, silencer, config)
10
16
  adapter_select_opts = config.adapter_select_options
11
17
 
@@ -22,17 +28,10 @@ module Listen
22
28
  @adapter = adapter_class.new(aconfig)
23
29
  end
24
30
 
25
- def start
26
- adapter.start
27
- end
31
+ delegate start: :adapter
32
+ delegate stop: :adapter
28
33
 
29
- def stop
30
- # TODO: does nothing
31
- end
32
-
33
- def min_delay_between_events
34
- @min_delay_between_events
35
- end
34
+ attr_reader :min_delay_between_events
36
35
 
37
36
  private
38
37