listen 3.2.1 → 3.3.0.pre.2
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.
- checksums.yaml +4 -4
- data/README.md +7 -6
- data/lib/listen.rb +15 -20
- data/lib/listen/adapter.rb +6 -8
- data/lib/listen/adapter/base.rb +17 -29
- data/lib/listen/adapter/bsd.rb +3 -1
- data/lib/listen/adapter/config.rb +2 -0
- data/lib/listen/adapter/darwin.rb +10 -12
- data/lib/listen/adapter/linux.rb +6 -4
- data/lib/listen/adapter/polling.rb +2 -0
- data/lib/listen/adapter/windows.rb +6 -4
- data/lib/listen/backend.rb +2 -0
- data/lib/listen/change.rb +5 -3
- data/lib/listen/cli.rb +3 -2
- data/lib/listen/directory.rb +4 -2
- data/lib/listen/event/config.rb +8 -18
- data/lib/listen/event/loop.rb +43 -64
- data/lib/listen/event/processor.rb +26 -24
- data/lib/listen/event/queue.rb +4 -5
- data/lib/listen/file.rb +9 -2
- data/lib/listen/fsm.rb +69 -71
- data/lib/listen/listener.rb +24 -23
- data/lib/listen/listener/config.rb +2 -0
- data/lib/listen/logger.rb +27 -24
- data/lib/listen/options.rb +3 -1
- data/lib/listen/queue_optimizer.rb +2 -0
- data/lib/listen/record.rb +16 -2
- data/lib/listen/record/entry.rb +3 -1
- data/lib/listen/record/symlink_detector.rb +2 -0
- data/lib/listen/silencer.rb +2 -0
- data/lib/listen/silencer/controller.rb +2 -0
- data/lib/listen/thread.rb +47 -0
- data/lib/listen/version.rb +3 -1
- metadata +9 -25
- data/lib/listen/internals/thread_pool.rb +0 -29
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 82d32d20751964de477dd8c2ff8af48cc0c70558b323c1043b37d5bf9183c3ba
|
4
|
+
data.tar.gz: fb40a33b41e0bf52ce30303fc88a7fb1dd35a9d56e2e920fccf598fcd7193c17
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 14e679e027bb5c100eaf438f10ec96ce5336465366facf7559a19ed6fa23d0c6e89f72eba25fb53a1e689ca08d0572d54399826b3d78d5cb354f2b2c7d105b61
|
7
|
+
data.tar.gz: 4b4f93d99b7519d06a7302152e8d86332edb8a656caef7c1b164596d79c221d539ad0a29481709915070945e46fb1c4661bde3368f0e9c55cd277ffe52bc8b13
|
data/README.md
CHANGED
@@ -1,13 +1,14 @@
|
|
1
|
-
## IMPORTANT: If you cannot install Listen (e.g. on Travis/CI builds), [a workaround is here](https://github.com/guard/listen/wiki/Ruby-version-requirements)
|
2
|
-
|
3
|
-
:exclamation: Listen is currently accepting more maintainers. Please [read this](https://github.com/guard/guard/wiki/Maintainers) if you're interested in joining the team.
|
4
|
-
|
5
1
|
# Listen
|
6
2
|
|
7
|
-
[](http://badge.fury.io/rb/listen) [](https://travis-ci.org/guard/listen) [](https://codeclimate.com/github/guard/listen) [](https://coveralls.io/r/guard/listen)
|
8
|
-
|
9
3
|
The Listen gem listens to file modifications and notifies you about the changes.
|
10
4
|
|
5
|
+
:exclamation: Listen is currently accepting more maintainers. Please [read this](https://github.com/guard/guard/wiki/Maintainers) if you're interested in joining the team.
|
6
|
+
|
7
|
+
[](https://github.com/guard/listen/actions?workflow=Development)
|
8
|
+
[](http://badge.fury.io/rb/listen)
|
9
|
+
[](https://codeclimate.com/github/guard/listen)
|
10
|
+
[](https://coveralls.io/r/guard/listen)
|
11
|
+
|
11
12
|
## Features
|
12
13
|
|
13
14
|
* OS-optimized adapters on MRI for Mac OS X 10.6+, Linux, \*BSD and Windows, [more info](#listen-adapters) below.
|
data/lib/listen.rb
CHANGED
@@ -1,23 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'logger'
|
4
|
+
require 'weakref'
|
2
5
|
require 'listen/logger'
|
3
6
|
require 'listen/listener'
|
4
7
|
|
5
|
-
require 'listen/internals/thread_pool'
|
6
|
-
|
7
|
-
# Always set up logging by default first time file is required
|
8
|
-
#
|
9
|
-
# NOTE: If you need to clear the logger completely, do so *after*
|
10
|
-
# requiring this file. If you need to set a custom logger,
|
11
|
-
# require the listen/logger file and set the logger before requiring
|
12
|
-
# this file.
|
13
|
-
Listen.setup_default_logger_if_unset
|
14
|
-
|
15
8
|
# Won't print anything by default because of level - unless you've set
|
16
9
|
# LISTEN_GEM_DEBUGGING or provided your own logger with a high enough level
|
17
|
-
Listen
|
18
|
-
Listen
|
10
|
+
Listen.logger.info "Listen loglevel set to: #{Listen.logger.level}"
|
11
|
+
Listen.logger.info "Listen version: #{Listen::VERSION}"
|
19
12
|
|
20
13
|
module Listen
|
14
|
+
@listeners = Queue.new
|
15
|
+
|
21
16
|
class << self
|
22
17
|
# Listens to file system modifications on a either single directory or
|
23
18
|
# multiple directories.
|
@@ -32,21 +27,21 @@ module Listen
|
|
32
27
|
# @return [Listen::Listener] the listener
|
33
28
|
#
|
34
29
|
def to(*args, &block)
|
35
|
-
@listeners ||= []
|
36
30
|
Listener.new(*args, &block).tap do |listener|
|
37
|
-
@listeners
|
31
|
+
@listeners.enq(WeakRef.new(listener))
|
38
32
|
end
|
39
33
|
end
|
40
34
|
|
41
35
|
# This is used by the `listen` binary to handle Ctrl-C
|
42
36
|
#
|
43
37
|
def stop
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
38
|
+
while (listener = @listeners.deq(true))
|
39
|
+
begin
|
40
|
+
listener.stop
|
41
|
+
rescue WeakRef::RefError
|
42
|
+
end
|
43
|
+
end
|
44
|
+
rescue ThreadError
|
50
45
|
end
|
51
46
|
end
|
52
47
|
end
|
data/lib/listen/adapter.rb
CHANGED
@@ -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'
|
@@ -13,15 +15,15 @@ module Listen
|
|
13
15
|
|
14
16
|
class << self
|
15
17
|
def select(options = {})
|
16
|
-
|
18
|
+
Listen.logger.debug 'Adapter: considering polling ...'
|
17
19
|
return Polling if options[:force_polling]
|
18
|
-
|
20
|
+
Listen.logger.debug 'Adapter: considering optimized backend...'
|
19
21
|
return _usable_adapter_class if _usable_adapter_class
|
20
|
-
|
22
|
+
Listen.logger.debug 'Adapter: falling back to polling...'
|
21
23
|
_warn_polling_fallback(options)
|
22
24
|
Polling
|
23
25
|
rescue
|
24
|
-
|
26
|
+
Listen.logger.warn format('Adapter: failed: %s:%s', $ERROR_POSITION.inspect,
|
25
27
|
$ERROR_POSITION * "\n")
|
26
28
|
raise
|
27
29
|
end
|
@@ -36,10 +38,6 @@ module Listen
|
|
36
38
|
msg = options.fetch(:polling_fallback_message, POLLING_FALLBACK_MESSAGE)
|
37
39
|
Kernel.warn "[Listen warning]:\n #{msg}" if msg
|
38
40
|
end
|
39
|
-
|
40
|
-
def _log(type, message)
|
41
|
-
Listen::Logger.send(type, message)
|
42
|
-
end
|
43
41
|
end
|
44
42
|
end
|
45
43
|
end
|
data/lib/listen/adapter/base.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
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
|
@@ -30,7 +33,7 @@ module Listen
|
|
30
33
|
# TODO: it's a separate method as a temporary workaround for tests
|
31
34
|
def configure
|
32
35
|
if @configured
|
33
|
-
|
36
|
+
Listen.logger.warn('Adapter already configured!')
|
34
37
|
return
|
35
38
|
end
|
36
39
|
|
@@ -63,48 +66,39 @@ module Listen
|
|
63
66
|
configure
|
64
67
|
|
65
68
|
if started?
|
66
|
-
|
69
|
+
Listen.logger.warn('Adapter already started!')
|
67
70
|
return
|
68
71
|
end
|
69
72
|
|
70
73
|
@started = true
|
71
74
|
|
72
|
-
|
73
|
-
|
74
|
-
|
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.values.each 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
|
-
|
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
96
|
start = Time.now.to_f
|
103
97
|
yield
|
104
98
|
diff = Time.now.to_f - start
|
105
|
-
Listen
|
99
|
+
Listen.logger.info format('%s: %.05f seconds', title, diff)
|
106
100
|
rescue
|
107
|
-
Listen
|
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,14 +116,12 @@ module Listen
|
|
126
116
|
caller_stack * "\n"
|
127
117
|
)
|
128
118
|
|
129
|
-
|
119
|
+
Listen.logger.error(formatted)
|
130
120
|
end
|
131
121
|
|
132
122
|
class << self
|
133
|
-
|
134
|
-
|
135
|
-
def _log(*args, &block)
|
136
|
-
Listen::Logger.send(*args, &block)
|
123
|
+
def usable?
|
124
|
+
const_get('OS_REGEXP') =~ RbConfig::CONFIG['target_os']
|
137
125
|
end
|
138
126
|
end
|
139
127
|
end
|
data/lib/listen/adapter/bsd.rb
CHANGED
@@ -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
|
@@ -94,7 +96,7 @@ module Listen
|
|
94
96
|
def _watch_file(path, queue)
|
95
97
|
queue.watch_file(path, *options.events, &@callback)
|
96
98
|
rescue Errno::ENOENT => e
|
97
|
-
|
99
|
+
Listen.logger.warn "kqueue: watch file failed: #{e.message}"
|
98
100
|
end
|
99
101
|
|
100
102
|
# Quick rubocop workaround
|
@@ -1,12 +1,13 @@
|
|
1
|
-
|
2
|
-
|
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
|
10
11
|
|
11
12
|
# The default delay between checking for changes.
|
12
13
|
DEFAULTS = { latency: 0.1 }.freeze
|
@@ -43,9 +44,9 @@ module Listen
|
|
43
44
|
require 'rb-fsevent'
|
44
45
|
worker = FSEvent.new
|
45
46
|
dirs_to_watch = @callbacks.keys.map(&:to_s)
|
46
|
-
|
47
|
+
Listen.logger.info { "fsevent: watching: #{dirs_to_watch.inspect}" }
|
47
48
|
worker.watch(dirs_to_watch, { latency: options.latency }, &method(:_process_changes))
|
48
|
-
Listen::
|
49
|
+
@worker_thread = Listen::Thread.new("worker_thread") { worker.run }
|
49
50
|
end
|
50
51
|
|
51
52
|
def _process_changes(dirs)
|
@@ -61,18 +62,15 @@ module Listen
|
|
61
62
|
end
|
62
63
|
|
63
64
|
def _process_event(dir, path)
|
64
|
-
|
65
|
+
Listen.logger.debug { "fsevent: processing path: #{path.inspect}" }
|
65
66
|
# TODO: does this preserve symlinks?
|
66
67
|
rel_path = path.relative_path_from(dir).to_s
|
67
68
|
_queue_change(:dir, dir, rel_path, recursive: true)
|
68
69
|
end
|
69
70
|
|
70
|
-
def
|
71
|
-
|
72
|
-
|
73
|
-
rescue
|
74
|
-
format_string = 'fsevent: running worker failed: %s:%s called from: %s'
|
75
|
-
_log_exception format_string, caller
|
71
|
+
def _stop
|
72
|
+
@worker_thread&.kill
|
73
|
+
super
|
76
74
|
end
|
77
75
|
end
|
78
76
|
end
|
data/lib/listen/adapter/linux.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Listen
|
2
4
|
module Adapter
|
3
5
|
# @see https://github.com/nex3/rb-inotify
|
@@ -35,9 +37,7 @@ module Listen
|
|
35
37
|
end
|
36
38
|
|
37
39
|
def _run
|
38
|
-
Thread.current[:listen_blocking_read_thread] = true
|
39
40
|
@worker.run
|
40
|
-
Thread.current[:listen_blocking_read_thread] = false
|
41
41
|
end
|
42
42
|
|
43
43
|
def _process_event(dir, event)
|
@@ -47,7 +47,7 @@ module Listen
|
|
47
47
|
path = Pathname.new(event.watcher.path) + event.name
|
48
48
|
rel_path = path.relative_path_from(dir).to_s
|
49
49
|
|
50
|
-
|
50
|
+
Listen.logger.debug { "inotify: #{rel_path} (#{event.flags.inspect})" }
|
51
51
|
|
52
52
|
if /1|true/ =~ ENV['LISTEN_GEM_SIMULATE_FSEVENT']
|
53
53
|
if (event.flags & [:moved_to, :moved_from]) || _dir_event?(event)
|
@@ -99,7 +99,9 @@ module Listen
|
|
99
99
|
end
|
100
100
|
|
101
101
|
def _stop
|
102
|
-
@worker
|
102
|
+
@worker&.close
|
103
|
+
|
104
|
+
super
|
103
105
|
end
|
104
106
|
end
|
105
107
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Listen
|
2
4
|
module Adapter
|
3
5
|
# Adapter implementation for Windows `wdm`.
|
@@ -15,7 +17,7 @@ module Listen
|
|
15
17
|
require 'wdm'
|
16
18
|
true
|
17
19
|
rescue LoadError
|
18
|
-
|
20
|
+
Listen.logger.debug format('wdm - load failed: %s:%s', $ERROR_INFO,
|
19
21
|
$ERROR_POSITION * "\n")
|
20
22
|
|
21
23
|
Kernel.warn BUNDLER_DECLARE_GEM
|
@@ -26,7 +28,7 @@ module Listen
|
|
26
28
|
|
27
29
|
def _configure(dir)
|
28
30
|
require 'wdm'
|
29
|
-
|
31
|
+
Listen.logger.debug 'wdm - starting...'
|
30
32
|
@worker ||= WDM::Monitor.new
|
31
33
|
@worker.watch_recursively(dir.to_s, :files) do |change|
|
32
34
|
yield([:file, change])
|
@@ -47,7 +49,7 @@ module Listen
|
|
47
49
|
end
|
48
50
|
|
49
51
|
def _process_event(dir, event)
|
50
|
-
|
52
|
+
Listen.logger.debug "wdm - callback: #{event.inspect}"
|
51
53
|
|
52
54
|
type, change = event
|
53
55
|
|
@@ -80,7 +82,7 @@ module Listen
|
|
80
82
|
end
|
81
83
|
rescue
|
82
84
|
details = event.inspect
|
83
|
-
|
85
|
+
Listen.logger.error format('wdm - callback (%s): %s:%s', details, $ERROR_INFO,
|
84
86
|
$ERROR_POSITION * "\n")
|
85
87
|
raise
|
86
88
|
end
|
data/lib/listen/backend.rb
CHANGED
data/lib/listen/change.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'listen/file'
|
2
4
|
require 'listen/directory'
|
3
5
|
|
@@ -35,13 +37,13 @@ module Listen
|
|
35
37
|
cookie = options[:cookie]
|
36
38
|
|
37
39
|
if !cookie && config.silenced?(rel_path, type)
|
38
|
-
Listen
|
40
|
+
Listen.logger.debug { "(silenced): #{rel_path.inspect}" }
|
39
41
|
return
|
40
42
|
end
|
41
43
|
|
42
44
|
path = watched_dir + rel_path
|
43
45
|
|
44
|
-
Listen
|
46
|
+
Listen.logger.debug do
|
45
47
|
log_details = options[:silence] && 'recording' || change || 'unknown'
|
46
48
|
"#{log_details}: #{type}:#{path} (#{options.inspect})"
|
47
49
|
end
|
@@ -65,7 +67,7 @@ module Listen
|
|
65
67
|
__method__,
|
66
68
|
exinspect,
|
67
69
|
ex.backtrace * "\n")
|
68
|
-
Listen
|
70
|
+
Listen.logger.error(msg)
|
69
71
|
raise
|
70
72
|
end
|
71
73
|
|
data/lib/listen/cli.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'thor'
|
2
4
|
require 'listen'
|
3
5
|
require 'logger'
|
@@ -35,8 +37,7 @@ module Listen
|
|
35
37
|
attr_reader :logger
|
36
38
|
def initialize(options)
|
37
39
|
@options = options
|
38
|
-
@logger = ::Logger.new(STDOUT)
|
39
|
-
@logger.level = ::Logger::INFO
|
40
|
+
@logger = ::Logger.new(STDOUT, level: ::Logger::INFO)
|
40
41
|
@logger.formatter = proc { |_, _, _, msg| "#{msg}\n" }
|
41
42
|
end
|
42
43
|
|
data/lib/listen/directory.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'set'
|
2
4
|
|
3
5
|
module Listen
|
@@ -14,7 +16,7 @@ module Listen
|
|
14
16
|
path = dir + rel_path
|
15
17
|
current = Set.new(_children(path))
|
16
18
|
|
17
|
-
Listen
|
19
|
+
Listen.logger.debug do
|
18
20
|
format('%s: %s(%s): %s -> %s',
|
19
21
|
(options[:silence] ? 'Recording' : 'Scanning'),
|
20
22
|
rel_path, options.inspect, previous.inspect, current.inspect)
|
@@ -47,7 +49,7 @@ module Listen
|
|
47
49
|
_async_changes(snapshot, path, previous, options)
|
48
50
|
_change(snapshot, :file, rel_path, options)
|
49
51
|
rescue
|
50
|
-
Listen
|
52
|
+
Listen.logger.warn do
|
51
53
|
format('scan DIED: %s:%s', $ERROR_INFO, $ERROR_POSITION * "\n")
|
52
54
|
end
|
53
55
|
raise
|