listen 0.5.1 → 0.5.2

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.
@@ -1,203 +1,203 @@
1
- require 'pathname'
2
-
3
- module Listen
4
- class Listener
5
- attr_reader :directory, :directory_record, :adapter
6
-
7
- # The default value for using relative paths in the callback.
8
- DEFAULT_TO_RELATIVE_PATHS = false
9
-
10
- # Initializes the directory listener.
11
- #
12
- # @param [String] directory the directory to listen to
13
- # @param [Hash] options the listen options
14
- # @option options [Regexp] ignore a pattern for ignoring paths
15
- # @option options [Regexp] filter a pattern for filtering paths
16
- # @option options [Float] latency the delay between checking for changes in seconds
17
- # @option options [Boolean] relative_paths whether or not to use relative-paths in the callback
18
- # @option options [Boolean] force_polling whether to force the polling adapter or not
19
- # @option options [String, Boolean] polling_fallback_message to change polling fallback message or remove it
20
- #
21
- # @yield [modified, added, removed] the changed files
22
- # @yieldparam [Array<String>] modified the list of modified files
23
- # @yieldparam [Array<String>] added the list of added files
24
- # @yieldparam [Array<String>] removed the list of removed files
25
- #
26
- def initialize(directory, options = {}, &block)
27
- @block = block
28
- @directory = Pathname.new(directory).realpath.to_s
29
- @directory_record = DirectoryRecord.new(@directory)
30
- @use_relative_paths = DEFAULT_TO_RELATIVE_PATHS
31
-
32
- @use_relative_paths = options.delete(:relative_paths) if options[:relative_paths]
33
- @directory_record.ignore(*options.delete(:ignore)) if options[:ignore]
34
- @directory_record.filter(*options.delete(:filter)) if options[:filter]
35
-
36
- @adapter_options = options
37
- end
38
-
39
- # Starts the listener by initializing the adapter and building
40
- # the directory record concurrently, then it starts the adapter to watch
41
- # for changes.
42
- #
43
- # @param [Boolean] blocking whether or not to block the current thread after starting
44
- #
45
- def start(blocking = true)
46
- t = Thread.new { @directory_record.build }
47
- @adapter = initialize_adapter
48
- t.join
49
- @adapter.start(blocking)
50
- end
51
-
52
- # Stops the listener.
53
- #
54
- def stop
55
- @adapter.stop
56
- end
57
-
58
- # Pauses the listener.
59
- #
60
- # @return [Listen::Listener] the listener
61
- #
62
- def pause
63
- @adapter.paused = true
64
- self
65
- end
66
-
67
- # Unpauses the listener.
68
- #
69
- # @return [Listen::Listener] the listener
70
- #
71
- def unpause
72
- @directory_record.build
73
- @adapter.paused = false
74
- self
75
- end
76
-
77
- # Returns whether the listener is paused or not.
78
- #
79
- # @return [Boolean] adapter paused status
80
- #
81
- def paused?
82
- !!@adapter && @adapter.paused == true
83
- end
84
-
85
- # Adds ignoring patterns to the listener.
86
- #
87
- # @param (see Listen::DirectoryRecord#ignore)
88
- #
89
- # @return [Listen::Listener] the listener
90
- #
91
- def ignore(*regexps)
92
- @directory_record.ignore(*regexps)
93
- self
94
- end
95
-
96
- # Adds filtering patterns to the listener.
97
- #
98
- # @param (see Listen::DirectoryRecord#filter)
99
- #
100
- # @return [Listen::Listener] the listener
101
- #
102
- def filter(*regexps)
103
- @directory_record.filter(*regexps)
104
- self
105
- end
106
-
107
- # Sets the latency for the adapter. This is a helper method
108
- # to simplify changing the latency directly from the listener.
109
- #
110
- # @example Wait 0.5 seconds each time before checking changes
111
- # latency 0.5
112
- #
113
- # @param [Float] seconds the amount of delay, in seconds
114
- #
115
- # @return [Listen::Listener] the listener
116
- #
117
- def latency(seconds)
118
- @adapter_options[:latency] = seconds
119
- self
120
- end
121
-
122
- # Sets whether the use of the polling adapter
123
- # should be forced or not.
124
- #
125
- # @example Forcing the use of the polling adapter
126
- # force_polling true
127
- #
128
- # @param [Boolean] value whether to force the polling adapter or not
129
- #
130
- # @return [Listen::Listener] the listener
131
- #
132
- def force_polling(value)
133
- @adapter_options[:force_polling] = value
134
- self
135
- end
136
-
137
- # Sets whether the paths in the callback should be
138
- # relative or absolute.
139
- #
140
- # @example Enabling relative paths in the callback
141
- # relative_paths true
142
- #
143
- # @param [Boolean] value whether to enable relative paths in the callback or not
144
- #
145
- # @return [Listen::Listener] the listener
146
- #
147
- def relative_paths(value)
148
- @use_relative_paths = value
149
- self
150
- end
151
-
152
- # Defines a custom polling fallback message of disable it.
153
- #
154
- # @example Disabling the polling fallback message
155
- # polling_fallback_message false
156
- #
157
- # @param [String, Boolean] value to change polling fallback message or remove it
158
- #
159
- # @return [Listen::Listener] the listener
160
- #
161
- def polling_fallback_message(value)
162
- @adapter_options[:polling_fallback_message] = value
163
- self
164
- end
165
-
166
- # Sets the callback that gets called on changes.
167
- #
168
- # @example Assign a callback to be called on changes
169
- # callback = lambda { |modified, added, removed| ... }
170
- # change &callback
171
- #
172
- # @param [Proc] block the callback proc
173
- #
174
- # @return [Listen::Listener] the listener
175
- #
176
- def change(&block) # modified, added, removed
177
- @block = block
178
- self
179
- end
180
-
181
- # Runs the callback passing it the changes if there are any.
182
- #
183
- # @param (see Listen::DirectoryRecord#fetch_changes)
184
- #
185
- def on_change(directories, options = {})
186
- changes = @directory_record.fetch_changes(directories, options.merge(
187
- :relative_paths => @use_relative_paths
188
- ))
189
- unless changes.values.all? { |paths| paths.empty? }
190
- @block.call(changes[:modified],changes[:added],changes[:removed])
191
- end
192
- end
193
-
194
- private
195
-
196
- # Initializes an adapter passing it the callback and adapters' options.
197
- #
198
- def initialize_adapter
199
- callback = lambda { |changed_dirs, options| self.on_change(changed_dirs, options) }
200
- Adapter.select_and_initialize(@directory, @adapter_options, &callback)
201
- end
202
- end
203
- end
1
+ require 'pathname'
2
+
3
+ module Listen
4
+ class Listener
5
+ attr_reader :directory, :directory_record, :adapter
6
+
7
+ # The default value for using relative paths in the callback.
8
+ DEFAULT_TO_RELATIVE_PATHS = false
9
+
10
+ # Initializes the directory listener.
11
+ #
12
+ # @param [String] directory the directory to listen to
13
+ # @param [Hash] options the listen options
14
+ # @option options [Regexp] ignore a pattern for ignoring paths
15
+ # @option options [Regexp] filter a pattern for filtering paths
16
+ # @option options [Float] latency the delay between checking for changes in seconds
17
+ # @option options [Boolean] relative_paths whether or not to use relative-paths in the callback
18
+ # @option options [Boolean] force_polling whether to force the polling adapter or not
19
+ # @option options [String, Boolean] polling_fallback_message to change polling fallback message or remove it
20
+ #
21
+ # @yield [modified, added, removed] the changed files
22
+ # @yieldparam [Array<String>] modified the list of modified files
23
+ # @yieldparam [Array<String>] added the list of added files
24
+ # @yieldparam [Array<String>] removed the list of removed files
25
+ #
26
+ def initialize(directory, options = {}, &block)
27
+ @block = block
28
+ @directory = Pathname.new(directory).realpath.to_s
29
+ @directory_record = DirectoryRecord.new(@directory)
30
+ @use_relative_paths = DEFAULT_TO_RELATIVE_PATHS
31
+
32
+ @use_relative_paths = options.delete(:relative_paths) if options[:relative_paths]
33
+ @directory_record.ignore(*options.delete(:ignore)) if options[:ignore]
34
+ @directory_record.filter(*options.delete(:filter)) if options[:filter]
35
+
36
+ @adapter_options = options
37
+ end
38
+
39
+ # Starts the listener by initializing the adapter and building
40
+ # the directory record concurrently, then it starts the adapter to watch
41
+ # for changes.
42
+ #
43
+ # @param [Boolean] blocking whether or not to block the current thread after starting
44
+ #
45
+ def start(blocking = true)
46
+ t = Thread.new { @directory_record.build }
47
+ @adapter = initialize_adapter
48
+ t.join
49
+ @adapter.start(blocking)
50
+ end
51
+
52
+ # Stops the listener.
53
+ #
54
+ def stop
55
+ @adapter.stop
56
+ end
57
+
58
+ # Pauses the listener.
59
+ #
60
+ # @return [Listen::Listener] the listener
61
+ #
62
+ def pause
63
+ @adapter.paused = true
64
+ self
65
+ end
66
+
67
+ # Unpauses the listener.
68
+ #
69
+ # @return [Listen::Listener] the listener
70
+ #
71
+ def unpause
72
+ @directory_record.build
73
+ @adapter.paused = false
74
+ self
75
+ end
76
+
77
+ # Returns whether the listener is paused or not.
78
+ #
79
+ # @return [Boolean] adapter paused status
80
+ #
81
+ def paused?
82
+ !!@adapter && @adapter.paused == true
83
+ end
84
+
85
+ # Adds ignoring patterns to the listener.
86
+ #
87
+ # @param (see Listen::DirectoryRecord#ignore)
88
+ #
89
+ # @return [Listen::Listener] the listener
90
+ #
91
+ def ignore(*regexps)
92
+ @directory_record.ignore(*regexps)
93
+ self
94
+ end
95
+
96
+ # Adds filtering patterns to the listener.
97
+ #
98
+ # @param (see Listen::DirectoryRecord#filter)
99
+ #
100
+ # @return [Listen::Listener] the listener
101
+ #
102
+ def filter(*regexps)
103
+ @directory_record.filter(*regexps)
104
+ self
105
+ end
106
+
107
+ # Sets the latency for the adapter. This is a helper method
108
+ # to simplify changing the latency directly from the listener.
109
+ #
110
+ # @example Wait 0.5 seconds each time before checking changes
111
+ # latency 0.5
112
+ #
113
+ # @param [Float] seconds the amount of delay, in seconds
114
+ #
115
+ # @return [Listen::Listener] the listener
116
+ #
117
+ def latency(seconds)
118
+ @adapter_options[:latency] = seconds
119
+ self
120
+ end
121
+
122
+ # Sets whether the use of the polling adapter
123
+ # should be forced or not.
124
+ #
125
+ # @example Forcing the use of the polling adapter
126
+ # force_polling true
127
+ #
128
+ # @param [Boolean] value whether to force the polling adapter or not
129
+ #
130
+ # @return [Listen::Listener] the listener
131
+ #
132
+ def force_polling(value)
133
+ @adapter_options[:force_polling] = value
134
+ self
135
+ end
136
+
137
+ # Sets whether the paths in the callback should be
138
+ # relative or absolute.
139
+ #
140
+ # @example Enabling relative paths in the callback
141
+ # relative_paths true
142
+ #
143
+ # @param [Boolean] value whether to enable relative paths in the callback or not
144
+ #
145
+ # @return [Listen::Listener] the listener
146
+ #
147
+ def relative_paths(value)
148
+ @use_relative_paths = value
149
+ self
150
+ end
151
+
152
+ # Defines a custom polling fallback message of disable it.
153
+ #
154
+ # @example Disabling the polling fallback message
155
+ # polling_fallback_message false
156
+ #
157
+ # @param [String, Boolean] value to change polling fallback message or remove it
158
+ #
159
+ # @return [Listen::Listener] the listener
160
+ #
161
+ def polling_fallback_message(value)
162
+ @adapter_options[:polling_fallback_message] = value
163
+ self
164
+ end
165
+
166
+ # Sets the callback that gets called on changes.
167
+ #
168
+ # @example Assign a callback to be called on changes
169
+ # callback = lambda { |modified, added, removed| ... }
170
+ # change &callback
171
+ #
172
+ # @param [Proc] block the callback proc
173
+ #
174
+ # @return [Listen::Listener] the listener
175
+ #
176
+ def change(&block) # modified, added, removed
177
+ @block = block
178
+ self
179
+ end
180
+
181
+ # Runs the callback passing it the changes if there are any.
182
+ #
183
+ # @param (see Listen::DirectoryRecord#fetch_changes)
184
+ #
185
+ def on_change(directories, options = {})
186
+ changes = @directory_record.fetch_changes(directories, options.merge(
187
+ :relative_paths => @use_relative_paths
188
+ ))
189
+ unless changes.values.all? { |paths| paths.empty? }
190
+ @block.call(changes[:modified],changes[:added],changes[:removed])
191
+ end
192
+ end
193
+
194
+ private
195
+
196
+ # Initializes an adapter passing it the callback and adapters' options.
197
+ #
198
+ def initialize_adapter
199
+ callback = lambda { |changed_dirs, options| self.on_change(changed_dirs, options) }
200
+ Adapter.select_and_initialize(@directory, @adapter_options, &callback)
201
+ end
202
+ end
203
+ end
@@ -1,121 +1,121 @@
1
- module Listen
2
- class MultiListener < Listener
3
- attr_reader :directories, :directories_records, :adapter
4
-
5
- # Initializes the multiple directories listener.
6
- #
7
- # @param [String] directories the directories to listen to
8
- # @param [Hash] options the listen options
9
- # @option options [Regexp] ignore a pattern for ignoring paths
10
- # @option options [Regexp] filter a pattern for filtering paths
11
- # @option options [Float] latency the delay between checking for changes in seconds
12
- # @option options [Boolean] force_polling whether to force the polling adapter or not
13
- # @option options [String, Boolean] polling_fallback_message to change polling fallback message or remove it
14
- #
15
- # @yield [modified, added, removed] the changed files
16
- # @yieldparam [Array<String>] modified the list of modified files
17
- # @yieldparam [Array<String>] added the list of added files
18
- # @yieldparam [Array<String>] removed the list of removed files
19
- #
20
- def initialize(*args, &block)
21
- options = args.last.is_a?(Hash) ? args.pop : {}
22
- directories = args
23
-
24
- @block = block
25
- @directories = directories.map { |d| Pathname.new(d).realpath.to_s }
26
- @directories_records = @directories.map { |d| DirectoryRecord.new(d) }
27
-
28
- ignore(*options.delete(:ignore)) if options[:ignore]
29
- filter(*options.delete(:filter)) if options[:filter]
30
-
31
- @adapter_options = options
32
- end
33
-
34
- # Starts the listener by initializing the adapter and building
35
- # the directory record concurrently, then it starts the adapter to watch
36
- # for changes.
37
- #
38
- # @param [Boolean] blocking whether or not to block the current thread after starting
39
- #
40
- def start(blocking = true)
41
- t = Thread.new { @directories_records.each { |r| r.build } }
42
- @adapter = initialize_adapter
43
- t.join
44
- @adapter.start(blocking)
45
- end
46
-
47
- # Unpauses the listener.
48
- #
49
- # @return [Listen::Listener] the listener
50
- #
51
- def unpause
52
- @directories_records.each { |r| r.build }
53
- @adapter.paused = false
54
- self
55
- end
56
-
57
- # Adds ignored paths to the listener.
58
- #
59
- # @param (see Listen::DirectoryRecord#ignore)
60
- #
61
- # @return [Listen::Listener] the listener
62
- #
63
- def ignore(*paths)
64
- @directories_records.each { |r| r.ignore(*paths) }
65
- self
66
- end
67
-
68
- # Adds file filters to the listener.
69
- #
70
- # @param (see Listen::DirectoryRecord#filter)
71
- #
72
- # @return [Listen::Listener] the listener
73
- #
74
- def filter(*regexps)
75
- @directories_records.each { |r| r.filter(*regexps) }
76
- self
77
- end
78
-
79
- # Runs the callback passing it the changes if there are any.
80
- #
81
- # @param (see Listen::DirectoryRecord#fetch_changes)
82
- #
83
- def on_change(directories_to_search, options = {})
84
- changes = fetch_records_changes(directories_to_search, options)
85
- unless changes.values.all? { |paths| paths.empty? }
86
- @block.call(changes[:modified],changes[:added],changes[:removed])
87
- end
88
- end
89
-
90
- private
91
-
92
- # Initializes an adapter passing it the callback and adapters' options.
93
- #
94
- def initialize_adapter
95
- callback = lambda { |changed_dirs, options| self.on_change(changed_dirs, options) }
96
- Adapter.select_and_initialize(@directories, @adapter_options, &callback)
97
- end
98
-
99
- # Returns the sum of all the changes to the directories records
100
- #
101
- # @param (see Listen::DirectoryRecord#fetch_changes)
102
- #
103
- # @return [Hash] the changes
104
- #
105
- def fetch_records_changes(directories_to_search, options)
106
- @directories_records.inject({}) do |h, r|
107
- # directory records skips paths outside their range, so passing the
108
- # whole `directories` array is not a problem.
109
- record_changes = r.fetch_changes(directories_to_search, options.merge(:relative_paths => DEFAULT_TO_RELATIVE_PATHS))
110
-
111
- if h.empty?
112
- h.merge!(record_changes)
113
- else
114
- h.each { |k, v| h[k] += record_changes[k] }
115
- end
116
-
117
- h
118
- end
119
- end
120
- end
121
- end
1
+ module Listen
2
+ class MultiListener < Listener
3
+ attr_reader :directories, :directories_records, :adapter
4
+
5
+ # Initializes the multiple directories listener.
6
+ #
7
+ # @param [String] directories the directories to listen to
8
+ # @param [Hash] options the listen options
9
+ # @option options [Regexp] ignore a pattern for ignoring paths
10
+ # @option options [Regexp] filter a pattern for filtering paths
11
+ # @option options [Float] latency the delay between checking for changes in seconds
12
+ # @option options [Boolean] force_polling whether to force the polling adapter or not
13
+ # @option options [String, Boolean] polling_fallback_message to change polling fallback message or remove it
14
+ #
15
+ # @yield [modified, added, removed] the changed files
16
+ # @yieldparam [Array<String>] modified the list of modified files
17
+ # @yieldparam [Array<String>] added the list of added files
18
+ # @yieldparam [Array<String>] removed the list of removed files
19
+ #
20
+ def initialize(*args, &block)
21
+ options = args.last.is_a?(Hash) ? args.pop : {}
22
+ directories = args
23
+
24
+ @block = block
25
+ @directories = directories.map { |d| Pathname.new(d).realpath.to_s }
26
+ @directories_records = @directories.map { |d| DirectoryRecord.new(d) }
27
+
28
+ ignore(*options.delete(:ignore)) if options[:ignore]
29
+ filter(*options.delete(:filter)) if options[:filter]
30
+
31
+ @adapter_options = options
32
+ end
33
+
34
+ # Starts the listener by initializing the adapter and building
35
+ # the directory record concurrently, then it starts the adapter to watch
36
+ # for changes.
37
+ #
38
+ # @param [Boolean] blocking whether or not to block the current thread after starting
39
+ #
40
+ def start(blocking = true)
41
+ t = Thread.new { @directories_records.each { |r| r.build } }
42
+ @adapter = initialize_adapter
43
+ t.join
44
+ @adapter.start(blocking)
45
+ end
46
+
47
+ # Unpauses the listener.
48
+ #
49
+ # @return [Listen::Listener] the listener
50
+ #
51
+ def unpause
52
+ @directories_records.each { |r| r.build }
53
+ @adapter.paused = false
54
+ self
55
+ end
56
+
57
+ # Adds ignored paths to the listener.
58
+ #
59
+ # @param (see Listen::DirectoryRecord#ignore)
60
+ #
61
+ # @return [Listen::Listener] the listener
62
+ #
63
+ def ignore(*paths)
64
+ @directories_records.each { |r| r.ignore(*paths) }
65
+ self
66
+ end
67
+
68
+ # Adds file filters to the listener.
69
+ #
70
+ # @param (see Listen::DirectoryRecord#filter)
71
+ #
72
+ # @return [Listen::Listener] the listener
73
+ #
74
+ def filter(*regexps)
75
+ @directories_records.each { |r| r.filter(*regexps) }
76
+ self
77
+ end
78
+
79
+ # Runs the callback passing it the changes if there are any.
80
+ #
81
+ # @param (see Listen::DirectoryRecord#fetch_changes)
82
+ #
83
+ def on_change(directories_to_search, options = {})
84
+ changes = fetch_records_changes(directories_to_search, options)
85
+ unless changes.values.all? { |paths| paths.empty? }
86
+ @block.call(changes[:modified],changes[:added],changes[:removed])
87
+ end
88
+ end
89
+
90
+ private
91
+
92
+ # Initializes an adapter passing it the callback and adapters' options.
93
+ #
94
+ def initialize_adapter
95
+ callback = lambda { |changed_dirs, options| self.on_change(changed_dirs, options) }
96
+ Adapter.select_and_initialize(@directories, @adapter_options, &callback)
97
+ end
98
+
99
+ # Returns the sum of all the changes to the directories records
100
+ #
101
+ # @param (see Listen::DirectoryRecord#fetch_changes)
102
+ #
103
+ # @return [Hash] the changes
104
+ #
105
+ def fetch_records_changes(directories_to_search, options)
106
+ @directories_records.inject({}) do |h, r|
107
+ # directory records skips paths outside their range, so passing the
108
+ # whole `directories` array is not a problem.
109
+ record_changes = r.fetch_changes(directories_to_search, options.merge(:relative_paths => DEFAULT_TO_RELATIVE_PATHS))
110
+
111
+ if h.empty?
112
+ h.merge!(record_changes)
113
+ else
114
+ h.each { |k, v| h[k] += record_changes[k] }
115
+ end
116
+
117
+ h
118
+ end
119
+ end
120
+ end
121
+ end