listen 3.3.1 → 3.4.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -5,21 +5,22 @@ module Listen
5
5
  def initialize(opts, defaults)
6
6
  @options = {}
7
7
  given_options = opts.dup
8
- defaults.keys.each do |key|
8
+ defaults.each_key do |key|
9
9
  @options[key] = given_options.delete(key) || defaults[key]
10
10
  end
11
11
 
12
- return if given_options.empty?
12
+ given_options.empty? or raise ArgumentError, "Unknown options: #{given_options.inspect}"
13
+ end
13
14
 
14
- msg = "Unknown options: #{given_options.inspect}"
15
- Listen.logger.warn msg
16
- fail msg
15
+ # rubocop:disable Lint/MissingSuper
16
+ def respond_to_missing?(name, *_)
17
+ @options.has_key?(name)
17
18
  end
18
19
 
19
20
  def method_missing(name, *_)
20
- return @options[name] if @options.key?(name)
21
- msg = "Bad option: #{name.inspect} (valid:#{@options.keys.inspect})"
22
- fail NameError, msg
21
+ respond_to_missing?(name) or raise NameError, "Bad option: #{name.inspect} (valid:#{@options.keys.inspect})"
22
+ @options[name]
23
23
  end
24
+ # rubocop:enable Lint/MissingSuper
24
25
  end
25
26
  end
@@ -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.detect { |x| x == :modified }
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
- data = _detect_possible_editor_save(changes)
95
- if data
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 _detect_possible_editor_save(changes)
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
- return unless config.silenced?(Pathname(from), from_type)
131
- config.silenced?(Pathname(to), to_type) ? nil : [to_dir, to]
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
@@ -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
- return if [nil, '', '.'].include? rel_path
20
- @tree[rel_path] ||= {}
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,41 +35,26 @@ 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
- if [nil, '', '.'].include? rel_path.to_s
48
- tree
49
- else
50
- _sub_tree(rel_path)
51
- end
52
-
53
- result = {}
54
- subtree.each do |key, values|
55
- # only get data for file entries
56
- result[key] = values.key?(:mtime) ? values : {}
48
+ subtree = if ['', '.'].include? rel_path.to_s
49
+ @tree
50
+ else
51
+ @tree[rel_path.to_s] ||= _auto_hash
52
+ @tree[rel_path.to_s]
57
53
  end
58
- result
59
- end
60
-
61
- def _sub_tree(rel_path)
62
- tree.each_with_object({}) do |(path, meta), result|
63
- next unless path.start_with?(rel_path)
64
54
 
65
- if path == rel_path
66
- result.merge!(meta)
67
- else
68
- sub_path = path.sub(%r{\A#{rel_path}/?}, '')
69
- result[sub_path] = meta
70
- end
55
+ subtree.transform_values do |values|
56
+ # only get data for file entries
57
+ values.key?(:mtime) ? values : {}
71
58
  end
72
59
  end
73
60
 
@@ -85,29 +72,27 @@ module Listen
85
72
  private
86
73
 
87
74
  def _auto_hash
88
- Hash.new { |h, k| h[k] = Hash.new }
75
+ Hash.new { |h, k| h[k] = {} }
89
76
  end
90
77
 
91
- attr_reader :tree
92
-
93
78
  def _fast_update_file(dirname, basename, data)
94
- if [nil, '', '.'].include? dirname
95
- tree[basename] = (tree[basename] || {}).merge(data)
79
+ if [nil, '', '.'].include?(dirname)
80
+ @tree[basename] = (@tree[basename] || {}).merge(data)
96
81
  else
97
- tree[dirname] ||= {}
98
- tree[dirname][basename] = (tree[dirname][basename] || {}).merge(data)
82
+ @tree[dirname] ||= {}
83
+ @tree[dirname][basename] = (@tree[dirname][basename] || {}).merge(data)
99
84
  end
100
85
  end
101
86
 
102
87
  def _fast_unset_path(dirname, basename)
103
88
  # this may need to be reworked to properly remove
104
89
  # entries from a tree, without adding non-existing dirs to the record
105
- if [nil, '', '.'].include? dirname
106
- return unless tree.key?(basename)
107
- tree.delete(basename)
108
- else
109
- return unless tree.key?(dirname)
110
- tree[dirname].delete(basename)
90
+ if [nil, '', '.'].include?(dirname)
91
+ if @tree.key?(basename)
92
+ @tree.delete(basename)
93
+ end
94
+ elsif @tree.key?(dirname)
95
+ @tree[dirname].delete(basename)
111
96
  end
112
97
  end
113
98
 
@@ -17,7 +17,7 @@ module Listen
17
17
 
18
18
  def children
19
19
  child_relative = _join
20
- (_entries(sys_path) - %w(. ..)).map do |name|
20
+ (_entries(sys_path) - %w[. ..]).map do |name|
21
21
  Entry.new(@root, child_relative, name)
22
22
  end
23
23
  end
@@ -1,25 +1,25 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'set'
4
+ require 'listen/error'
4
5
 
5
6
  module Listen
6
7
  # @private api
7
8
  class Record
8
9
  class SymlinkDetector
9
- WIKI = 'https://github.com/guard/listen/wiki/Duplicate-directory-errors'.freeze
10
+ README_URL = 'https://github.com/guard/listen/blob/master/README.md'
10
11
 
11
- SYMLINK_LOOP_ERROR = <<-EOS.freeze
12
+ SYMLINK_LOOP_ERROR = <<-EOS
12
13
  ** ERROR: directory is already being watched! **
13
14
 
14
15
  Directory: %s
15
16
 
16
17
  is already being watched through: %s
17
18
 
18
- MORE INFO: #{WIKI}
19
+ MORE INFO: #{README_URL}
19
20
  EOS
20
21
 
21
- class Error < RuntimeError
22
- end
22
+ Error = ::Listen::Error # for backward compatibility
23
23
 
24
24
  def initialize
25
25
  @real_dirs = Set.new
@@ -27,14 +27,14 @@ module Listen
27
27
 
28
28
  def verify_unwatched!(entry)
29
29
  real_path = entry.real_path
30
- @real_dirs.add?(real_path) || _fail(entry.sys_path, real_path)
30
+ @real_dirs.add?(real_path) or _fail(entry.sys_path, real_path)
31
31
  end
32
32
 
33
33
  private
34
34
 
35
35
  def _fail(symlinked, real_path)
36
- STDERR.puts format(SYMLINK_LOOP_ERROR, symlinked, real_path)
37
- fail Error, 'Failed due to looped symlinks'
36
+ warn(format(SYMLINK_LOOP_ERROR, symlinked, real_path))
37
+ raise ::Listen::Error::SymlinkLoop, 'Failed due to looped symlinks'
38
38
  end
39
39
  end
40
40
  end
@@ -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
- if only_patterns && type == :file
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
- attr_reader :options
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 = []
@@ -9,6 +9,7 @@ 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
+ # rubocop:disable Style/MultilineBlockChain
12
13
  def new(name, &block)
13
14
  thread_name = "listen-#{name}"
14
15
  caller_stack = caller
@@ -19,31 +20,32 @@ module Listen
19
20
  thread.name = thread_name
20
21
  end
21
22
  end
23
+ # rubocop:enable Style/MultilineBlockChain
22
24
 
23
25
  def rescue_and_log(method_name, *args, caller_stack: nil)
24
26
  yield(*args)
25
- rescue Exception => ex
26
- _log_exception(ex, method_name, caller_stack: caller_stack)
27
+ rescue Exception => exception # rubocop:disable Lint/RescueException
28
+ _log_exception(exception, method_name, caller_stack: caller_stack)
27
29
  end
28
30
 
29
31
  private
30
32
 
31
- def _log_exception(ex, thread_name, caller_stack: nil)
33
+ def _log_exception(exception, thread_name, caller_stack: nil)
32
34
  complete_backtrace = if caller_stack
33
- [*ex.backtrace, "--- Thread.new ---", *caller_stack]
34
- else
35
- ex.backtrace
36
- end
37
- message = "Exception rescued in #{thread_name}:\n#{_exception_with_causes(ex)}\n#{complete_backtrace * "\n"}"
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"}"
38
40
  Listen.logger.error(message)
39
41
  end
40
42
 
41
- def _exception_with_causes(ex)
42
- result = +"#{ex.class}: #{ex}"
43
- if ex.cause
43
+ def _exception_with_causes(exception)
44
+ result = +"#{exception.class}: #{exception}"
45
+ if exception.cause
44
46
  result << "\n"
45
47
  result << "--- Caused by: ---\n"
46
- result << _exception_with_causes(ex.cause)
48
+ result << _exception_with_causes(exception.cause)
47
49
  end
48
50
  result
49
51
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Listen
4
- VERSION = '3.3.1'
4
+ VERSION = '3.4.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.3.1
4
+ version: 3.4.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: 2020-11-13 00:00:00.000000000 Z
11
+ date: 2021-01-14 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
- changegem. Works everywhere!
54
+ changes. Works everywhere!
55
55
  email: thibaud@thibaud.gg
56
56
  executables:
57
57
  - listen
@@ -76,6 +76,7 @@ files:
76
76
  - lib/listen/change.rb
77
77
  - lib/listen/cli.rb
78
78
  - lib/listen/directory.rb
79
+ - lib/listen/error.rb
79
80
  - lib/listen/event/config.rb
80
81
  - lib/listen/event/loop.rb
81
82
  - lib/listen/event/processor.rb
@@ -85,6 +86,7 @@ files:
85
86
  - lib/listen/listener.rb
86
87
  - lib/listen/listener/config.rb
87
88
  - lib/listen/logger.rb
89
+ - lib/listen/monotonic_time.rb
88
90
  - lib/listen/options.rb
89
91
  - lib/listen/queue_optimizer.rb
90
92
  - lib/listen/record.rb
@@ -99,6 +101,11 @@ licenses:
99
101
  - MIT
100
102
  metadata:
101
103
  allowed_push_host: https://rubygems.org
104
+ bug_tracker_uri: https://github.com/guard/listen/issues
105
+ changelog_uri: https://github.com/guard/listen/releases
106
+ documentation_uri: https://www.rubydoc.info/gems/listen/3.4.1
107
+ homepage_uri: https://github.com/guard/listen
108
+ source_code_uri: https://github.com/guard/listen/tree/v3.4.1
102
109
  post_install_message:
103
110
  rdoc_options: []
104
111
  require_paths: