directory_watcher 1.3.2 → 1.4.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.
- data/.gitignore +14 -0
- data/History.txt +5 -0
- data/bin/dw +2 -0
- data/lib/directory_watcher.rb +23 -6
- data/lib/directory_watcher/coolio_scanner.rb +184 -0
- data/version.txt +1 -1
- metadata +32 -20
data/.gitignore
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# git-ls-files --others --exclude-from=.git/info/exclude
|
2
|
+
# Lines that start with '#' are comments.
|
3
|
+
# For a project mostly in C, the following would be a good set of
|
4
|
+
# exclude patterns (uncomment them if you want to use them):
|
5
|
+
# *.[oa]
|
6
|
+
# *~
|
7
|
+
announcement.txt
|
8
|
+
coverage
|
9
|
+
doc
|
10
|
+
pkg
|
11
|
+
tags
|
12
|
+
temp.dir
|
13
|
+
tmp.rb
|
14
|
+
tmp.yml
|
data/History.txt
CHANGED
data/bin/dw
ADDED
data/lib/directory_watcher.rb
CHANGED
@@ -175,14 +175,14 @@ require 'yaml'
|
|
175
175
|
# This approach is fairly intensive for short intervals and/or directories
|
176
176
|
# with many files.
|
177
177
|
#
|
178
|
-
# DirectoryWatcher supports using
|
179
|
-
# busy polling thread. These libraries use system level kernel hooks to
|
178
|
+
# DirectoryWatcher supports using Cool.io, EventMachine, or Rev instead
|
179
|
+
# of a busy polling thread. These libraries use system level kernel hooks to
|
180
180
|
# receive notifications of file system changes. This makes DirectoryWorker
|
181
181
|
# much more efficient.
|
182
182
|
#
|
183
|
-
# This example will use
|
183
|
+
# This example will use Cool.io to generate file notifications.
|
184
184
|
#
|
185
|
-
# dw = DirectoryWatcher.new '.', :glob => '**/*.rb', :scanner => :
|
185
|
+
# dw = DirectoryWatcher.new '.', :glob => '**/*.rb', :scanner => :coolio
|
186
186
|
# dw.add_observer {|*args| args.each {|event| puts event}}
|
187
187
|
#
|
188
188
|
# dw.start
|
@@ -193,6 +193,17 @@ require 'yaml'
|
|
193
193
|
# created. To use an EventMachine scanner, pass :em as the :scanner
|
194
194
|
# option.
|
195
195
|
#
|
196
|
+
# If you wish to use the Cool.io scanner, then you must have the Cool.io gem
|
197
|
+
# installed. The same goes for EventMachine and Rev. To install any of these
|
198
|
+
# gems run the following on the command line:
|
199
|
+
#
|
200
|
+
# gem install cool.io
|
201
|
+
# gem install eventmachine
|
202
|
+
# gem install rev
|
203
|
+
#
|
204
|
+
# Note: Rev has been replace by Cool.io and support for the Rev scanner will
|
205
|
+
# eventually be dropped from DirectoryWatcher.
|
206
|
+
#
|
196
207
|
# == Contact
|
197
208
|
#
|
198
209
|
# A lot of discussion happens about Ruby in general on the ruby-talk
|
@@ -300,7 +311,7 @@ class DirectoryWatcher
|
|
300
311
|
# from the file when the directory watcher is
|
301
312
|
# stopped and started (respectively)
|
302
313
|
# :scanner => nil the directory scanning strategy to use with
|
303
|
-
# the directory watcher (either :em :rev or nil)
|
314
|
+
# the directory watcher (either :coolio, :em, :rev or nil)
|
304
315
|
#
|
305
316
|
# The default glob pattern will scan all files in the configured directory.
|
306
317
|
# Setting the :stable option to +nil+ will prevent stable events from being
|
@@ -395,7 +406,12 @@ class DirectoryWatcher
|
|
395
406
|
glob.uniq!
|
396
407
|
@scanner.glob = glob
|
397
408
|
end
|
398
|
-
|
409
|
+
|
410
|
+
# Returns the array of glob patterns used to monitor files in the directory.
|
411
|
+
#
|
412
|
+
def glob
|
413
|
+
@scanner.glob
|
414
|
+
end
|
399
415
|
|
400
416
|
# Sets the directory scan interval. The directory will be scanned every
|
401
417
|
# _interval_ seconds for changes to files matching the glob pattern.
|
@@ -569,6 +585,7 @@ end # class DirectoryWatcher
|
|
569
585
|
|
570
586
|
DirectoryWatcher.libpath {
|
571
587
|
require 'directory_watcher/scanner'
|
588
|
+
require 'directory_watcher/coolio_scanner'
|
572
589
|
require 'directory_watcher/em_scanner'
|
573
590
|
require 'directory_watcher/rev_scanner'
|
574
591
|
}
|
@@ -0,0 +1,184 @@
|
|
1
|
+
begin
|
2
|
+
require 'coolio'
|
3
|
+
DirectoryWatcher::HAVE_COOLIO = true
|
4
|
+
rescue LoadError
|
5
|
+
DirectoryWatcher::HAVE_COOLIO = false
|
6
|
+
end
|
7
|
+
|
8
|
+
if DirectoryWatcher::HAVE_COOLIO
|
9
|
+
|
10
|
+
# The CoolioScanner uses the Coolio loop to monitor changes to files in the
|
11
|
+
# watched directory. This scanner is more efficient than the pure Ruby
|
12
|
+
# scanner because it relies on the operating system kernel notifictions
|
13
|
+
# instead of a periodic polling and stat of every file in the watched
|
14
|
+
# directory (the technique used by the Scanner class).
|
15
|
+
#
|
16
|
+
class DirectoryWatcher::CoolioScanner < ::DirectoryWatcher::Scanner
|
17
|
+
|
18
|
+
# call-seq:
|
19
|
+
# CoolioScanner.new { |events| block }
|
20
|
+
#
|
21
|
+
# Create a Coolio based scanner that will generate file events and pass
|
22
|
+
# those events (as an array) to the given _block_.
|
23
|
+
#
|
24
|
+
def initialize( &block )
|
25
|
+
super(&block)
|
26
|
+
@watchers = {}
|
27
|
+
end
|
28
|
+
|
29
|
+
# Start the Coolio scanner loop. If the scanner is already running, this method
|
30
|
+
# will return without taking any action.
|
31
|
+
#
|
32
|
+
def start
|
33
|
+
return if running?
|
34
|
+
|
35
|
+
@timer = Timer.new self
|
36
|
+
@thread = Thread.new {
|
37
|
+
coolio_loop = Thread.current._coolio_loop
|
38
|
+
@files.keys.each do |fn|
|
39
|
+
if test ?e, fn
|
40
|
+
_watch_file fn
|
41
|
+
next
|
42
|
+
end
|
43
|
+
|
44
|
+
@files.delete fn
|
45
|
+
@events << ::DirectoryWatcher::Event.new(:removed, fn)
|
46
|
+
end
|
47
|
+
|
48
|
+
@timer.attach(coolio_loop)
|
49
|
+
coolio_loop.run
|
50
|
+
}
|
51
|
+
end
|
52
|
+
|
53
|
+
# Stop the Coolio scanner loop. If the scanner is already stopped, this method
|
54
|
+
# will return without taking any action.
|
55
|
+
#
|
56
|
+
def stop
|
57
|
+
return unless running?
|
58
|
+
|
59
|
+
@timer.detach
|
60
|
+
@timer = nil
|
61
|
+
|
62
|
+
@watchers.each_value {|w| w.detach}
|
63
|
+
@watchers.clear
|
64
|
+
|
65
|
+
notify
|
66
|
+
|
67
|
+
@thread._coolio_loop.stop rescue nil
|
68
|
+
@thread.kill # for some reason the rev loop is not returning after stopping
|
69
|
+
@thread = nil
|
70
|
+
end
|
71
|
+
|
72
|
+
# :stopdoc:
|
73
|
+
#
|
74
|
+
# This callback is invoked by a Watcher instance when some change has
|
75
|
+
# occured on the file. The scanner determines if the file has been
|
76
|
+
# modified or deleted and notifies the directory watcher accordingly.
|
77
|
+
#
|
78
|
+
def _on_change( watcher )
|
79
|
+
fn = watcher.path
|
80
|
+
stat = watcher.stat
|
81
|
+
|
82
|
+
if stat
|
83
|
+
if @files[fn] != stat
|
84
|
+
@files[fn] = stat
|
85
|
+
@events << ::DirectoryWatcher::Event.new(:modified, fn)
|
86
|
+
end
|
87
|
+
else
|
88
|
+
watcher.detach
|
89
|
+
@watchers.delete fn
|
90
|
+
@files.delete fn
|
91
|
+
@events << ::DirectoryWatcher::Event.new(:removed, fn)
|
92
|
+
end
|
93
|
+
|
94
|
+
notify
|
95
|
+
end
|
96
|
+
|
97
|
+
# This callback is invoked by the Timer instance when it is triggered by
|
98
|
+
# the Coolio loop. This method will check for added files and stable files
|
99
|
+
# and notify the directory watcher accordingly.
|
100
|
+
#
|
101
|
+
def _on_timer
|
102
|
+
_find_added
|
103
|
+
_find_stable
|
104
|
+
notify
|
105
|
+
end
|
106
|
+
# :startdoc:
|
107
|
+
|
108
|
+
|
109
|
+
private
|
110
|
+
|
111
|
+
# From the list of files in the watched directory, find those that we are
|
112
|
+
# not currently watching and add them to the watch list. Generate "added"
|
113
|
+
# events for those newly found files.
|
114
|
+
#
|
115
|
+
def _find_added
|
116
|
+
cur = list_files
|
117
|
+
prev = @files.keys
|
118
|
+
added = cur - prev
|
119
|
+
|
120
|
+
added.each do |fn|
|
121
|
+
@files[fn] = _watch_file(fn).stat
|
122
|
+
@events << ::DirectoryWatcher::Event.new(:added, fn)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
# Iterate over the FileStat instances looking for those with non-nil
|
127
|
+
# stable counts. Decrement these counts and generate "stable" events for
|
128
|
+
# those files whose count reaches zero.
|
129
|
+
#
|
130
|
+
def _find_stable
|
131
|
+
@files.each do |fn, stat|
|
132
|
+
next if stat.stable.nil?
|
133
|
+
stat.stable -= 1
|
134
|
+
if stat.stable <= 0
|
135
|
+
@events << ::DirectoryWatcher::Event.new(:stable, fn)
|
136
|
+
stat.stable = nil
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
# Create and return a new Watcher instance for the given filename _fn_.
|
142
|
+
#
|
143
|
+
def _watch_file( fn )
|
144
|
+
w = Watcher.new(fn, self)
|
145
|
+
w.attach(@thread ? @thread._coolio_loop : Thread.current._coolio_loop)
|
146
|
+
@watchers[fn] = w
|
147
|
+
end
|
148
|
+
|
149
|
+
# :stopdoc:
|
150
|
+
#
|
151
|
+
class Watcher < Coolio::StatWatcher
|
152
|
+
def initialize( fn, scanner )
|
153
|
+
super(fn, scanner.interval)
|
154
|
+
@scanner = scanner
|
155
|
+
end
|
156
|
+
|
157
|
+
def on_change
|
158
|
+
@scanner._on_change self
|
159
|
+
end
|
160
|
+
|
161
|
+
def stat
|
162
|
+
return unless test ?e, path
|
163
|
+
stat = File.stat path
|
164
|
+
::DirectoryWatcher::FileStat.new(stat.mtime, stat.size, @scanner.stable)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
class Timer < Coolio::TimerWatcher
|
169
|
+
def initialize( scanner )
|
170
|
+
super(scanner.interval, true)
|
171
|
+
@scanner = scanner
|
172
|
+
end
|
173
|
+
|
174
|
+
def on_timer
|
175
|
+
@scanner._on_timer
|
176
|
+
end
|
177
|
+
end
|
178
|
+
# :startdoc:
|
179
|
+
|
180
|
+
end # class DirectoryWatcher::CoolioScanner
|
181
|
+
|
182
|
+
end # if DirectoryWatcher::HAVE_COOLIO
|
183
|
+
|
184
|
+
# EOF
|
data/version.txt
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.4.0
|
metadata
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: directory_watcher
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
hash: 7
|
4
5
|
prerelease: false
|
5
6
|
segments:
|
6
7
|
- 1
|
7
|
-
-
|
8
|
-
-
|
9
|
-
version: 1.
|
8
|
+
- 4
|
9
|
+
- 0
|
10
|
+
version: 1.4.0
|
10
11
|
platform: ruby
|
11
12
|
authors:
|
12
13
|
- Tim Pease
|
@@ -14,63 +15,67 @@ autorequire:
|
|
14
15
|
bindir: bin
|
15
16
|
cert_chain: []
|
16
17
|
|
17
|
-
date:
|
18
|
+
date: 2011-03-15 00:00:00 -06:00
|
18
19
|
default_executable:
|
19
20
|
dependencies:
|
20
21
|
- !ruby/object:Gem::Dependency
|
21
22
|
name: bones-git
|
22
23
|
prerelease: false
|
23
24
|
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
24
26
|
requirements:
|
25
27
|
- - ">="
|
26
28
|
- !ruby/object:Gem::Version
|
29
|
+
hash: 23
|
27
30
|
segments:
|
28
31
|
- 1
|
29
|
-
-
|
30
|
-
-
|
31
|
-
version: 1.
|
32
|
+
- 2
|
33
|
+
- 4
|
34
|
+
version: 1.2.4
|
32
35
|
type: :development
|
33
36
|
version_requirements: *id001
|
34
37
|
- !ruby/object:Gem::Dependency
|
35
38
|
name: rev
|
36
39
|
prerelease: false
|
37
40
|
requirement: &id002 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
38
42
|
requirements:
|
39
43
|
- - ">="
|
40
44
|
- !ruby/object:Gem::Version
|
45
|
+
hash: 3
|
41
46
|
segments:
|
42
47
|
- 0
|
43
|
-
|
44
|
-
- 2
|
45
|
-
version: 0.3.2
|
48
|
+
version: "0"
|
46
49
|
type: :development
|
47
50
|
version_requirements: *id002
|
48
51
|
- !ruby/object:Gem::Dependency
|
49
52
|
name: eventmachine
|
50
53
|
prerelease: false
|
51
54
|
requirement: &id003 !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
52
56
|
requirements:
|
53
57
|
- - ">="
|
54
58
|
- !ruby/object:Gem::Version
|
59
|
+
hash: 3
|
55
60
|
segments:
|
56
61
|
- 0
|
57
|
-
|
58
|
-
- 10
|
59
|
-
version: 0.12.10
|
62
|
+
version: "0"
|
60
63
|
type: :development
|
61
64
|
version_requirements: *id003
|
62
65
|
- !ruby/object:Gem::Dependency
|
63
66
|
name: bones
|
64
67
|
prerelease: false
|
65
68
|
requirement: &id004 !ruby/object:Gem::Requirement
|
69
|
+
none: false
|
66
70
|
requirements:
|
67
71
|
- - ">="
|
68
72
|
- !ruby/object:Gem::Version
|
73
|
+
hash: 21
|
69
74
|
segments:
|
70
75
|
- 3
|
71
|
-
-
|
72
|
-
-
|
73
|
-
version: 3.
|
76
|
+
- 6
|
77
|
+
- 5
|
78
|
+
version: 3.6.5
|
74
79
|
type: :development
|
75
80
|
version_requirements: *id004
|
76
81
|
description: |-
|
@@ -80,19 +85,22 @@ description: |-
|
|
80
85
|
dispatched to registered observers. Three types of events are supported --
|
81
86
|
added, modified, and removed.
|
82
87
|
email: tim.pease@gmail.com
|
83
|
-
executables:
|
84
|
-
|
88
|
+
executables:
|
89
|
+
- dw
|
85
90
|
extensions: []
|
86
91
|
|
87
92
|
extra_rdoc_files:
|
88
93
|
- History.txt
|
89
94
|
- README.txt
|
90
|
-
-
|
95
|
+
- bin/dw
|
91
96
|
files:
|
97
|
+
- .gitignore
|
92
98
|
- History.txt
|
93
99
|
- README.txt
|
94
100
|
- Rakefile
|
101
|
+
- bin/dw
|
95
102
|
- lib/directory_watcher.rb
|
103
|
+
- lib/directory_watcher/coolio_scanner.rb
|
96
104
|
- lib/directory_watcher/em_scanner.rb
|
97
105
|
- lib/directory_watcher/rev_scanner.rb
|
98
106
|
- lib/directory_watcher/scanner.rb
|
@@ -108,23 +116,27 @@ rdoc_options:
|
|
108
116
|
require_paths:
|
109
117
|
- lib
|
110
118
|
required_ruby_version: !ruby/object:Gem::Requirement
|
119
|
+
none: false
|
111
120
|
requirements:
|
112
121
|
- - ">="
|
113
122
|
- !ruby/object:Gem::Version
|
123
|
+
hash: 3
|
114
124
|
segments:
|
115
125
|
- 0
|
116
126
|
version: "0"
|
117
127
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
128
|
+
none: false
|
118
129
|
requirements:
|
119
130
|
- - ">="
|
120
131
|
- !ruby/object:Gem::Version
|
132
|
+
hash: 3
|
121
133
|
segments:
|
122
134
|
- 0
|
123
135
|
version: "0"
|
124
136
|
requirements: []
|
125
137
|
|
126
138
|
rubyforge_project: directory_watcher
|
127
|
-
rubygems_version: 1.3.
|
139
|
+
rubygems_version: 1.3.7
|
128
140
|
signing_key:
|
129
141
|
specification_version: 3
|
130
142
|
summary: A class for watching files within a directory and generating events when those files change
|