listen 3.5.1 → 3.7.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 321b55dd88acb041f6dfa31d44047d4f90ebfa970adb85d82facd5ceff94db90
4
- data.tar.gz: 4e4eb8728548f782d6b99b7b9b40473102f31315e27dae2bacf2b146c2609969
3
+ metadata.gz: 800a9d0af997cb48bc330b0aeaecdcb39b53e9bdeb2dbed6c08fd03b237a3d36
4
+ data.tar.gz: 5caa12c52d09e7447d0f1b43fddadf03e4e33ae4c611bd0ed7d367e3cd3a280b
5
5
  SHA512:
6
- metadata.gz: 843e2fe248d9216087fc09e8a5e70f6ee10ed27e55fe993939c93ee1260d55fa3076a684579cae143f304e24b5ecc98318de0e00678e63bee9f52192b1e7292b
7
- data.tar.gz: a74621cffdb908165c010b50848e07e9eef9eed9e53b3449533752f2a54caceb5d57c9e1e02c43560a3e6832d6210fd3540e838de34c6f6d1e391d496a5bf8de
6
+ metadata.gz: 8fa9b8758f30b8ececde07ca321a23fb02c9cfbec59e587011b1598d297f8a0a451728fb394e0bc1fa182e7ef40e4598bfa82b035bdccc29f6375b5df95dda6f
7
+ data.tar.gz: 8b94d5ab7085f27382cfca52d32ff8717c3d17f14ed3632a96853e8e4bcd2174bbc8f5f8f0ff3709f739b13c440fb87a82540bb0ae784395896fb0513837895a
data/README.md CHANGED
@@ -25,10 +25,8 @@ The `listen` gem listens to file modifications and notifies you about the change
25
25
  * Support for plugins planned for future.
26
26
  * TCP functionality was removed in `listen` [3.0.0](https://github.com/guard/listen/releases/tag/v3.0.0) ([#319](https://github.com/guard/listen/issues/319), [#218](https://github.com/guard/listen/issues/218)). There are plans to extract this feature to separate gems ([#258](https://github.com/guard/listen/issues/258)), until this is finished, you can use by locking the `listen` gem to version `'~> 2.10'`.
27
27
  * Some filesystems won't work without polling (VM/Vagrant Shared folders, NFS, Samba, sshfs, etc.).
28
- * Specs suite on JRuby and Rubinius aren't reliable on Travis CI, but should work.
29
28
  * Windows and \*BSD adapter aren't continuously and automatically tested.
30
29
  * OSX adapter has some performance limitations ([#342](https://github.com/guard/listen/issues/342)).
31
- * FreeBSD users need patched version of rb-kqueue (as of 2020/11). See #475 for the issue, mat813/rb-kqueue#12 for the patch, and Bug 250432 in bugzilla.
32
30
  * Listeners do not notify across forked processes, if you wish for multiple processes to receive change notifications you must [listen inside of each process](https://github.com/guard/listen/issues/398#issuecomment-223957952).
33
31
 
34
32
  Pull requests or help is very welcome for these.
@@ -99,23 +97,23 @@ The callback receives **three** array parameters: `modified`, `added` and `remov
99
97
  Each of these three is always an array with 0 or more entries.
100
98
  Each array entry is an absolute path.
101
99
 
102
- ### Pause / unpause / stop
100
+ ### Pause / start / stop
103
101
 
104
- Listeners can also be easily paused/unpaused:
102
+ Listeners can also be easily paused and later un-paused with start:
105
103
 
106
104
  ``` ruby
107
105
  listener = Listen.to('dir/path/to/listen') { |modified, added, removed| puts 'handle changes here...' }
108
106
 
109
107
  listener.start
110
- listener.paused? # => false
108
+ listener.paused? # => false
111
109
  listener.processing? # => true
112
110
 
113
- listener.pause # stops processing changes (but keeps on collecting them)
114
- listener.paused? # => true
111
+ listener.pause # stops processing changes (but keeps on collecting them)
112
+ listener.paused? # => true
115
113
  listener.processing? # => false
116
114
 
117
- listener.unpause # resumes processing changes ("start" would do the same)
118
- listener.stop # stop both listening to changes and processing them
115
+ listener.start # resumes processing changes
116
+ listener.stop # stop both listening to changes and processing them
119
117
  ```
120
118
 
121
119
  Note: While paused, `listen` keeps on collecting changes in the background - to clear them, call `stop`.
@@ -124,7 +122,7 @@ listener.stop # stop both listening to changes and processing them
124
122
 
125
123
  ### Ignore / ignore!
126
124
 
127
- `Listen` ignores some directories and extensions by default (See DEFAULT_IGNORED_DIRECTORIES and DEFAULT_IGNORED_EXTENSIONS in Listen::Silencer).
125
+ `Listen` ignores some directories and extensions by default (See DEFAULT_IGNORED_FILES and DEFAULT_IGNORED_EXTENSIONS in Listen::Silencer).
128
126
  You can add ignoring patterns with the `ignore` option/method or overwrite default with `ignore!` option/method.
129
127
 
130
128
  ``` ruby
@@ -159,7 +157,7 @@ All the following options can be set through the `Listen.to` after the directory
159
157
 
160
158
  ```ruby
161
159
  ignore: [%r{/foo/bar}, /\.pid$/, /\.coffee$/] # Ignore a list of paths
162
- # default: See DEFAULT_IGNORED_DIRECTORIES and DEFAULT_IGNORED_EXTENSIONS in Listen::Silencer
160
+ # default: See DEFAULT_IGNORED_FILES and DEFAULT_IGNORED_EXTENSIONS in Listen::Silencer
163
161
 
164
162
  ignore!: %r{/foo/bar} # Same as ignore options, but overwrite default ignored paths.
165
163
 
@@ -51,7 +51,7 @@ module Listen
51
51
  # TODO: separate config per directory (some day maybe)
52
52
  change_config = Change::Config.new(config.queue, config.silencer)
53
53
  config.directories.each do |dir|
54
- record = Record.new(dir)
54
+ record = Record.new(dir, config.silencer)
55
55
  snapshot = Change.new(change_config, record)
56
56
  @snapshots[dir] = snapshot
57
57
  end
@@ -24,17 +24,14 @@ module Listen
24
24
  README_URL = 'https://github.com/guard/listen'\
25
25
  '/blob/master/README.md#increasing-the-amount-of-inotify-watchers'
26
26
 
27
- INOTIFY_LIMIT_MESSAGE = <<-EOS
28
- FATAL: Listen error: unable to monitor directories for changes.
29
- Visit #{README_URL} for info on how to fix this.
30
- EOS
31
-
32
27
  def _configure(directory, &callback)
33
28
  require 'rb-inotify'
34
29
  @worker ||= ::INotify::Notifier.new
35
30
  @worker.watch(directory.to_s, *options.events, &callback)
36
31
  rescue Errno::ENOSPC
37
- abort(INOTIFY_LIMIT_MESSAGE)
32
+ raise ::Listen::Error::INotifyMaxWatchesExceeded, <<~EOS
33
+ Unable to monitor directories for changes because iNotify max watches exceeded. See #{README_URL} .
34
+ EOS
38
35
  end
39
36
 
40
37
  def _run
@@ -36,7 +36,7 @@ module Listen
36
36
  end
37
37
 
38
38
  # TODO: this is not tested properly
39
- previous = previous.reject { |entry, _| current.include? path + entry }
39
+ previous = previous.reject { |entry, _| current.include?(path + entry) }
40
40
 
41
41
  _async_changes(snapshot, Pathname.new(rel_path), previous, options)
42
42
  rescue Errno::ENOENT, Errno::EHOSTDOWN
data/lib/listen/error.rb CHANGED
@@ -6,5 +6,6 @@ module Listen
6
6
  class Error < RuntimeError
7
7
  class NotStarted < Error; end
8
8
  class SymlinkLoop < Error; end
9
+ class INotifyMaxWatchesExceeded < Error; end
9
10
  end
10
11
  end
data/lib/listen/file.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'digest/md5'
3
+ require 'digest'
4
4
 
5
5
  module Listen
6
6
  class File
@@ -53,7 +53,7 @@ module Listen
53
53
  # then at ???14.998, but the fstat time would be ???14.0 in
54
54
  # both cases).
55
55
  #
56
- # If change happend at ???14.999997, the mtime is 14.0, so for
56
+ # If change happened at ???14.999997, the mtime is 14.0, so for
57
57
  # an mtime=???14.0 we assume it could even be almost ???15.0
58
58
  #
59
59
  # So if Time.now.to_f is ???15.999998 and stat reports mtime
@@ -67,9 +67,11 @@ module Listen
67
67
  #
68
68
  return if data[:mtime].to_i + 2 <= Time.now.to_f
69
69
 
70
- md5 = Digest::MD5.file(path).digest
71
- record.update_file(rel_path, data.merge(md5: md5))
72
- :modified if record_data[:md5] && md5 != record_data[:md5]
70
+ sha = Digest::SHA256.file(path).digest
71
+ record.update_file(rel_path, data.merge(sha: sha))
72
+ if record_data[:sha] && sha != record_data[:sha]
73
+ :modified
74
+ end
73
75
  rescue SystemCallError
74
76
  record.unset_path(rel_path)
75
77
  :removed
data/lib/listen/record.rb CHANGED
@@ -11,14 +11,15 @@ module Listen
11
11
 
12
12
  attr_reader :root
13
13
 
14
- def initialize(directory)
15
- @tree = _auto_hash
14
+ def initialize(directory, silencer)
15
+ reset_tree
16
16
  @root = directory.to_s
17
+ @silencer = silencer
17
18
  end
18
19
 
19
20
  def add_dir(rel_path)
20
- if ![nil, '', '.'].include?(rel_path)
21
- @tree[rel_path] ||= {}
21
+ if !empty_dirname?(rel_path.to_s)
22
+ @tree[rel_path.to_s]
22
23
  end
23
24
  end
24
25
 
@@ -34,32 +35,32 @@ module Listen
34
35
 
35
36
  def file_data(rel_path)
36
37
  dirname, basename = Pathname(rel_path).split.map(&:to_s)
37
- if [nil, '', '.'].include? dirname
38
- @tree[basename] ||= {}
38
+ if empty_dirname?(dirname)
39
39
  @tree[basename].dup
40
40
  else
41
- @tree[dirname] ||= {}
42
41
  @tree[dirname][basename] ||= {}
43
42
  @tree[dirname][basename].dup
44
43
  end
45
44
  end
46
45
 
47
46
  def dir_entries(rel_path)
48
- subtree = if ['', '.'].include? rel_path.to_s
47
+ rel_path_s = rel_path.to_s
48
+ subtree = if empty_dirname?(rel_path_s)
49
49
  @tree
50
50
  else
51
- @tree[rel_path.to_s] ||= _auto_hash
52
- @tree[rel_path.to_s]
51
+ @tree[rel_path_s]
53
52
  end
54
53
 
55
- subtree.transform_values do |values|
56
- # only get data for file entries
57
- values.key?(:mtime) ? values : {}
54
+ subtree.each_with_object({}) do |(key, values), result|
55
+ # only return data for file entries inside the dir (which will each be sub-hashes)
56
+ if values.is_a?(Hash)
57
+ result[key] = values.has_key?(:mtime) ? values : {}
58
+ end
58
59
  end
59
60
  end
60
61
 
61
62
  def build
62
- @tree = _auto_hash
63
+ reset_tree
63
64
  # TODO: test with a file name given
64
65
  # TODO: test other permissions
65
66
  # TODO: test with mixed encoding
@@ -71,15 +72,18 @@ module Listen
71
72
 
72
73
  private
73
74
 
74
- def _auto_hash
75
- Hash.new { |h, k| h[k] = {} }
75
+ def empty_dirname?(dirname)
76
+ dirname == '.' || dirname == ''
77
+ end
78
+
79
+ def reset_tree
80
+ @tree = Hash.new { |h, k| h[k] = {} }
76
81
  end
77
82
 
78
83
  def _fast_update_file(dirname, basename, data)
79
- if [nil, '', '.'].include?(dirname)
80
- @tree[basename] = (@tree[basename] || {}).merge(data)
84
+ if empty_dirname?(dirname.to_s)
85
+ @tree[basename] = @tree[basename].merge(data)
81
86
  else
82
- @tree[dirname] ||= {}
83
87
  @tree[dirname][basename] = (@tree[dirname][basename] || {}).merge(data)
84
88
  end
85
89
  end
@@ -87,7 +91,7 @@ module Listen
87
91
  def _fast_unset_path(dirname, basename)
88
92
  # this may need to be reworked to properly remove
89
93
  # entries from a tree, without adding non-existing dirs to the record
90
- if [nil, '', '.'].include?(dirname)
94
+ if empty_dirname?(dirname.to_s)
91
95
  if @tree.key?(basename)
92
96
  @tree.delete(basename)
93
97
  end
@@ -98,6 +102,8 @@ module Listen
98
102
 
99
103
  def _fast_build_dir(remaining, symlink_detector)
100
104
  entry = remaining.pop
105
+ return if @silencer.silenced?(entry.record_dir_key, :dir)
106
+
101
107
  children = entry.children # NOTE: children() implicitly tests if dir
102
108
  symlink_detector.verify_unwatched!(entry)
103
109
  children.each { |child| remaining << child }
@@ -3,8 +3,8 @@
3
3
  module Listen
4
4
  class Silencer
5
5
  # The default list of directories that get ignored.
6
- DEFAULT_IGNORED_DIRECTORIES = %r{^(?:
7
- \.git
6
+ DEFAULT_IGNORED_FILES = %r{\A(?:
7
+ \.git
8
8
  | \.svn
9
9
  | \.hg
10
10
  | \.rbx
@@ -13,8 +13,12 @@ module Listen
13
13
  | vendor/bundle
14
14
  | log
15
15
  | tmp
16
- |vendor/ruby
17
- )(/|$)}x.freeze
16
+ | vendor/ruby
17
+
18
+ # emacs temp files
19
+ | \#.+\#
20
+ | \.\#.+
21
+ )(/|\z)}x.freeze
18
22
 
19
23
  # The default list of files that get ignored.
20
24
  DEFAULT_IGNORED_EXTENSIONS = %r{(?:
@@ -35,7 +39,7 @@ module Listen
35
39
  | ^4913
36
40
 
37
41
  # Sed temporary files - but without actual words, like 'sedatives'
38
- | (?:^
42
+ | (?:\A
39
43
  sed
40
44
 
41
45
  (?:
@@ -55,25 +59,23 @@ module Listen
55
59
  | \.DS_Store
56
60
  | \.tmp
57
61
  | ~
58
- )$}x.freeze
62
+ )\z}x.freeze
59
63
 
64
+ # TODO: deprecate these mutators; use attr_reader instead
60
65
  attr_accessor :only_patterns, :ignore_patterns
61
66
 
62
- def initialize
63
- configure({})
67
+ def initialize(**options)
68
+ configure(options)
64
69
  end
65
70
 
71
+ # TODO: deprecate this mutator
66
72
  def configure(options)
67
73
  @only_patterns = options[:only] ? Array(options[:only]) : nil
68
74
  @ignore_patterns = _init_ignores(options[:ignore], options[:ignore!])
69
75
  end
70
76
 
71
- # Note: relative_path is temporarily expected to be a relative Pathname to
72
- # make refactoring easier (ideally, it would take a string)
73
-
74
- # TODO: switch type and path places - and verify
75
77
  def silenced?(relative_path, type)
76
- path = relative_path.to_s
78
+ path = relative_path.to_s # in case it is a Pathname
77
79
 
78
80
  _ignore?(path) || (only_patterns && type == :file && !_only?(path))
79
81
  end
@@ -91,7 +93,7 @@ module Listen
91
93
  def _init_ignores(ignores, overrides)
92
94
  patterns = []
93
95
  unless overrides
94
- patterns << DEFAULT_IGNORED_DIRECTORIES
96
+ patterns << DEFAULT_IGNORED_FILES
95
97
  patterns << DEFAULT_IGNORED_EXTENSIONS
96
98
  end
97
99
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Listen
4
- VERSION = '3.5.1'
4
+ VERSION = '3.7.1'
5
5
  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: 3.5.1
4
+ version: 3.7.1
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: 2021-03-30 00:00:00.000000000 Z
11
+ date: 2022-01-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rb-fsevent
@@ -103,9 +103,9 @@ metadata:
103
103
  allowed_push_host: https://rubygems.org
104
104
  bug_tracker_uri: https://github.com/guard/listen/issues
105
105
  changelog_uri: https://github.com/guard/listen/releases
106
- documentation_uri: https://www.rubydoc.info/gems/listen/3.5.1
106
+ documentation_uri: https://www.rubydoc.info/gems/listen/3.7.1
107
107
  homepage_uri: https://github.com/guard/listen
108
- source_code_uri: https://github.com/guard/listen/tree/v3.5.1
108
+ source_code_uri: https://github.com/guard/listen/tree/v3.7.1
109
109
  post_install_message:
110
110
  rdoc_options: []
111
111
  require_paths: