listen 2.8.2 → 2.8.3
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/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
|