listen 1.3.1 → 2.0.0.beta.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1 -368
- data/README.md +82 -215
- data/lib/listen.rb +2 -36
- data/lib/listen/adapter.rb +23 -304
- data/lib/listen/adapter/base.rb +40 -0
- data/lib/listen/adapter/bsd.rb +93 -0
- data/lib/listen/adapter/darwin.rb +44 -0
- data/lib/listen/adapter/linux.rb +92 -0
- data/lib/listen/adapter/polling.rb +49 -0
- data/lib/listen/adapter/windows.rb +63 -0
- data/lib/listen/change.rb +42 -0
- data/lib/listen/directory.rb +73 -0
- data/lib/listen/file.rb +108 -0
- data/lib/listen/listener.rb +69 -260
- data/lib/listen/record.rb +41 -0
- data/lib/listen/silencer.rb +44 -0
- data/lib/listen/version.rb +1 -1
- metadata +35 -17
- data/lib/listen/adapters/bsd.rb +0 -75
- data/lib/listen/adapters/darwin.rb +0 -48
- data/lib/listen/adapters/linux.rb +0 -81
- data/lib/listen/adapters/polling.rb +0 -58
- data/lib/listen/adapters/windows.rb +0 -91
- data/lib/listen/directory_record.rb +0 -406
- data/lib/listen/turnstile.rb +0 -32
data/lib/listen/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: listen
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0.beta.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Thibaud Guillaume-Gentil
|
@@ -9,8 +9,22 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-09-
|
12
|
+
date: 2013-09-14 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: celluloid
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - '>='
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: 0.15.1
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - '>='
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: 0.15.1
|
14
28
|
- !ruby/object:Gem::Dependency
|
15
29
|
name: rb-fsevent
|
16
30
|
requirement: !ruby/object:Gem::Requirement
|
@@ -40,21 +54,21 @@ dependencies:
|
|
40
54
|
- !ruby/object:Gem::Version
|
41
55
|
version: '0.9'
|
42
56
|
- !ruby/object:Gem::Dependency
|
43
|
-
name:
|
57
|
+
name: bundler
|
44
58
|
requirement: !ruby/object:Gem::Requirement
|
45
59
|
requirements:
|
46
60
|
- - '>='
|
47
61
|
- !ruby/object:Gem::Version
|
48
|
-
version: '0
|
49
|
-
type: :
|
62
|
+
version: '0'
|
63
|
+
type: :development
|
50
64
|
prerelease: false
|
51
65
|
version_requirements: !ruby/object:Gem::Requirement
|
52
66
|
requirements:
|
53
67
|
- - '>='
|
54
68
|
- !ruby/object:Gem::Version
|
55
|
-
version: '0
|
69
|
+
version: '0'
|
56
70
|
- !ruby/object:Gem::Dependency
|
57
|
-
name:
|
71
|
+
name: rspec
|
58
72
|
requirement: !ruby/object:Gem::Requirement
|
59
73
|
requirements:
|
60
74
|
- - '>='
|
@@ -68,7 +82,7 @@ dependencies:
|
|
68
82
|
- !ruby/object:Gem::Version
|
69
83
|
version: '0'
|
70
84
|
- !ruby/object:Gem::Dependency
|
71
|
-
name: rspec
|
85
|
+
name: rspec-retry
|
72
86
|
requirement: !ruby/object:Gem::Requirement
|
73
87
|
requirements:
|
74
88
|
- - '>='
|
@@ -90,15 +104,19 @@ executables: []
|
|
90
104
|
extensions: []
|
91
105
|
extra_rdoc_files: []
|
92
106
|
files:
|
107
|
+
- lib/listen/adapter/base.rb
|
108
|
+
- lib/listen/adapter/bsd.rb
|
109
|
+
- lib/listen/adapter/darwin.rb
|
110
|
+
- lib/listen/adapter/linux.rb
|
111
|
+
- lib/listen/adapter/polling.rb
|
112
|
+
- lib/listen/adapter/windows.rb
|
93
113
|
- lib/listen/adapter.rb
|
94
|
-
- lib/listen/
|
95
|
-
- lib/listen/
|
96
|
-
- lib/listen/
|
97
|
-
- lib/listen/adapters/polling.rb
|
98
|
-
- lib/listen/adapters/windows.rb
|
99
|
-
- lib/listen/directory_record.rb
|
114
|
+
- lib/listen/change.rb
|
115
|
+
- lib/listen/directory.rb
|
116
|
+
- lib/listen/file.rb
|
100
117
|
- lib/listen/listener.rb
|
101
|
-
- lib/listen/
|
118
|
+
- lib/listen/record.rb
|
119
|
+
- lib/listen/silencer.rb
|
102
120
|
- lib/listen/version.rb
|
103
121
|
- lib/listen.rb
|
104
122
|
- CHANGELOG.md
|
@@ -116,7 +134,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
116
134
|
requirements:
|
117
135
|
- - '>='
|
118
136
|
- !ruby/object:Gem::Version
|
119
|
-
version:
|
137
|
+
version: 1.9.3
|
120
138
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
121
139
|
requirements:
|
122
140
|
- - '>='
|
@@ -124,7 +142,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
124
142
|
version: 1.3.6
|
125
143
|
requirements: []
|
126
144
|
rubyforge_project: listen
|
127
|
-
rubygems_version: 2.
|
145
|
+
rubygems_version: 2.1.3
|
128
146
|
signing_key:
|
129
147
|
specification_version: 4
|
130
148
|
summary: Listen to file modifications
|
data/lib/listen/adapters/bsd.rb
DELETED
@@ -1,75 +0,0 @@
|
|
1
|
-
module Listen
|
2
|
-
module Adapters
|
3
|
-
|
4
|
-
# Listener implementation for BSD's `kqueue`.
|
5
|
-
#
|
6
|
-
class BSD < Adapter
|
7
|
-
# Watched kqueue events
|
8
|
-
#
|
9
|
-
# @see http://www.freebsd.org/cgi/man.cgi?query=kqueue
|
10
|
-
# @see https://github.com/nex3/rb-kqueue/blob/master/lib/rb-kqueue/queue.rb
|
11
|
-
#
|
12
|
-
EVENTS = [:delete, :write, :extend, :attrib, :link, :rename, :revoke]
|
13
|
-
|
14
|
-
def self.target_os_regex; /freebsd/i; end
|
15
|
-
def self.adapter_gem; 'rb-kqueue'; end
|
16
|
-
|
17
|
-
private
|
18
|
-
|
19
|
-
# Initializes a kqueue Queue and adds a watcher for each files in
|
20
|
-
# the directories passed to the adapter.
|
21
|
-
#
|
22
|
-
# @return [INotify::Notifier] initialized kqueue
|
23
|
-
#
|
24
|
-
# @see Listen::Adapter#initialize_worker
|
25
|
-
#
|
26
|
-
def initialize_worker
|
27
|
-
require 'find'
|
28
|
-
|
29
|
-
callback = lambda do |event|
|
30
|
-
path = event.watcher.path
|
31
|
-
mutex.synchronize do
|
32
|
-
# kqueue watches everything, but Listen only needs the
|
33
|
-
# directory where stuffs happens.
|
34
|
-
@changed_directories << (File.directory?(path) ? path : File.dirname(path))
|
35
|
-
|
36
|
-
# If it is a directory, and it has a write flag, it means a
|
37
|
-
# file has been added so find out which and deal with it.
|
38
|
-
# No need to check for removed files, kqueue will forget them
|
39
|
-
# when the vfs does.
|
40
|
-
if File.directory?(path) && event.flags.include?(:write)
|
41
|
-
queue = event.watcher.queue
|
42
|
-
Find.find(path) do |file|
|
43
|
-
unless queue.watchers.detect { |k,v| v.path == file.to_s }
|
44
|
-
queue.watch_file(file, *EVENTS, &callback)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
KQueue::Queue.new.tap do |queue|
|
52
|
-
directories.each do |directory|
|
53
|
-
Find.find(directory) do |path|
|
54
|
-
queue.watch_file(path, *EVENTS, &callback)
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
# Starts the worker in a new thread.
|
61
|
-
#
|
62
|
-
# @see Listen::Adapter#start_worker
|
63
|
-
#
|
64
|
-
def start_worker
|
65
|
-
@worker_thread = Thread.new do
|
66
|
-
until stopped
|
67
|
-
worker.poll
|
68
|
-
sleep(latency)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
end
|
75
|
-
end
|
@@ -1,48 +0,0 @@
|
|
1
|
-
module Listen
|
2
|
-
module Adapters
|
3
|
-
|
4
|
-
# Adapter implementation for Mac OS X `FSEvents`.
|
5
|
-
#
|
6
|
-
class Darwin < Adapter
|
7
|
-
LAST_SEPARATOR_REGEX = /\/$/
|
8
|
-
|
9
|
-
|
10
|
-
def self.target_os_regex; /darwin(1.+)?$/i; end
|
11
|
-
def self.adapter_gem; 'rb-fsevent'; end
|
12
|
-
|
13
|
-
private
|
14
|
-
|
15
|
-
# Initializes a FSEvent worker and adds a watcher for
|
16
|
-
# each directory passed to the adapter.
|
17
|
-
#
|
18
|
-
# @return [FSEvent] initialized worker
|
19
|
-
#
|
20
|
-
# @see Listen::Adapter#initialize_worker
|
21
|
-
#
|
22
|
-
def initialize_worker
|
23
|
-
FSEvent.new.tap do |worker|
|
24
|
-
worker.watch(directories.dup, :latency => latency) do |changes|
|
25
|
-
next if paused
|
26
|
-
|
27
|
-
mutex.synchronize do
|
28
|
-
changes.each { |path| @changed_directories << path.sub(LAST_SEPARATOR_REGEX, '') }
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
# Starts the worker in a new thread and sleep 0.1 second.
|
35
|
-
#
|
36
|
-
# @see Listen::Adapter#start_worker
|
37
|
-
#
|
38
|
-
def start_worker
|
39
|
-
@worker_thread = Thread.new { worker.run }
|
40
|
-
# The FSEvent worker needs some time to start up. Turnstiles can't
|
41
|
-
# be used to wait for it as it runs in a loop.
|
42
|
-
# TODO: Find a better way to block until the worker starts.
|
43
|
-
sleep 0.1
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
end
|
48
|
-
end
|
@@ -1,81 +0,0 @@
|
|
1
|
-
module Listen
|
2
|
-
module Adapters
|
3
|
-
|
4
|
-
# Listener implementation for Linux `inotify`.
|
5
|
-
#
|
6
|
-
class Linux < Adapter
|
7
|
-
# Watched inotify events
|
8
|
-
#
|
9
|
-
# @see http://www.tin.org/bin/man.cgi?section=7&topic=inotify
|
10
|
-
# @see https://github.com/nex3/rb-inotify/blob/master/lib/rb-inotify/notifier.rb#L99-L177
|
11
|
-
#
|
12
|
-
EVENTS = [:recursive, :attrib, :create, :delete, :move, :close_write]
|
13
|
-
|
14
|
-
# The message to show when the limit of inotify watchers is not enough
|
15
|
-
#
|
16
|
-
INOTIFY_LIMIT_MESSAGE = <<-EOS.gsub(/^\s*/, '')
|
17
|
-
Listen error: unable to monitor directories for changes.
|
18
|
-
|
19
|
-
Please head to https://github.com/guard/listen/wiki/Increasing-the-amount-of-inotify-watchers
|
20
|
-
for information on how to solve this issue.
|
21
|
-
EOS
|
22
|
-
|
23
|
-
def self.target_os_regex; /linux/i; end
|
24
|
-
def self.adapter_gem; 'rb-inotify'; end
|
25
|
-
|
26
|
-
# Initializes the Adapter.
|
27
|
-
#
|
28
|
-
# @see Listen::Adapter#initialize
|
29
|
-
#
|
30
|
-
def initialize(directories, options = {}, &callback)
|
31
|
-
super
|
32
|
-
rescue Errno::ENOSPC
|
33
|
-
abort(INOTIFY_LIMIT_MESSAGE)
|
34
|
-
end
|
35
|
-
|
36
|
-
private
|
37
|
-
|
38
|
-
# Initializes a INotify worker and adds a watcher for
|
39
|
-
# each directory passed to the adapter.
|
40
|
-
#
|
41
|
-
# @return [INotify::Notifier] initialized worker
|
42
|
-
#
|
43
|
-
# @see Listen::Adapter#initialize_worker
|
44
|
-
#
|
45
|
-
def initialize_worker
|
46
|
-
callback = lambda do |event|
|
47
|
-
if paused || (
|
48
|
-
# Event on root directory
|
49
|
-
event.name == ""
|
50
|
-
) || (
|
51
|
-
# INotify reports changes to files inside directories as events
|
52
|
-
# on the directories themselves too.
|
53
|
-
#
|
54
|
-
# @see http://linux.die.net/man/7/inotify
|
55
|
-
event.flags.include?(:isdir) and (event.flags & [:close, :modify]).any?
|
56
|
-
)
|
57
|
-
# Skip all of these!
|
58
|
-
next
|
59
|
-
end
|
60
|
-
|
61
|
-
mutex.synchronize do
|
62
|
-
@changed_directories << File.dirname(event.absolute_name)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
INotify::Notifier.new.tap do |worker|
|
67
|
-
directories.each { |dir| worker.watch(dir, *EVENTS, &callback) }
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
# Starts the worker in a new thread.
|
72
|
-
#
|
73
|
-
# @see Listen::Adapter#start_worker
|
74
|
-
#
|
75
|
-
def start_worker
|
76
|
-
@worker_thread = Thread.new { worker.run }
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
end
|
81
|
-
end
|
@@ -1,58 +0,0 @@
|
|
1
|
-
module Listen
|
2
|
-
module Adapters
|
3
|
-
|
4
|
-
DEFAULT_POLLING_LATENCY = 1.0
|
5
|
-
|
6
|
-
# Polling Adapter that works cross-platform and
|
7
|
-
# has no dependencies. This is the adapter that
|
8
|
-
# uses the most CPU processing power and has higher
|
9
|
-
# file IO than the other implementations.
|
10
|
-
#
|
11
|
-
class Polling < Adapter
|
12
|
-
private
|
13
|
-
|
14
|
-
# The default delay between checking for changes.
|
15
|
-
#
|
16
|
-
# @see Listen::Adapter#default_latency
|
17
|
-
#
|
18
|
-
def default_latency
|
19
|
-
1.0
|
20
|
-
end
|
21
|
-
|
22
|
-
# The thread on which the main thread should wait
|
23
|
-
# when the adapter has been started in blocking mode.
|
24
|
-
#
|
25
|
-
# @see Listen::Adapter#blocking_thread
|
26
|
-
#
|
27
|
-
def blocking_thread
|
28
|
-
poller_thread
|
29
|
-
end
|
30
|
-
|
31
|
-
# @see Listen::Adapter#start_worker
|
32
|
-
#
|
33
|
-
# @see Listen::Adapter#start_worker
|
34
|
-
#
|
35
|
-
def start_worker
|
36
|
-
# The polling adapter has no worker! Sad panda! :'(
|
37
|
-
end
|
38
|
-
|
39
|
-
# Poll listener directory for file system changes.
|
40
|
-
#
|
41
|
-
# @see Listen::Adapter#poll_changed_directories
|
42
|
-
#
|
43
|
-
def poll_changed_directories
|
44
|
-
until stopped
|
45
|
-
next if paused
|
46
|
-
|
47
|
-
start = Time.now.to_f
|
48
|
-
callback.call(directories.dup, :recursive => true)
|
49
|
-
turnstile.signal
|
50
|
-
nap_time = latency - (Time.now.to_f - start)
|
51
|
-
sleep(nap_time) if nap_time > 0
|
52
|
-
end
|
53
|
-
rescue Interrupt
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
end
|
58
|
-
end
|
@@ -1,91 +0,0 @@
|
|
1
|
-
require 'set'
|
2
|
-
require 'rubygems'
|
3
|
-
|
4
|
-
module Listen
|
5
|
-
module Adapters
|
6
|
-
|
7
|
-
# Adapter implementation for Windows `wdm`.
|
8
|
-
#
|
9
|
-
class Windows < Adapter
|
10
|
-
|
11
|
-
BUNDLER_DECLARE_GEM = <<-EOS.gsub(/^ {6}/, '')
|
12
|
-
Please add the following to your Gemfile to avoid polling for changes:
|
13
|
-
require 'rbconfig'
|
14
|
-
gem 'wdm', '>= 0.1.0' if RbConfig::CONFIG['target_os'] =~ /mswin|mingw/i
|
15
|
-
EOS
|
16
|
-
|
17
|
-
def self.target_os_regex; /mswin|mingw/i; end
|
18
|
-
def self.adapter_gem; 'wdm'; end
|
19
|
-
|
20
|
-
# Checks if the adapter is usable on target OS.
|
21
|
-
#
|
22
|
-
# @return [Boolean] whether usable or not
|
23
|
-
#
|
24
|
-
def self.usable?
|
25
|
-
super if mri? && at_least_ruby_1_9?
|
26
|
-
end
|
27
|
-
|
28
|
-
# Load the adapter gem
|
29
|
-
#
|
30
|
-
# @return [Boolean] whether required or not
|
31
|
-
#
|
32
|
-
def self.load_dependent_adapter
|
33
|
-
super
|
34
|
-
rescue Gem::LoadError
|
35
|
-
Kernel.warn BUNDLER_DECLARE_GEM
|
36
|
-
end
|
37
|
-
|
38
|
-
private
|
39
|
-
|
40
|
-
# Checks if Ruby engine is MRI.
|
41
|
-
#
|
42
|
-
# @return [Boolean]
|
43
|
-
#
|
44
|
-
def self.mri?
|
45
|
-
defined?(RUBY_ENGINE) && RUBY_ENGINE == 'ruby'
|
46
|
-
end
|
47
|
-
|
48
|
-
# Checks if Ruby engine is MRI.
|
49
|
-
#
|
50
|
-
# @return [Boolean]
|
51
|
-
#
|
52
|
-
def self.at_least_ruby_1_9?
|
53
|
-
Gem::Version.new(RUBY_VERSION.dup) >= Gem::Version.new('1.9.2')
|
54
|
-
end
|
55
|
-
|
56
|
-
# Initializes a WDM monitor and adds a watcher for
|
57
|
-
# each directory passed to the adapter.
|
58
|
-
#
|
59
|
-
# @return [WDM::Monitor] initialized worker
|
60
|
-
#
|
61
|
-
# @see Listen::Adapter#initialize_worker
|
62
|
-
#
|
63
|
-
def initialize_worker
|
64
|
-
callback = Proc.new do |change|
|
65
|
-
next if paused
|
66
|
-
|
67
|
-
mutex.synchronize do
|
68
|
-
@changed_directories << File.dirname(change.path)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
WDM::Monitor.new.tap do |worker|
|
73
|
-
directories.each { |dir| worker.watch_recursively(dir, &callback) }
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
# Start the worker in a new thread and sleep 0.1 second.
|
78
|
-
#
|
79
|
-
# @see Listen::Adapter#start_worker
|
80
|
-
#
|
81
|
-
def start_worker
|
82
|
-
@worker_thread = Thread.new { worker.run! }
|
83
|
-
# Wait for the worker to start. This is needed to avoid a deadlock
|
84
|
-
# when stopping immediately after starting.
|
85
|
-
sleep 0.1
|
86
|
-
end
|
87
|
-
|
88
|
-
end
|
89
|
-
|
90
|
-
end
|
91
|
-
end
|