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.
@@ -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
@@ -1,3 +1,8 @@
1
+ == 1.4.0 / 2011-03-15
2
+
3
+ Minor Enhancements
4
+ - added support for 'cool.io' [Jonathan Stott]
5
+
1
6
  == 1.3.2 / 2010-04-09
2
7
 
3
8
  * 1 bug fix
data/bin/dw ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env ruby
2
+
@@ -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 Rev () or EventMachine () instead of a
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 Rev to generate file notifications.
183
+ # This example will use Cool.io to generate file notifications.
184
184
  #
185
- # dw = DirectoryWatcher.new '.', :glob => '**/*.rb', :scanner => :rev
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
- attr_reader :glob
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
@@ -1 +1 @@
1
- 1.3.2
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
- - 3
8
- - 2
9
- version: 1.3.2
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: 2010-04-09 00:00:00 -06:00
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
- - 1
30
- - 1
31
- version: 1.1.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
- - 3
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
- - 12
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
- - 4
72
- - 1
73
- version: 3.4.1
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
- - version.txt
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.6
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