listen 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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