listen 2.8.2 → 2.8.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +18 -23
- data/lib/listen/record.rb +2 -1
- data/lib/listen/version.rb +1 -1
- data/spec/lib/listen/record_spec.rb +97 -40
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c41f2fe5cb60a1128a34a6df435da8325c245a31
|
4
|
+
data.tar.gz: ae4b18a4f893dcb9f2dea2065e75fd7d0af88335
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f3e6697f836c76a4dd24cf9440d8426563da850c58d7c1a698197d674879df4f7370a42b96c456842f942a321ea06fc201ac9d1d5d4511568bf06e8eb1d26463
|
7
|
+
data.tar.gz: 6659d1b8a8bc42c43e79993551bd3cd16ce89916292fe2400260d94c0e3bf1c60a31bbbd1397e1b09ef4841053abb342210337b9f56832e614ea5bd411d2b29c
|
data/README.md
CHANGED
@@ -6,29 +6,22 @@
|
|
6
6
|
|
7
7
|
The Listen gem listens to file modifications and notifies you about the changes.
|
8
8
|
|
9
|
-
##
|
9
|
+
## Known issues / Quickfixes / Workarounds
|
10
10
|
|
11
|
-
|
11
|
+
Just head over here: https://github.com/guard/listen/wiki/Quickfixes,-known-issues-and-workarounds
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
Output from using `LISTEN_GEM_DEBUGGING` (debug mode) is often *crucial* to quickly diagnosing and fixing issues.
|
16
|
-
|
17
|
-
There are TOO MANY possible and surprising reasons why Listen "doesn't work as expected" (e.g. Dropbox folders, editor settings, system limits) - and the best way to find out is by going through these 3 steps first:
|
18
|
-
|
19
|
-
See [TROUBLESHOOTING](https://github.com/guard/listen/blob/master/TROUBLESHOOTING.md)
|
20
|
-
|
21
|
-
Once you've reproduced the problem in debug mode (`LISTEN_GEM_DEBUGGING`), paste the output it into a Gist and link it to your issue.
|
13
|
+
## Tips and Techniques
|
22
14
|
|
15
|
+
Make sure you know these few basic tricks: https://github.com/guard/listen/wiki/Tips-and-Techniques
|
23
16
|
|
24
17
|
## Features
|
25
18
|
|
26
|
-
*
|
27
|
-
* OS-specific adapters on MRI for Mac OS X 10.6+, Linux, ~~\*BSD~~ and Windows, [more info](#listen-adapters) below.
|
19
|
+
* OS-optimized adapters on MRI for Mac OS X 10.6+, Linux, ~~\*BSD~~ and Windows, [more info](#listen-adapters) below.
|
28
20
|
* Detects file modification, addition and removal.
|
29
|
-
*
|
30
|
-
*
|
21
|
+
* You can watch multiple directories.
|
22
|
+
* Regexp-patterns for ignoring paths for more accuracy and speed
|
31
23
|
* Forwarding file events over TCP, [more info](#forwarding-file-events-over-tcp) below.
|
24
|
+
* Increased change detection accuracy on OS X HFS and VFAT volumes.
|
32
25
|
* Tested on MRI Ruby environments (1.9+ only) via [Travis CI](https://travis-ci.org/guard/listen),
|
33
26
|
|
34
27
|
Please note that:
|
@@ -37,10 +30,9 @@ Please note that:
|
|
37
30
|
- Windows and \*BSD adapter aren't continuously and automaticaly tested.
|
38
31
|
- \*BSD is broken and not supported any more, see: [#220](https://github.com/guard/listen/issues/220)
|
39
32
|
|
40
|
-
|
41
33
|
## Pending features / issues
|
42
34
|
|
43
|
-
*
|
35
|
+
* symlinked directories aren't fully transparent yet: https://github.com/guard/listen/issues/279
|
44
36
|
* Directory/adapter specific configuration options
|
45
37
|
* Support for plugins
|
46
38
|
|
@@ -51,7 +43,7 @@ Pull request or help is very welcome for these.
|
|
51
43
|
The simplest way to install Listen is to use [Bundler](http://bundler.io).
|
52
44
|
|
53
45
|
```ruby
|
54
|
-
gem 'listen', '~> 2.
|
46
|
+
gem 'listen', '~> 2.7' # this prevents upgrading to 3.x
|
55
47
|
```
|
56
48
|
|
57
49
|
## Usage
|
@@ -105,6 +97,8 @@ sleep
|
|
105
97
|
|
106
98
|
Note: Ignoring regexp patterns are evaluated against relative paths.
|
107
99
|
|
100
|
+
Note: ignoring paths does not improve performance - except when Polling
|
101
|
+
|
108
102
|
### Only
|
109
103
|
|
110
104
|
Listen catches all files (less the ignored once) by default, if you want to only listen to a specific type of file (ie: just rb extension) you should use the `only` option/method.
|
@@ -170,11 +164,11 @@ wait_for_delay: 4 # Set the delay (**in seconds**)
|
|
170
164
|
force_polling: true # Force the use of the polling adapter
|
171
165
|
# default: none
|
172
166
|
|
173
|
-
polling_fallback_message: 'custom message' # Set a custom polling fallback message (or disable it with false)
|
174
|
-
# default: "Listen will be polling for changes. Learn more at https://github.com/guard/listen#polling-fallback."
|
175
|
-
|
176
167
|
debug: true # Enable Celluloid logger
|
177
168
|
# default: false
|
169
|
+
|
170
|
+
polling_fallback_message: 'custom message' # Set a custom polling fallback message (or disable it with false)
|
171
|
+
# default: "Listen will be polling for changes. Learn more at https://github.com/guard/listen#polling-fallback."
|
178
172
|
```
|
179
173
|
|
180
174
|
Also, setting the environment variable `LISTEN_GEM_DEBUGGING=1` does the same as `debug: true` above.
|
@@ -242,13 +236,14 @@ If Listen seems slow or unresponsive, make sure you're not using the Polling ada
|
|
242
236
|
Also, if the directories you're watching contain many files, make sure you're:
|
243
237
|
|
244
238
|
* not using Polling (ideally)
|
245
|
-
* using `:ignore` and `:only` options to avoid tracking directories you don't care about
|
239
|
+
* using `:ignore` and `:only` options to avoid tracking directories you don't care about (important with Polling and on MacOS)
|
240
|
+
* running Listen with the `:latency` and `:wait_for_delay` options not too small or too big (depends on needs)
|
241
|
+
* not watching directories with log files, database files or other frequently changing files
|
246
242
|
* not using a version of Listen prior to 2.7.7
|
247
243
|
* not getting silent crashes within Listen (see LISTEN_GEM_DEBUGGING=2)
|
248
244
|
* not running multiple instances of Listen in the background
|
249
245
|
* using a file system with atime modification disabled (ideally)
|
250
246
|
* not using a filesystem with inaccurate file modification times (ideally), e.g. HFS, VFAT
|
251
|
-
* running Listen with the `:latency` and `:wait_for_delay` options not too small or too big (depends on needs)
|
252
247
|
* not buffering to a slow terminal (e.g. transparency + fancy font + slow gfx card + lots of output)
|
253
248
|
* ideally not running a slow encryption stack, e.g. btrfs + ecryptfs
|
254
249
|
|
data/lib/listen/record.rb
CHANGED
@@ -115,8 +115,9 @@ module Listen
|
|
115
115
|
|
116
116
|
def _fast_build_dir(remaining, symlink_detector)
|
117
117
|
entry = remaining.pop
|
118
|
+
children = entry.children # NOTE: children() implicitly tests if dir
|
118
119
|
symlink_detector.verify_unwatched!(entry)
|
119
|
-
|
120
|
+
children.each { |child| remaining << child }
|
120
121
|
add_dir(entry.root, entry.record_dir_key)
|
121
122
|
rescue Errno::ENOTDIR
|
122
123
|
_fast_try_file(entry)
|
data/lib/listen/version.rb
CHANGED
@@ -7,6 +7,46 @@ describe Listen::Record do
|
|
7
7
|
instance_double(Listen::Listener, registry: registry, options: {})
|
8
8
|
end
|
9
9
|
|
10
|
+
def dir_entries_for(hash)
|
11
|
+
hash.each do |dir, entries|
|
12
|
+
allow(::Dir).to receive(:entries).with(dir) { entries }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def real_directory(hash)
|
17
|
+
dir_entries_for(hash)
|
18
|
+
hash.each do |dir, _|
|
19
|
+
realpath(dir)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def file(path)
|
24
|
+
allow(::Dir).to receive(:entries).with(path).and_raise(Errno::ENOTDIR)
|
25
|
+
path
|
26
|
+
end
|
27
|
+
|
28
|
+
def lstat(path, stat = nil)
|
29
|
+
stat ||= instance_double(::File::Stat, mtime: 2.3, mode: 0755)
|
30
|
+
allow(::File).to receive(:lstat).with(path).and_return(stat)
|
31
|
+
stat
|
32
|
+
end
|
33
|
+
|
34
|
+
def realpath(path)
|
35
|
+
allow(::File).to receive(:realpath).with(path).and_return(path)
|
36
|
+
path
|
37
|
+
end
|
38
|
+
|
39
|
+
def symlink(hash_or_dir)
|
40
|
+
if String === hash_or_dir
|
41
|
+
allow(::File).to receive(:realpath).with(hash_or_dir).
|
42
|
+
and_return(hash_or_dir)
|
43
|
+
else
|
44
|
+
hash_or_dir.each do |dir, real_path|
|
45
|
+
allow(::File).to receive(:realpath).with(dir).and_return(real_path)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
10
50
|
let(:record) { Listen::Record.new(listener) }
|
11
51
|
let(:dir) { instance_double(Pathname, to_s: '/dir') }
|
12
52
|
|
@@ -208,9 +248,8 @@ describe Listen::Record do
|
|
208
248
|
end
|
209
249
|
|
210
250
|
it 're-inits paths' do
|
211
|
-
|
212
|
-
|
213
|
-
allow(::File).to receive(:realpath).with('/dir2').and_return('/dir2')
|
251
|
+
real_directory('/dir1' => [])
|
252
|
+
real_directory('/dir2' => [])
|
214
253
|
|
215
254
|
record.update_file(dir, 'path/file.rb', mtime: 1.1)
|
216
255
|
record.build
|
@@ -223,19 +262,10 @@ describe Listen::Record do
|
|
223
262
|
|
224
263
|
context 'with no subdirs' do
|
225
264
|
before do
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
allow(::File).to receive(:lstat).with('/dir1/bar') { bar_stat }
|
231
|
-
allow(::Dir).to receive(:entries).with('/dir2') { [] }
|
232
|
-
|
233
|
-
allow(::File).to receive(:realpath).with('/dir1').and_return('/dir1')
|
234
|
-
allow(::File).to receive(:realpath).with('/dir2').and_return('/dir2')
|
235
|
-
allow(::File).to receive(:realpath).with('/dir1/foo').
|
236
|
-
and_return('/dir1/foo')
|
237
|
-
allow(::File).to receive(:realpath).with('/dir1/bar').
|
238
|
-
and_return('/dir1/bar')
|
265
|
+
real_directory('/dir1' => %w(foo bar))
|
266
|
+
lstat(file('/dir1/foo'), foo_stat)
|
267
|
+
lstat(file('/dir1/bar'), bar_stat)
|
268
|
+
real_directory('/dir2' => [])
|
239
269
|
end
|
240
270
|
|
241
271
|
it 'builds record' do
|
@@ -250,18 +280,10 @@ describe Listen::Record do
|
|
250
280
|
|
251
281
|
context 'with subdir containing files' do
|
252
282
|
before do
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
allow(::Dir).to receive(:entries).with('/dir2') { [] }
|
258
|
-
|
259
|
-
allow(::File).to receive(:realpath).with('/dir1').and_return('/dir1')
|
260
|
-
allow(::File).to receive(:realpath).with('/dir2').and_return('/dir2')
|
261
|
-
allow(::File).to receive(:realpath).with('/dir1/foo').
|
262
|
-
and_return('/dir1/foo')
|
263
|
-
allow(::File).to receive(:realpath).with('/dir1/foo/bar').
|
264
|
-
and_return('/dir1/foo/bar')
|
283
|
+
real_directory('/dir1' => %w(foo))
|
284
|
+
real_directory('/dir1/foo' => %w(bar))
|
285
|
+
lstat(file('/dir1/foo/bar'))
|
286
|
+
real_directory('/dir2' => [])
|
265
287
|
end
|
266
288
|
|
267
289
|
it 'builds record' do
|
@@ -275,12 +297,13 @@ describe Listen::Record do
|
|
275
297
|
|
276
298
|
context 'with subdir containing dirs' do
|
277
299
|
before do
|
300
|
+
real_directory('/dir1' => %w(foo))
|
301
|
+
real_directory('/dir1/foo' => %w(bar baz))
|
302
|
+
real_directory('/dir1/foo/bar' => [])
|
303
|
+
real_directory('/dir1/foo/baz' => [])
|
304
|
+
real_directory('/dir2' => [])
|
305
|
+
|
278
306
|
allow(::File).to receive(:realpath) { |path| path }
|
279
|
-
allow(::Dir).to receive(:entries).with('/dir1') { %w(foo) }
|
280
|
-
allow(::Dir).to receive(:entries).with('/dir1/foo') { %w(bar baz) }
|
281
|
-
allow(::Dir).to receive(:entries).with('/dir1/foo/bar') { [] }
|
282
|
-
allow(::Dir).to receive(:entries).with('/dir1/foo/baz') { [] }
|
283
|
-
allow(::Dir).to receive(:entries).with('/dir2') { [] }
|
284
307
|
end
|
285
308
|
|
286
309
|
it 'builds record' do
|
@@ -299,15 +322,14 @@ describe Listen::Record do
|
|
299
322
|
context 'with subdir containing symlink to parent' do
|
300
323
|
subject { record.paths }
|
301
324
|
before do
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
allow(::File).to receive(:realpath).with('/dir2').and_return('/dir2')
|
325
|
+
real_directory('/dir1' => %w(foo))
|
326
|
+
dir_entries_for('/dir1/foo' => %w(dir1))
|
327
|
+
symlink('/dir1/foo' => '/dir1')
|
328
|
+
|
329
|
+
real_directory('/dir2' => [])
|
308
330
|
end
|
309
331
|
|
310
|
-
it 'shows
|
332
|
+
it 'shows a warning' do
|
311
333
|
expect(STDERR).to receive(:puts).
|
312
334
|
with(/directory is already being watched/)
|
313
335
|
|
@@ -316,5 +338,40 @@ describe Listen::Record do
|
|
316
338
|
# to raise_error(RuntimeError, /Failed due to looped symlinks/)
|
317
339
|
end
|
318
340
|
end
|
341
|
+
|
342
|
+
context 'with a normal symlinked directory to another' do
|
343
|
+
subject { record.paths }
|
344
|
+
|
345
|
+
before do
|
346
|
+
real_directory('/dir1' => %w(foo))
|
347
|
+
|
348
|
+
symlink('/dir1/foo' => '/dir2')
|
349
|
+
dir_entries_for('/dir1/foo' => %w(bar))
|
350
|
+
lstat(realpath(file('/dir1/foo/bar')))
|
351
|
+
|
352
|
+
real_directory('/dir2' => %w(bar))
|
353
|
+
lstat(file('/dir2/bar'))
|
354
|
+
end
|
355
|
+
|
356
|
+
it 'shows message' do
|
357
|
+
expect(STDERR).to_not receive(:puts)
|
358
|
+
record.build
|
359
|
+
end
|
360
|
+
end
|
361
|
+
|
362
|
+
context 'with subdir containing symlinked file' do
|
363
|
+
subject { record.paths }
|
364
|
+
before do
|
365
|
+
real_directory('/dir1' => %w(foo))
|
366
|
+
lstat(file('/dir1/foo'))
|
367
|
+
real_directory('/dir2' => [])
|
368
|
+
end
|
369
|
+
|
370
|
+
it 'shows a warning' do
|
371
|
+
expect(STDERR).to_not receive(:puts)
|
372
|
+
|
373
|
+
record.build
|
374
|
+
end
|
375
|
+
end
|
319
376
|
end
|
320
377
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: listen
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.8.
|
4
|
+
version: 2.8.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Thibaud Guillaume-Gentil
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-11-
|
11
|
+
date: 2014-11-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: celluloid
|