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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 82833c1dcd0ed421fcb93115f1c764492148b1f4
4
- data.tar.gz: 407619ca1bdba240ae918e4e3e73e237f129f132
3
+ metadata.gz: c41f2fe5cb60a1128a34a6df435da8325c245a31
4
+ data.tar.gz: ae4b18a4f893dcb9f2dea2065e75fd7d0af88335
5
5
  SHA512:
6
- metadata.gz: 03f0ba222830c725718adf106e479a559b183d663009c7482c35bf252c9c41799d3d824692ac30716ddf62ada053610400391b67c3d8caa82eb9a715ad3d16d7
7
- data.tar.gz: eaa55b1eaae113d97e621f6de5fb657186f584f0d1c6cd1051c17368702867e6b816047d9868114863118addbc73f413f7850b040d49c2631eb0699ae6b84763
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
- ## IMPORTANT NOTE
9
+ ## Known issues / Quickfixes / Workarounds
10
10
 
11
- Got an issue with Listen and you're "in a hurry"? First, try Polling mode as a workaround (described below).
11
+ Just head over here: https://github.com/guard/listen/wiki/Quickfixes,-known-issues-and-workarounds
12
12
 
13
- Otherwise ...
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
- * Supports watching multiple directories from a single listener.
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
- * Allows supplying regexp-patterns to ignore paths for better results.
30
- * File content checksum comparison for modifications made under the same second (OS X HFS volumes, VFAT volumes).
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
- * Ignored directories are actually still scanned [#274](https://github.com/guard/listen/issues/274) (Except when polling)
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.0'
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
- entry.children.each { |child| remaining << child }
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)
@@ -1,3 +1,3 @@
1
1
  module Listen
2
- VERSION = '2.8.2'
2
+ VERSION = '2.8.3'
3
3
  end
@@ -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
- allow(::Dir).to receive(:entries).and_return([])
212
- allow(::File).to receive(:realpath).with('/dir1').and_return('/dir1')
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
- allow(::Dir).to receive(:entries).with('/dir1') { %w(foo bar) }
227
- allow(::Dir).to receive(:entries).with('/dir1/foo').and_raise(Errno::ENOTDIR)
228
- allow(::Dir).to receive(:entries).with('/dir1/bar').and_raise(Errno::ENOTDIR)
229
- allow(::File).to receive(:lstat).with('/dir1/foo') { foo_stat }
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
- allow(::Dir).to receive(:entries).with('/dir1') { %w(foo) }
254
- allow(::Dir).to receive(:entries).with('/dir1/foo') { %w(bar) }
255
- allow(::Dir).to receive(:entries).with('/dir1/foo/bar').and_raise(Errno::ENOTDIR)
256
- allow(::File).to receive(:lstat).with('/dir1/foo/bar') { bar_stat }
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
- allow(::Dir).to receive(:entries).with('/dir1') { %w(foo) }
303
- allow(::Dir).to receive(:entries).with('/dir1/foo') { %w(foo) }
304
- allow(::Dir).to receive(:entries).with('/dir2') { [] }
305
- allow(::File).to receive(:realpath).with('/dir1').and_return('/bar')
306
- allow(::File).to receive(:realpath).with('/dir1/foo').and_return('/bar')
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 message and aborts with error' do
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.2
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-25 00:00:00.000000000 Z
11
+ date: 2014-11-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: celluloid