listen 3.3.0.pre.2 → 3.3.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 +105 -61
- data/bin/listen +3 -4
- data/lib/listen/adapter.rb +3 -3
- data/lib/listen/adapter/base.rb +4 -4
- data/lib/listen/adapter/bsd.rb +3 -4
- data/lib/listen/adapter/config.rb +1 -4
- data/lib/listen/adapter/darwin.rb +2 -2
- data/lib/listen/adapter/linux.rb +5 -2
- data/lib/listen/adapter/polling.rb +1 -1
- data/lib/listen/adapter/windows.rb +10 -14
- data/lib/listen/change.rb +10 -19
- data/lib/listen/cli.rb +3 -4
- data/lib/listen/directory.rb +5 -7
- data/lib/listen/event/config.rb +4 -5
- data/lib/listen/event/loop.rb +1 -4
- data/lib/listen/event/processor.rb +14 -10
- data/lib/listen/event/queue.rb +9 -9
- data/lib/listen/file.rb +6 -0
- data/lib/listen/fsm.rb +2 -2
- data/lib/listen/listener.rb +2 -0
- data/lib/listen/listener/config.rb +2 -4
- data/lib/listen/logger.rb +13 -12
- data/lib/listen/options.rb +9 -8
- data/lib/listen/queue_optimizer.rb +7 -12
- data/lib/listen/record.rb +28 -31
- data/lib/listen/record/entry.rb +1 -1
- data/lib/listen/record/symlink_detector.rb +4 -4
- data/lib/listen/silencer.rb +10 -8
- data/lib/listen/thread.rb +22 -15
- data/lib/listen/version.rb +1 -1
- metadata +11 -5
@@ -62,7 +62,7 @@ module Listen
|
|
62
62
|
actions << :added if actions.delete(:moved_to)
|
63
63
|
actions << :removed if actions.delete(:moved_from)
|
64
64
|
|
65
|
-
modified = actions.
|
65
|
+
modified = actions.find { |x| x == :modified }
|
66
66
|
_calculate_add_remove_difference(actions, path, modified)
|
67
67
|
end
|
68
68
|
|
@@ -91,10 +91,8 @@ module Listen
|
|
91
91
|
def _reinterpret_related_changes(cookies)
|
92
92
|
table = { moved_to: :added, moved_from: :removed }
|
93
93
|
cookies.flat_map do |_, changes|
|
94
|
-
|
95
|
-
|
96
|
-
to_dir, to_file = data
|
97
|
-
[[:modified, to_dir, to_file]]
|
94
|
+
if (editor_modified = editor_modified?(changes))
|
95
|
+
[[:modified, *editor_modified]]
|
98
96
|
else
|
99
97
|
not_silenced = changes.reject do |type, _, _, path, _|
|
100
98
|
config.silenced?(Pathname(path), type)
|
@@ -106,7 +104,7 @@ module Listen
|
|
106
104
|
end
|
107
105
|
end
|
108
106
|
|
109
|
-
def
|
107
|
+
def editor_modified?(changes)
|
110
108
|
return unless changes.size == 2
|
111
109
|
|
112
110
|
from_type = from = nil
|
@@ -118,17 +116,14 @@ module Listen
|
|
118
116
|
from_type, _from_change, _, from, = data
|
119
117
|
when :moved_to
|
120
118
|
to_type, _to_change, to_dir, to, = data
|
121
|
-
else
|
122
|
-
return nil
|
123
119
|
end
|
124
120
|
end
|
125
121
|
|
126
|
-
return unless from && to
|
127
|
-
|
128
122
|
# Expect an ignored moved_from and non-ignored moved_to
|
129
123
|
# to qualify as an "editor modify"
|
130
|
-
|
131
|
-
|
124
|
+
if from && to && config.silenced?(Pathname(from), from_type) && !config.silenced?(Pathname(to), to_type)
|
125
|
+
[to_dir, to]
|
126
|
+
end
|
132
127
|
end
|
133
128
|
end
|
134
129
|
end
|
data/lib/listen/record.rb
CHANGED
@@ -10,14 +10,16 @@ module Listen
|
|
10
10
|
# TODO: deprecate
|
11
11
|
|
12
12
|
attr_reader :root
|
13
|
+
|
13
14
|
def initialize(directory)
|
14
15
|
@tree = _auto_hash
|
15
16
|
@root = directory.to_s
|
16
17
|
end
|
17
18
|
|
18
19
|
def add_dir(rel_path)
|
19
|
-
|
20
|
-
|
20
|
+
if ![nil, '', '.'].include?(rel_path)
|
21
|
+
@tree[rel_path] ||= {}
|
22
|
+
end
|
21
23
|
end
|
22
24
|
|
23
25
|
def update_file(rel_path, data)
|
@@ -33,33 +35,30 @@ module Listen
|
|
33
35
|
def file_data(rel_path)
|
34
36
|
dirname, basename = Pathname(rel_path).split.map(&:to_s)
|
35
37
|
if [nil, '', '.'].include? dirname
|
36
|
-
tree[basename] ||= {}
|
37
|
-
tree[basename].dup
|
38
|
+
@tree[basename] ||= {}
|
39
|
+
@tree[basename].dup
|
38
40
|
else
|
39
|
-
tree[dirname] ||= {}
|
40
|
-
tree[dirname][basename] ||= {}
|
41
|
-
tree[dirname][basename].dup
|
41
|
+
@tree[dirname] ||= {}
|
42
|
+
@tree[dirname][basename] ||= {}
|
43
|
+
@tree[dirname][basename].dup
|
42
44
|
end
|
43
45
|
end
|
44
46
|
|
45
47
|
def dir_entries(rel_path)
|
46
|
-
subtree =
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
end
|
48
|
+
subtree = if [nil, '', '.'].include? rel_path.to_s
|
49
|
+
@tree
|
50
|
+
else
|
51
|
+
_sub_tree(rel_path)
|
52
|
+
end
|
52
53
|
|
53
|
-
|
54
|
-
subtree.each do |key, values|
|
54
|
+
subtree.transform_values do |values|
|
55
55
|
# only get data for file entries
|
56
|
-
|
56
|
+
values.key?(:mtime) ? values : {}
|
57
57
|
end
|
58
|
-
result
|
59
58
|
end
|
60
59
|
|
61
60
|
def _sub_tree(rel_path)
|
62
|
-
tree.each_with_object({}) do |(path, meta), result|
|
61
|
+
@tree.each_with_object({}) do |(path, meta), result|
|
63
62
|
next unless path.start_with?(rel_path)
|
64
63
|
|
65
64
|
if path == rel_path
|
@@ -85,29 +84,27 @@ module Listen
|
|
85
84
|
private
|
86
85
|
|
87
86
|
def _auto_hash
|
88
|
-
Hash.new { |h, k| h[k] =
|
87
|
+
Hash.new { |h, k| h[k] = {} }
|
89
88
|
end
|
90
89
|
|
91
|
-
attr_reader :tree
|
92
|
-
|
93
90
|
def _fast_update_file(dirname, basename, data)
|
94
|
-
if [nil, '', '.'].include?
|
95
|
-
tree[basename] = (tree[basename] || {}).merge(data)
|
91
|
+
if [nil, '', '.'].include?(dirname)
|
92
|
+
@tree[basename] = (@tree[basename] || {}).merge(data)
|
96
93
|
else
|
97
|
-
tree[dirname] ||= {}
|
98
|
-
tree[dirname][basename] = (tree[dirname][basename] || {}).merge(data)
|
94
|
+
@tree[dirname] ||= {}
|
95
|
+
@tree[dirname][basename] = (@tree[dirname][basename] || {}).merge(data)
|
99
96
|
end
|
100
97
|
end
|
101
98
|
|
102
99
|
def _fast_unset_path(dirname, basename)
|
103
100
|
# this may need to be reworked to properly remove
|
104
101
|
# entries from a tree, without adding non-existing dirs to the record
|
105
|
-
if [nil, '', '.'].include?
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
tree[dirname].delete(basename)
|
102
|
+
if [nil, '', '.'].include?(dirname)
|
103
|
+
if @tree.key?(basename)
|
104
|
+
@tree.delete(basename)
|
105
|
+
end
|
106
|
+
elsif @tree.key?(dirname)
|
107
|
+
@tree[dirname].delete(basename)
|
111
108
|
end
|
112
109
|
end
|
113
110
|
|
data/lib/listen/record/entry.rb
CHANGED
@@ -6,9 +6,9 @@ module Listen
|
|
6
6
|
# @private api
|
7
7
|
class Record
|
8
8
|
class SymlinkDetector
|
9
|
-
WIKI = 'https://github.com/guard/listen/wiki/Duplicate-directory-errors'
|
9
|
+
WIKI = 'https://github.com/guard/listen/wiki/Duplicate-directory-errors'
|
10
10
|
|
11
|
-
SYMLINK_LOOP_ERROR = <<-EOS
|
11
|
+
SYMLINK_LOOP_ERROR = <<-EOS
|
12
12
|
** ERROR: directory is already being watched! **
|
13
13
|
|
14
14
|
Directory: %s
|
@@ -33,8 +33,8 @@ module Listen
|
|
33
33
|
private
|
34
34
|
|
35
35
|
def _fail(symlinked, real_path)
|
36
|
-
|
37
|
-
|
36
|
+
warn(format(SYMLINK_LOOP_ERROR, symlinked, real_path))
|
37
|
+
raise Error, 'Failed due to looped symlinks'
|
38
38
|
end
|
39
39
|
end
|
40
40
|
end
|
data/lib/listen/silencer.rb
CHANGED
@@ -14,7 +14,7 @@ module Listen
|
|
14
14
|
| log
|
15
15
|
| tmp
|
16
16
|
|vendor/ruby
|
17
|
-
)(/|$)}x
|
17
|
+
)(/|$)}x.freeze
|
18
18
|
|
19
19
|
# The default list of files that get ignored.
|
20
20
|
DEFAULT_IGNORED_EXTENSIONS = %r{(?:
|
@@ -55,7 +55,7 @@ module Listen
|
|
55
55
|
| \.DS_Store
|
56
56
|
| \.tmp
|
57
57
|
| ~
|
58
|
-
)$}x
|
58
|
+
)$}x.freeze
|
59
59
|
|
60
60
|
attr_accessor :only_patterns, :ignore_patterns
|
61
61
|
|
@@ -75,16 +75,18 @@ module Listen
|
|
75
75
|
def silenced?(relative_path, type)
|
76
76
|
path = relative_path.to_s
|
77
77
|
|
78
|
-
|
79
|
-
return true unless only_patterns.any? { |pattern| path =~ pattern }
|
80
|
-
end
|
81
|
-
|
82
|
-
ignore_patterns.any? { |pattern| path =~ pattern }
|
78
|
+
_ignore?(path) || (only_patterns && type == :file && !_only?(path))
|
83
79
|
end
|
84
80
|
|
85
81
|
private
|
86
82
|
|
87
|
-
|
83
|
+
def _ignore?(path)
|
84
|
+
ignore_patterns.any? { |pattern| path =~ pattern }
|
85
|
+
end
|
86
|
+
|
87
|
+
def _only?(path)
|
88
|
+
only_patterns.any? { |pattern| path =~ pattern }
|
89
|
+
end
|
88
90
|
|
89
91
|
def _init_ignores(ignores, overrides)
|
90
92
|
patterns = []
|
data/lib/listen/thread.rb
CHANGED
@@ -9,36 +9,43 @@ module Listen
|
|
9
9
|
class << self
|
10
10
|
# Creates a new thread with the given name.
|
11
11
|
# Any exceptions raised by the thread will be logged with the thread name and complete backtrace.
|
12
|
-
|
12
|
+
# rubocop:disable Style/MultilineBlockChain
|
13
|
+
def new(name, &block)
|
13
14
|
thread_name = "listen-#{name}"
|
14
|
-
|
15
15
|
caller_stack = caller
|
16
|
+
|
16
17
|
::Thread.new do
|
17
|
-
|
18
|
-
yield
|
19
|
-
rescue Exception => ex
|
20
|
-
_log_exception(ex, thread_name, caller_stack)
|
21
|
-
nil
|
22
|
-
end
|
18
|
+
rescue_and_log(thread_name, caller_stack: caller_stack, &block)
|
23
19
|
end.tap do |thread|
|
24
20
|
thread.name = thread_name
|
25
21
|
end
|
26
22
|
end
|
23
|
+
# rubocop:enable Style/MultilineBlockChain
|
24
|
+
|
25
|
+
def rescue_and_log(method_name, *args, caller_stack: nil)
|
26
|
+
yield(*args)
|
27
|
+
rescue Exception => exception # rubocop:disable Lint/RescueException
|
28
|
+
_log_exception(exception, method_name, caller_stack: caller_stack)
|
29
|
+
end
|
27
30
|
|
28
31
|
private
|
29
32
|
|
30
|
-
def _log_exception(
|
31
|
-
complete_backtrace =
|
32
|
-
|
33
|
+
def _log_exception(exception, thread_name, caller_stack: nil)
|
34
|
+
complete_backtrace = if caller_stack
|
35
|
+
[*exception.backtrace, "--- Thread.new ---", *caller_stack]
|
36
|
+
else
|
37
|
+
exception.backtrace
|
38
|
+
end
|
39
|
+
message = "Exception rescued in #{thread_name}:\n#{_exception_with_causes(exception)}\n#{complete_backtrace * "\n"}"
|
33
40
|
Listen.logger.error(message)
|
34
41
|
end
|
35
42
|
|
36
|
-
def _exception_with_causes(
|
37
|
-
result = +"#{
|
38
|
-
if
|
43
|
+
def _exception_with_causes(exception)
|
44
|
+
result = +"#{exception.class}: #{exception}"
|
45
|
+
if exception.cause
|
39
46
|
result << "\n"
|
40
47
|
result << "--- Caused by: ---\n"
|
41
|
-
result << _exception_with_causes(
|
48
|
+
result << _exception_with_causes(exception.cause)
|
42
49
|
end
|
43
50
|
result
|
44
51
|
end
|
data/lib/listen/version.rb
CHANGED
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.3.
|
4
|
+
version: 3.3.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: 2020-
|
11
|
+
date: 2020-11-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rb-fsevent
|
@@ -51,7 +51,7 @@ dependencies:
|
|
51
51
|
- !ruby/object:Gem::Version
|
52
52
|
version: 0.9.10
|
53
53
|
description: The Listen gem listens to file modifications and notifies you about the
|
54
|
-
|
54
|
+
changes. Works everywhere!
|
55
55
|
email: thibaud@thibaud.gg
|
56
56
|
executables:
|
57
57
|
- listen
|
@@ -99,6 +99,12 @@ licenses:
|
|
99
99
|
- MIT
|
100
100
|
metadata:
|
101
101
|
allowed_push_host: https://rubygems.org
|
102
|
+
bug_tracker_uri: https://github.com/guard/listen/issues
|
103
|
+
changelog_uri: https://github.com/guard/listen/releases
|
104
|
+
documentation_uri: https://www.rubydoc.info/gems/listen/3.3.3
|
105
|
+
homepage_uri: https://github.com/guard/listen
|
106
|
+
source_code_uri: https://github.com/guard/listen/tree/v3.3.3
|
107
|
+
wiki_uri: https://github.com/guard/listen/wiki
|
102
108
|
post_install_message:
|
103
109
|
rdoc_options: []
|
104
110
|
require_paths:
|
@@ -110,9 +116,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
110
116
|
version: 2.2.7
|
111
117
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
112
118
|
requirements:
|
113
|
-
- - "
|
119
|
+
- - ">="
|
114
120
|
- !ruby/object:Gem::Version
|
115
|
-
version:
|
121
|
+
version: '0'
|
116
122
|
requirements: []
|
117
123
|
rubygems_version: 3.0.1
|
118
124
|
signing_key:
|