listen 3.2.1 → 3.3.0.pre.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
[![Gem Version](https://badge.fury.io/rb/listen.svg)](http://badge.fury.io/rb/listen) [![Build Status](https://travis-ci.org/guard/listen.svg)](https://travis-ci.org/guard/listen) [![Code Climate](https://codeclimate.com/github/guard/listen.svg)](https://codeclimate.com/github/guard/listen) [![Coverage Status](https://coveralls.io/repos/guard/listen/badge.svg?branch=master)](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
|
+
[![Development Status](https://github.com/guard/listen/workflows/Development/badge.svg)](https://github.com/guard/listen/actions?workflow=Development)
|
8
|
+
[![Gem Version](https://badge.fury.io/rb/listen.svg)](http://badge.fury.io/rb/listen)
|
9
|
+
[![Code Climate](https://codeclimate.com/github/guard/listen.svg)](https://codeclimate.com/github/guard/listen)
|
10
|
+
[![Coverage Status](https://coveralls.io/repos/guard/listen/badge.svg?branch=master)](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
|