listen 1.3.1 → 2.0.0.beta.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|