listen 0.2.0 → 0.3.0

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.
data/CHANGELOG.md CHANGED
@@ -1,4 +1,9 @@
1
- ## Master
1
+ ## 0.3.0 - February 21, 2012
2
+
3
+ - Add automatic fallback to polling if system adapter doesn't work (like a DropBox folder). ([@thibaudgg][])
4
+ - Add latency and force_polling options. ([@Maher4Ever][])
5
+
6
+ ## 0.2.0 - February 13, 2012
2
7
 
3
8
  - Add checksum comparaison support for detecting consecutive file modifications made during the same second. ([@thibaudgg][])
4
9
  - Add rb-fchange support. ([@thibaudgg][])
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2012 The listen team
1
+ Copyright (c) 2012 Thibaud Guillaume-Gentil
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,20 +1,16 @@
1
1
  # Listen [![Build Status](https://secure.travis-ci.org/guard/listen.png?branch=master)](http://travis-ci.org/guard/listen)
2
2
 
3
- **Work in progress...**
4
-
5
3
  The Listen gem listens to file modifications and notifies you about the changes.
6
4
 
7
- ## TODO
5
+ ## Features
8
6
 
9
- - **DONE** Add polling support
10
- - **DONE** Add `rb-fsevent` support
11
- - **DONE** Add `rb-inotify` support
12
- - **DONE** Add `rb-fchange` support
13
- - **DONE** Add checksum comparaison support for detecting consecutive file modifications made during the same second. (like Guard)
14
- - Add latency option
15
- - Add polling option (true: polling forced, false: polling never used (to skip DropBox polling fallback))
16
- - Dropbox detection with polling fallback (if needed)
17
- - Improve API (if needed)
7
+ * Works everywhere!
8
+ * OS-specific adapters for Mac OS X 10.6+, Linux and Windows.
9
+ * Automatic fallback to polling if OS-specific adapter doesn't work.
10
+ * Detects files modification, addidation and removal.
11
+ * Checksum comparaison for modifications made under the same second.
12
+ * Tested on all Ruby environments via [travis-ci](http://travis-ci.org/guard/listen).
13
+ * Threadable.
18
14
 
19
15
  ## Install
20
16
 
@@ -27,14 +23,12 @@ gem install listen
27
23
  There are two ways you can use Listen.
28
24
 
29
25
  1. call `Listen.to` with a path params, and define callbacks in a block.
30
- 3. create a `listener` object usable in an (ARel style) chainable way.
26
+ 2. create a `listener` object usable in an (ARel style) chainable way.
31
27
 
32
28
  Feel free to give your feeback via [Listen issues](https://github.com/guard/listener/issues)
33
29
 
34
30
  ### Block API
35
31
 
36
- #### One dir
37
-
38
32
  ``` ruby
39
33
  Listen.to('dir/path/to/listen', filter: /.*\.rb/, ignore: '/ignored/path') do |modified, added, removed|
40
34
  # ...
@@ -47,6 +41,9 @@ end
47
41
  listener = Listen.to('dir/path/to/listen')
48
42
  listener = listener.ignore('/ignored/path')
49
43
  listener = listener.filter(/.*\.rb/)
44
+ listener = listener.latency(0.5)
45
+ listener = listener.force_polling(true)
46
+ listener = listener.polling_fallback_message(false)
50
47
  listener = listener.change(&callback)
51
48
  listener.start # enter the run loop
52
49
  listener.stop
@@ -55,7 +52,14 @@ listener.stop
55
52
  #### Chainable
56
53
 
57
54
  ``` ruby
58
- Listen.to('dir/path/to/listen').ignore('/ignored/path').filter(/.*\.rb/).change(&callback).start # enter the run loop
55
+ Listen.to('dir/path/to/listen')
56
+ .ignore('/ignored/path')
57
+ .filter(/.*\.rb/)
58
+ .latency(0.5)
59
+ .force_polling(true)
60
+ .polling_fallback_message('custom message')
61
+ .change(&callback)
62
+ .start # enter the run loop
59
63
  ```
60
64
 
61
65
  #### Multiple listeners support available via Thread
@@ -74,20 +78,83 @@ Thread.new { scripts.start } # enter the run loop
74
78
  These options can be set through `Listen.to` params or via methods (see the "Object" API)
75
79
 
76
80
  ```ruby
77
- :filter => /.*\.rb/, /.*\.coffee/ # Filter files to listen to via a regexps list.
78
- # default: none
81
+ :filter => /.*\.rb/, /.*\.coffee/ # Filter files to listen to via a regexps list.
82
+ # default: none
83
+
84
+ :ignore => 'path1', 'path2' # Ignore a list of paths (root directory or sub-dir)
85
+ # default: '.bundle', '.git', '.DS_Store', 'log', 'tmp', 'vendor'
79
86
 
80
- :ignore => 'path1', 'path2' # Ignore a list of paths (root directory or sub-dir)
81
- # default: '.bundle', '.git', '.DS_Store', 'log', 'tmp', 'vendor'
87
+ :latency => 0.5 # Set the delay (**in seconds**) between checking for changes
88
+ # default: 0.1 sec (1.0 sec for polling)
89
+
90
+ :force_polling => true # Force the use of the polling adapter
91
+ # default: none
92
+
93
+ :polling_fallback_message => 'custom message' # Set a custom polling fallback message (or disable it with `false`)
94
+ # default: "WARNING: Listen fallen back to polling, learn more at https://github.com/guard/listen#fallback."
82
95
  ```
83
96
 
97
+ ## Listen adapters
98
+
99
+ The Listen gem has a set of adapters to notify it when there are changes.
100
+ There are 3 OS-specific adapters to support Mac, Linux and Windows. These adapters are fast
101
+ as they use some system-calls to implement the notifying function.
102
+
103
+ There is also a polling adapter which is a cross-platform adapter and it will
104
+ work on any system. This adapter is unfortunately slower than the rest of the adapters.
105
+
106
+ The Listen gem will choose the best and working adapter for your machine automatically. If you
107
+ want to force the use of the polling adapter, either use the `:force_polling` option
108
+ while initializing the listener or call the `force_polling` method on your listener
109
+ before starting it.
110
+
111
+ <a name="fallback"/>
112
+ ### Polling fallback
113
+
114
+ When the OS-specific adapter doesn't work the Listen gem automatically falls back to the polling adapter.
115
+ Here some things to try to avoiding this fallback:
116
+
117
+ * [Update your Dropbox client](http://www.dropbox.com/downloading) (if used).
118
+ * Move or rename the listened folder.
119
+ * Update/reboot your OS.
120
+
121
+ If it still falling back, feel free to [open an issue](https://github.com/guard/listen/issues/new) (and be sure to give all details).
122
+
123
+ ## Development [![Dependency Status](https://gemnasium.com/guard/listen.png?branch=master)](https://gemnasium.com/guard/listen)
124
+
125
+ * Documentation hosted at [RubyDoc](http://rubydoc.info/github/guard/listen/master/frames).
126
+ * Source hosted at [GitHub](https://github.com/guard/listen).
127
+
128
+ Pull requests are very welcome! Please try to follow these simple rules if applicable:
129
+
130
+ * Please create a topic branch for every separate change you make.
131
+ * Make sure your patches are well tested. All specs run with `rake spec:portability` must pass.
132
+ * Update the [Yard](http://yardoc.org/) documentation.
133
+ * Update the README.
134
+ * Update the CHANGELOG for noteworthy changes.
135
+ * Please **do not change** the version number.
136
+
137
+ For questions please join us in our [Google group](http://groups.google.com/group/guard-dev) or on
138
+ `#guard` (irc.freenode.net).
139
+
84
140
  ## Acknowledgment
85
141
 
86
- - [Travis Tilley (ttilley)][] for this awesome work on [fssm][] & [rb-fsevent][].
87
- - [Nathan Weizenbaum (nex3)][] for [rb-inotify][], a thorough inotify wrapper.
88
- - [stereobooster][] for [rb-fchange][], windows support wouldn't exist without him.
89
- - [Yehuda Katz (wycats)][] for [vigilo][], that has been a great source of inspiration.
142
+ * [Michael Kessler (netzpirat)][] for having written the [initial specs](https://github.com/guard/listen/commit/1e457b13b1bb8a25d2240428ce5ed488bafbed1f).
143
+ * [Travis Tilley (ttilley)][] for this awesome work on [fssm][] & [rb-fsevent][].
144
+ * [Nathan Weizenbaum (nex3)][] for [rb-inotify][], a thorough inotify wrapper.
145
+ * [stereobooster][] for [rb-fchange][], windows support wouldn't exist without him.
146
+ * [Yehuda Katz (wycats)][] for [vigilo][], that has been a great source of inspiration.
147
+
148
+ ## Author
149
+
150
+ [Thibaud Guillaume-Gentil][] ([@thibaudgg](http://twitter.com/thibaudgg))
151
+
152
+ ## Contributors
153
+
154
+ [https://github.com/guard/listen/contributors](https://github.com/guard/listen/contributors)
90
155
 
156
+ [Thibaud Guillaume-Gentil]: https://github.com/thibaudgg
157
+ [Michael Kessler (netzpirat)]: https://github.com/netzpirat
91
158
  [Travis Tilley (ttilley)]: https://github.com/ttilley
92
159
  [fssm]: https://github.com/ttilley/fssm
93
160
  [rb-fsevent]: https://github.com/thibaudgg/rb-fsevent
data/lib/listen.rb CHANGED
@@ -8,6 +8,8 @@ module Listen
8
8
  # @param [Hash] options the listen options
9
9
  # @option options [String] ignore a list of paths to ignore
10
10
  # @option options [Regexp] filter a list of regexps file filters
11
+ # @option options [Float] latency the delay between checking for changes in seconds
12
+ # @option options [Boolean] polling whether to force or disable the polling adapter
11
13
  #
12
14
  # @yield [modified, added, removed] the changed files
13
15
  # @yieldparam [Array<String>] modified the list of modified files
@@ -4,35 +4,115 @@ module Listen
4
4
  class Adapter
5
5
  attr_accessor :latency
6
6
 
7
+ # The default delay between checking for changes.
8
+ DEFAULT_LATENCY = 0.1
9
+ # The default warning message when falling back to polling adapter.
10
+ POLLING_FALLBACK_MESSAGE = "WARNING: Listen fallen back to polling, learn more at https://github.com/guard/listen#fallback."
11
+
7
12
  # Select the appropriate adapter implementation for the
8
13
  # current OS and initializes it.
9
14
  #
15
+ # @param [String, Pathname] directory the directory to watch
16
+ # @param [Hash] options the adapter options
17
+ # @option options [Boolean] force_polling to force polling or not
18
+ # @option options [String, Boolean] polling_fallback_message to change polling fallback message or remove it
19
+ # @option options [Float] latency the delay between checking for changes in seconds
20
+ #
21
+ # @yield [changed_dirs, options] callback Callback called when a change happens
22
+ # @yieldparam [Array<String>] changed_dirs the changed directories
23
+ # @yieldparam [Hash] options callback options (like :recursive => true)
24
+ #
10
25
  # @return [Listen::Adapter] the chosen adapter
11
26
  #
12
- def self.select_and_initialize(listener)
13
- if Adapters::Darwin.usable?
14
- Adapters::Darwin.new(listener)
15
- elsif Adapters::Linux.usable?
16
- Adapters::Linux.new(listener)
17
- elsif Adapters::Windows.usable?
18
- Adapters::Windows.new(listener)
27
+ def self.select_and_initialize(directory, options = {}, &callback)
28
+ return Adapters::Polling.new(directory, options, &callback) if options.delete(:force_polling)
29
+
30
+ if Adapters::Darwin.usable_and_work?(directory, options)
31
+ Adapters::Darwin.new(directory, options, &callback)
32
+ elsif Adapters::Linux.usable_and_work?(directory, options)
33
+ Adapters::Linux.new(directory, options, &callback)
34
+ elsif Adapters::Windows.usable_and_work?(directory, options)
35
+ Adapters::Windows.new(directory, options, &callback)
19
36
  else
20
- Adapters::Polling.new(listener)
37
+ unless options[:polling_fallback_message] == false
38
+ Kernel.warn(options[:polling_fallback_message] || POLLING_FALLBACK_MESSAGE)
39
+ end
40
+ Adapters::Polling.new(directory, options, &callback)
21
41
  end
22
42
  end
23
43
 
24
- def initialize(listener)
25
- @listener = listener
44
+ # Initialize the adapter.
45
+ #
46
+ # @param [String, Pathname] directory the directory to watch
47
+ # @param [Hash] options the adapter options
48
+ # @option options [Float] latency the delay between checking for changes in seconds
49
+ #
50
+ # @yield [changed_dirs, options] callback Callback called when a change happens
51
+ # @yieldparam [Array<String>] changed_dirs the changed directories
52
+ # @yieldparam [Hash] options callback options (like :recursive => true)
53
+ #
54
+ # @return [Listen::Adapter] the adapter
55
+ #
56
+ def initialize(directory, options = {}, &callback)
57
+ @directory = directory
58
+ @callback = callback
59
+ @latency ||= DEFAULT_LATENCY
60
+ @latency = options[:latency] if options[:latency]
26
61
  end
27
62
 
28
63
  # Start the adapter.
29
64
  #
30
65
  def start
66
+ @stop = false
31
67
  end
32
68
 
33
69
  # Stop the adapter.
34
70
  #
35
71
  def stop
72
+ @stop = true
73
+ end
74
+
75
+ private
76
+
77
+ # Check if the adapter is usable and works on the current OS.
78
+ #
79
+ # @param [String, Pathname] directory the directory to watch
80
+ # @param [Hash] options the adapter options
81
+ # @option options [Float] latency the delay between checking for changes in seconds
82
+ #
83
+ # @return [Boolean] whether usable and work or not
84
+ #
85
+ def self.usable_and_work?(directory, options = {})
86
+ usable? && work?(directory, options)
87
+ end
88
+
89
+ # Check if the adapter is really working on the current OS by actually testing it.
90
+ # This test take some time depending the adapter latency (max latency + 0.2 seconds).
91
+ #
92
+ # @param [String, Pathname] directory the directory to watch
93
+ # @param [Hash] options the adapter options
94
+ # @option options [Float] latency the delay between checking for changes in seconds
95
+ #
96
+ # @return [Boolean] whether work or not
97
+ #
98
+ def self.work?(directory, options = {})
99
+ @work = nil
100
+ Thread.new do
101
+ begin
102
+ callback = lambda { |changed_dirs, options| @work = true }
103
+ adapter = self.new(directory, options, &callback)
104
+ thread = Thread.new { adapter.start }
105
+ sleep 0.1 # wait for the adapter starts
106
+ FileUtils.touch "#{directory}/.listen_test"
107
+ sleep adapter.latency + 0.1 # wait for callback
108
+ @work ||= false
109
+ Thread.kill(thread)
110
+ ensure
111
+ FileUtils.rm "#{directory}/.listen_test"
112
+ end
113
+ end
114
+ sleep 0.01 while @work.nil?
115
+ @work
36
116
  end
37
117
 
38
118
  end
@@ -5,11 +5,10 @@ module Listen
5
5
  #
6
6
  class Darwin < Adapter
7
7
 
8
- # Initialize the Adapter.
8
+ # Initialize the Adapter. See {Listen::Adapter#initialize} for more info.
9
9
  #
10
- def initialize(*)
10
+ def initialize(directory, options = {}, &callback)
11
11
  super
12
- @latency ||= 0.1
13
12
  init_worker
14
13
  end
15
14
 
@@ -46,9 +45,9 @@ module Listen
46
45
  #
47
46
  def init_worker
48
47
  @worker = FSEvent.new
49
- @worker.watch(@listener.directory, :latency => @latency) do |changed_dirs|
48
+ @worker.watch(@directory, :latency => @latency) do |changed_dirs|
50
49
  changed_dirs.map! { |path| path.sub /\/$/, '' }
51
- @listener.on_change(changed_dirs)
50
+ @callback.call(changed_dirs, {})
52
51
  end
53
52
  end
54
53
 
@@ -9,16 +9,15 @@ module Listen
9
9
  # @see https://github.com/nex3/rb-inotify/blob/master/lib/rb-inotify/notifier.rb#L99-L177
10
10
  #
11
11
  EVENTS = %w[recursive attrib close modify move create delete delete_self move_self]
12
-
12
+
13
13
  # Listener implementation for Linux `inotify`.
14
14
  #
15
15
  class Linux < Adapter
16
16
 
17
- # Initialize the Adapter.
17
+ # Initialize the Adapter. See {Listen::Adapter#initialize} for more info.
18
18
  #
19
- def initialize(*)
19
+ def initialize(directory, options = {}, &callback)
20
20
  super
21
- @latency ||= 0.1
22
21
  @changed_dirs = Set.new
23
22
  init_worker
24
23
  end
@@ -28,7 +27,6 @@ module Listen
28
27
  def start
29
28
  super
30
29
  Thread.new { @worker.run }
31
- @stop = false
32
30
  poll_changed_dirs
33
31
  end
34
32
 
@@ -36,7 +34,6 @@ module Listen
36
34
  #
37
35
  def stop
38
36
  super
39
- @stop = true
40
37
  @worker.stop
41
38
  end
42
39
 
@@ -54,28 +51,27 @@ module Listen
54
51
  end
55
52
 
56
53
  private
57
-
58
- # Initialiaze INotify worker and set watch callback block.
54
+
55
+ # Initialize INotify worker and set watch callback block.
59
56
  #
60
57
  def init_worker
61
58
  @worker = INotify::Notifier.new
62
- @worker.watch(@listener.directory, *EVENTS.map(&:to_sym)) do |event|
59
+ @worker.watch(@directory, *EVENTS.map(&:to_sym)) do |event|
63
60
  unless event.name == "" # Event on root directory
64
61
  @changed_dirs << File.dirname(event.absolute_name)
65
62
  end
66
63
  end
67
64
  end
68
-
65
+
69
66
  # Polling around @changed_dirs presence.
70
67
  #
71
68
  def poll_changed_dirs
72
69
  until @stop
73
70
  sleep(@latency)
74
-
75
71
  next if @changed_dirs.empty?
76
72
  changed_dirs = @changed_dirs.to_a
77
- @changed_dirs.clear
78
- @listener.on_change(changed_dirs)
73
+ @changed_dirs.clear
74
+ @callback.call(changed_dirs, {})
79
75
  end
80
76
  end
81
77
 
@@ -1,6 +1,9 @@
1
1
  module Listen
2
2
  module Adapters
3
3
 
4
+ # The default delay between checking for changes.
5
+ DEFAULT_POLLING_LATENCY = 1.0
6
+
4
7
  # Polling Adapter that works cross-platform and
5
8
  # has no dependencies. This is the adapter that
6
9
  # uses the most CPU processing power and has higher
@@ -8,18 +11,17 @@ module Listen
8
11
  #
9
12
  class Polling < Adapter
10
13
 
11
- # Initialize the Adapter.
14
+ # Initialize the Adapter. See {Listen::Adapter#initialize} for more info.
12
15
  #
13
- def initialize(*)
16
+ def initialize(directory, options = {}, &callback)
17
+ @latency ||= DEFAULT_POLLING_LATENCY
14
18
  super
15
- @latency ||= 1.0
16
19
  end
17
20
 
18
21
  # Start the adapter.
19
22
  #
20
23
  def start
21
24
  super
22
- @stop = false
23
25
  poll
24
26
  end
25
27
 
@@ -27,7 +29,6 @@ module Listen
27
29
  #
28
30
  def stop
29
31
  super
30
- @stop = true
31
32
  end
32
33
 
33
34
  private
@@ -37,10 +38,11 @@ module Listen
37
38
  def poll
38
39
  until @stop
39
40
  start = Time.now.to_f
40
- @listener.on_change([@listener.directory], :recursive => true)
41
+ @callback.call([@directory], :recursive => true)
41
42
  nap_time = @latency - (Time.now.to_f - start)
42
43
  sleep(nap_time) if nap_time > 0
43
44
  end
45
+ rescue Interrupt
44
46
  end
45
47
 
46
48
  end
@@ -7,11 +7,10 @@ module Listen
7
7
  #
8
8
  class Windows < Adapter
9
9
 
10
- # Initialize the Adapter.
10
+ # Initialize the Adapter. See {Listen::Adapter#initialize} for more info.
11
11
  #
12
- def initialize(*)
12
+ def initialize(directory, options = {}, &callback)
13
13
  super
14
- @latency ||= 0.1
15
14
  @changed_dirs = Set.new
16
15
  init_worker
17
16
  end
@@ -21,7 +20,6 @@ module Listen
21
20
  def start
22
21
  super
23
22
  Thread.new { @worker.run }
24
- @stop = false
25
23
  poll_changed_dirs
26
24
  end
27
25
 
@@ -51,21 +49,21 @@ module Listen
51
49
  #
52
50
  def init_worker
53
51
  @worker = FChange::Notifier.new
54
- @worker.watch(@listener.directory, :all_events, :recursive) do |event|
52
+ @worker.watch(@directory, :all_events, :recursive) do |event|
55
53
  @changed_dirs << File.expand_path(event.watcher.path)
56
54
  end
57
55
  end
58
-
56
+
59
57
  # Polling around @changed_dirs presence.
60
58
  #
61
59
  def poll_changed_dirs
62
60
  until @stop
63
61
  sleep(@latency)
64
-
62
+
65
63
  next if @changed_dirs.empty?
66
64
  changed_dirs = @changed_dirs.to_a
67
65
  @changed_dirs.clear
68
- @listener.on_change(changed_dirs, :recursive => true)
66
+ @callback.call(changed_dirs, :recursive => true)
69
67
  end
70
68
  end
71
69
 
@@ -9,17 +9,20 @@ require 'listen/adapters/windows'
9
9
 
10
10
  module Listen
11
11
  class Listener
12
- attr_accessor :directory, :ignored_paths, :file_filters, :sha1_checksums, :paths, :adapter
12
+ attr_accessor :directory, :ignored_paths, :file_filters, :sha1_checksums, :paths
13
13
 
14
14
  # Default paths that gets ignored by the listener
15
15
  DEFAULT_IGNORED_PATHS = %w[.bundle .git .DS_Store log tmp vendor]
16
16
 
17
17
  # Initialize the file listener.
18
18
  #
19
- # @param [String, Pathname] dir the directory to watch
19
+ # @param [String, Pathname] directory the directory to watch
20
20
  # @param [Hash] options the listen options
21
21
  # @option options [String] ignore a list of paths to ignore
22
22
  # @option options [Regexp] filter a list of regexps file filters
23
+ # @option options [Float] latency the delay between checking for changes in seconds
24
+ # @option options [Boolean] force_polling whether to force the polling adapter or not
25
+ # @option options [String, Boolean] polling_fallback_message to change polling fallback message or remove it
23
26
  #
24
27
  # @yield [modified, added, removed] the changed files
25
28
  # @yieldparam [Array<String>] modified the list of modified files
@@ -28,23 +31,24 @@ module Listen
28
31
  #
29
32
  # @return [Listen::Listener] the file listener
30
33
  #
31
- def initialize(*args, &block)
32
- @directory = args.first
34
+ def initialize(directory, options = {}, &block)
35
+ @directory = directory
33
36
  @ignored_paths = DEFAULT_IGNORED_PATHS
34
37
  @file_filters = []
35
38
  @sha1_checksums = {}
36
39
  @block = block
37
- if args[1]
38
- @ignored_paths += Array(args[1][:ignore]) if args[1][:ignore]
39
- @file_filters += Array(args[1][:filter]) if args[1][:filter]
40
- end
41
- @adapter = Adapter.select_and_initialize(self)
40
+ @ignored_paths += Array(options.delete(:ignore)) if options[:ignore]
41
+ @file_filters += Array(options.delete(:filter)) if options[:filter]
42
+
43
+ @adapter_options = options
42
44
  end
43
45
 
44
- # Initialize the @paths and start the adapter.
46
+ # Initialize the adapter and the @paths concurrently and start the adapter.
45
47
  #
46
48
  def start
49
+ Thread.new { @adapter = initialize_adapter }
47
50
  init_paths
51
+ sleep 0.01 while @adapter.nil?
48
52
  @adapter.start
49
53
  end
50
54
 
@@ -82,9 +86,53 @@ module Listen
82
86
  self
83
87
  end
84
88
 
89
+ # Sets the latency for the adapter. This is a helper method
90
+ # to simplify changing the latency directly from the listener.
91
+ #
92
+ # @example Wait 0.5 seconds each time before checking changes
93
+ # latency 0.5
94
+ #
95
+ # @param [Float] seconds the amount of delay, in seconds
96
+ #
97
+ # @return [Listen::Listener] the listener itself
98
+ #
99
+ def latency(seconds)
100
+ @adapter_options[:latency] = seconds
101
+ self
102
+ end
103
+
104
+ # Defines whether the use of the polling adapter
105
+ # should be forced or not.
106
+ #
107
+ # @example Forcing the use of the polling adapter
108
+ # force_polling true
109
+ #
110
+ # @param [Boolean] value wheather to force the polling adapter or not
111
+ #
112
+ # @return [Listen::Listener] the listener itself
113
+ #
114
+ def force_polling(value)
115
+ @adapter_options[:force_polling] = value
116
+ self
117
+ end
118
+
119
+ # Defines a custom polling fallback message of disable it.
120
+ #
121
+ # @example Disabling the polling fallback message
122
+ # polling_fallback_message false
123
+ #
124
+ # @param [String, Boolean] value to change polling fallback message or remove it
125
+ #
126
+ # @return [Listen::Listener] the listener itself
127
+ #
128
+ def polling_fallback_message(value)
129
+ @adapter_options[:polling_fallback_message] = value
130
+ self
131
+ end
132
+
85
133
  # Set change callback block to the listener.
86
134
  #
87
- # @example Filter some files
135
+ # @example Assign a callback to be called on changes
88
136
  # callback = lambda { |modified, added, removed| ... }
89
137
  # change &callback
90
138
  #
@@ -136,6 +184,13 @@ module Listen
136
184
 
137
185
  private
138
186
 
187
+ # Initialize adapter with the listener callback and the @adapter_options
188
+ #
189
+ def initialize_adapter
190
+ callback = lambda { |changed_dirs, options| self.on_change(changed_dirs, options) }
191
+ Adapter.select_and_initialize(@directory, @adapter_options, &callback)
192
+ end
193
+
139
194
  # Research all existing paths (directories & files) filtered and without ignored directories paths.
140
195
  #
141
196
  # @yield [path] the existing path
@@ -183,7 +238,7 @@ module Listen
183
238
  def detect_modifications_and_removals(directory, options = {})
184
239
  @paths[directory].each do |basename, type|
185
240
  path = File.join(directory, basename)
186
-
241
+
187
242
  case type
188
243
  when 'Dir'
189
244
  if File.directory?(path)
@@ -1,3 +1,3 @@
1
1
  module Listen
2
- VERSION = '0.2.0'
2
+ VERSION = '0.3.0'
3
3
  end
metadata CHANGED
@@ -1,20 +1,19 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: listen
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - Thibaud Guillaume-Gentil
9
- - Michael Kessler
10
9
  autorequire:
11
10
  bindir: bin
12
11
  cert_chain: []
13
- date: 2012-02-12 00:00:00.000000000 Z
12
+ date: 2012-02-21 00:00:00.000000000 Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
15
  name: rb-fsevent
17
- requirement: &70294412755220 !ruby/object:Gem::Requirement
16
+ requirement: &70190939404480 !ruby/object:Gem::Requirement
18
17
  none: false
19
18
  requirements:
20
19
  - - ~>
@@ -22,10 +21,10 @@ dependencies:
22
21
  version: 0.9.0
23
22
  type: :runtime
24
23
  prerelease: false
25
- version_requirements: *70294412755220
24
+ version_requirements: *70190939404480
26
25
  - !ruby/object:Gem::Dependency
27
26
  name: rb-inotify
28
- requirement: &70294412770880 !ruby/object:Gem::Requirement
27
+ requirement: &70190939403840 !ruby/object:Gem::Requirement
29
28
  none: false
30
29
  requirements:
31
30
  - - ~>
@@ -33,10 +32,10 @@ dependencies:
33
32
  version: 0.8.8
34
33
  type: :runtime
35
34
  prerelease: false
36
- version_requirements: *70294412770880
35
+ version_requirements: *70190939403840
37
36
  - !ruby/object:Gem::Dependency
38
37
  name: rb-fchange
39
- requirement: &70294412770160 !ruby/object:Gem::Requirement
38
+ requirement: &70190939403220 !ruby/object:Gem::Requirement
40
39
  none: false
41
40
  requirements:
42
41
  - - ~>
@@ -44,10 +43,10 @@ dependencies:
44
43
  version: 0.0.5
45
44
  type: :runtime
46
45
  prerelease: false
47
- version_requirements: *70294412770160
46
+ version_requirements: *70190939403220
48
47
  - !ruby/object:Gem::Dependency
49
48
  name: bundler
50
- requirement: &70294412769580 !ruby/object:Gem::Requirement
49
+ requirement: &70190939402680 !ruby/object:Gem::Requirement
51
50
  none: false
52
51
  requirements:
53
52
  - - ! '>='
@@ -55,12 +54,11 @@ dependencies:
55
54
  version: '0'
56
55
  type: :development
57
56
  prerelease: false
58
- version_requirements: *70294412769580
57
+ version_requirements: *70190939402680
59
58
  description: The Listen gem listens to file modifications and notifies you about the
60
59
  changes. Works everywhere!
61
60
  email:
62
61
  - thibaud@thibaud.me
63
- - michi@netzpiraten.ch
64
62
  executables: []
65
63
  extensions: []
66
64
  extra_rdoc_files: []
@@ -96,7 +94,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
96
94
  version: 1.3.6
97
95
  requirements: []
98
96
  rubyforge_project: listen
99
- rubygems_version: 1.8.15
97
+ rubygems_version: 1.8.16
100
98
  signing_key:
101
99
  specification_version: 3
102
100
  summary: Listen to file modifications