sass 3.2.5 → 3.2.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. data/VERSION +1 -1
  2. data/VERSION_DATE +1 -1
  3. data/bin/sass +2 -1
  4. data/bin/sass-convert +2 -1
  5. data/bin/scss +2 -1
  6. data/lib/sass/cache_stores/chain.rb +1 -1
  7. data/lib/sass/cache_stores/filesystem.rb +0 -1
  8. data/lib/sass/engine.rb +7 -1
  9. data/lib/sass/importers/filesystem.rb +1 -1
  10. data/lib/sass/media.rb +1 -4
  11. data/lib/sass/script/funcall.rb +43 -8
  12. data/lib/sass/script/lexer.rb +0 -2
  13. data/lib/sass/script/parser.rb +0 -2
  14. data/lib/sass/scss/parser.rb +13 -1
  15. data/lib/sass/selector/simple_sequence.rb +1 -1
  16. data/lib/sass/tree/comment_node.rb +2 -2
  17. data/lib/sass/tree/visitors/cssize.rb +10 -1
  18. data/lib/sass/tree/visitors/perform.rb +4 -2
  19. data/lib/sass/util.rb +54 -1
  20. data/lib/sass/util/multibyte_string_scanner.rb +29 -8
  21. data/test/sass/engine_test.rb +16 -0
  22. data/test/sass/extend_test.rb +15 -0
  23. data/test/sass/script_test.rb +3 -1
  24. data/vendor/listen/CHANGELOG.md +76 -2
  25. data/vendor/listen/CONTRIBUTING.md +38 -0
  26. data/vendor/listen/Gemfile +8 -1
  27. data/vendor/listen/Guardfile +1 -1
  28. data/vendor/listen/LICENSE +1 -1
  29. data/vendor/listen/README.md +8 -5
  30. data/vendor/listen/lib/listen.rb +7 -5
  31. data/vendor/listen/lib/listen/adapter.rb +76 -29
  32. data/vendor/listen/lib/listen/adapters/bsd.rb +112 -0
  33. data/vendor/listen/lib/listen/adapters/darwin.rb +11 -10
  34. data/vendor/listen/lib/listen/adapters/linux.rb +33 -30
  35. data/vendor/listen/lib/listen/adapters/polling.rb +2 -1
  36. data/vendor/listen/lib/listen/adapters/windows.rb +27 -21
  37. data/vendor/listen/lib/listen/dependency_manager.rb +126 -0
  38. data/vendor/listen/lib/listen/directory_record.rb +63 -10
  39. data/vendor/listen/lib/listen/listener.rb +22 -0
  40. data/vendor/listen/lib/listen/multi_listener.rb +22 -0
  41. data/vendor/listen/lib/listen/version.rb +1 -1
  42. data/vendor/listen/listen.gemspec +0 -4
  43. data/vendor/listen/spec/listen/adapter_spec.rb +45 -4
  44. data/vendor/listen/spec/listen/adapters/bsd_spec.rb +36 -0
  45. data/vendor/listen/spec/listen/adapters/darwin_spec.rb +6 -0
  46. data/vendor/listen/spec/listen/adapters/linux_spec.rb +6 -0
  47. data/vendor/listen/spec/listen/adapters/windows_spec.rb +7 -1
  48. data/vendor/listen/spec/listen/dependency_manager_spec.rb +107 -0
  49. data/vendor/listen/spec/listen/directory_record_spec.rb +91 -4
  50. data/vendor/listen/spec/listen/listener_spec.rb +14 -0
  51. data/vendor/listen/spec/listen/multi_listener_spec.rb +19 -1
  52. data/vendor/listen/spec/spec_helper.rb +6 -3
  53. data/vendor/listen/spec/support/adapter_helper.rb +125 -212
  54. data/vendor/listen/spec/support/listeners_helper.rb +13 -1
  55. data/vendor/listen/spec/support/platform_helper.rb +4 -0
  56. metadata +9 -3
@@ -493,7 +493,9 @@ SASS
493
493
  # argument errors caused by programming errors in a function and
494
494
  # argument errors explicitly thrown within that function.
495
495
  return if RUBY_PLATFORM =~ /java/
496
- assert_raise_message(ArgumentError, 'wrong number of arguments (0 for 1)') {resolve("arg-error()")}
496
+
497
+ # Don't validate the message; it's different on Rubinius.
498
+ assert_raise(ArgumentError) {resolve("arg-error()")}
497
499
  end
498
500
 
499
501
  def test_shallow_argument_error_unwrapped
@@ -1,3 +1,62 @@
1
+ ## 0.7.2 - January 11, 2013
2
+
3
+ ### Bug fix
4
+
5
+ - [#76] Exception on filename which is not in UTF-8. (fixed by [@piotr-sokolowski][])
6
+
7
+ ## 0.7.1 - January 6, 2013
8
+
9
+ ### Bug fix
10
+
11
+ - [#75] Default high precision off if the mtime call fails. (fixed by [@zanker][])
12
+
13
+ ## 0.7.0 - December 29, 2012
14
+
15
+ ### Bug fixes
16
+
17
+ - [#73] Rescue Errno::EOPNOTSUPP on sha1_checksum generation. (fixed by [@thibaudgg][])
18
+
19
+ ### New feature
20
+
21
+ - Add support for *BSD with rb-kqueue. ([@mat813][])
22
+
23
+ ## 0.6.0 - November 21, 2012
24
+
25
+ ### New feature
26
+
27
+ - Add bang versions for filter and ignore listener methods. ([@tarsolya][])
28
+
29
+ ## 0.5.3 - October 3, 2012
30
+
31
+ ### Bug fixes
32
+
33
+ - [#65] Fix ruby warning in adapter.rb. (fixed by [@vongruenigen][])
34
+ - [#64] ENXIO raised when hashing UNIX domain socket file. (fixed by [@sunaku][])
35
+
36
+ ## 0.5.2 - Septemper 23, 2012
37
+
38
+ ### Bug fix
39
+
40
+ - [#62] Fix double change callback with polling adapter. (fixed by [@thibaudgg][])
41
+
42
+ ## 0.5.1 - Septemper 18, 2012
43
+
44
+ ### Bug fix
45
+
46
+ - [#61] Fix a synchronisation bug that caused constant fallback to polling. (fixed by [@Maher4Ever][])
47
+
48
+ ## 0.5.0 - Septemper 1, 2012
49
+
50
+ ### New features
51
+
52
+ - Add a dependency manager to handle platform-specific gems. So there is no need anymore to install
53
+ extra gems which will never be used on the user system. ([@Maher4Ever][])
54
+ - Add a manual reporting mode to the adapters. ([@Maher4Ever][])
55
+
56
+ ### Improvements
57
+
58
+ - [#28] Enhance the speed of detecting changes on Windows by using the [WDM][] library. ([@Maher4Ever][])
59
+
1
60
  ## 0.4.7 - June 27, 2012
2
61
 
3
62
  ### Bug fixes
@@ -128,8 +187,16 @@
128
187
  [#21]: https://github.com/guard/listen/issues/21
129
188
  [#24]: https://github.com/guard/listen/issues/24
130
189
  [#27]: https://github.com/guard/listen/issues/27
190
+ [#28]: https://github.com/guard/listen/issues/28
131
191
  [#32]: https://github.com/guard/listen/issues/32
132
- [#39]: https://github.com/guard/listen/issues/39
192
+ [#41]: https://github.com/guard/listen/issues/41
193
+ [#61]: https://github.com/guard/listen/issues/61
194
+ [#62]: https://github.com/guard/listen/issues/62
195
+ [#64]: https://github.com/guard/listen/issues/64
196
+ [#65]: https://github.com/guard/listen/issues/65
197
+ [#73]: https://github.com/guard/listen/issues/73
198
+ [#75]: https://github.com/guard/listen/issues/75
199
+ [#76]: https://github.com/guard/listen/issues/76
133
200
  [@Maher4Ever]: https://github.com/Maher4Ever
134
201
  [@dkubb]: https://github.com/dkubb
135
202
  [@ebroder]: https://github.com/ebroder
@@ -138,10 +205,17 @@
138
205
  [@daemonza]: https://github.com/daemonza
139
206
  [@fny]: https://github.com/fny
140
207
  [@markiz]: https://github.com/markiz
208
+ [@mat813]: https://github.com/mat813
141
209
  [@napcs]: https://github.com/napcs
142
210
  [@netzpirat]: https://github.com/netzpirat
143
211
  [@nex3]: https://github.com/nex3
212
+ [@piotr-sokolowski]: https://github.com/piotr-sokolowski
144
213
  [@rymai]: https://github.com/rymai
145
214
  [@scottdavis]: https://github.com/scottdavis
215
+ [@sunaku]: https://github.com/sunaku
146
216
  [@textgoeshere]: https://github.com/textgoeshere
147
- [@thibaudgg]: https://github.com/thibaudgg
217
+ [@thibaudgg]: https://github.com/thibaudgg
218
+ [@tarsolya]: https://github.com/tarsolya
219
+ [@vongruenigen]: https://github.com/vongruenigen
220
+ [@zanker]: https://github.com/zanker
221
+ [WDM]: https://github.com/Maher4Ever/wdm
@@ -0,0 +1,38 @@
1
+ Contribute to Listen
2
+ ===================
3
+
4
+ File an issue
5
+ -------------
6
+
7
+ You can report bugs and feature requests to [GitHub Issues](https://github.com/guard/listen/issues).
8
+
9
+ **Please don't ask question in the issue tracker**, instead ask them in our
10
+ [Google group](http://groups.google.com/group/guard-dev) or on `#guard` (irc.freenode.net).
11
+
12
+ Try to figure out where the issue belongs to: Is it an issue with Listen itself or with Guard?
13
+
14
+ When you file a bug, please try to follow these simple rules if applicable:
15
+
16
+ * Make sure you run Listen with `bundle exec` first.
17
+ * Add your `Guardfile` (if used) and `Gemfile` to the issue.
18
+ * Make sure that the issue is reproducible with your description.
19
+
20
+ **It's most likely that your bug gets resolved faster if you provide as much information as possible!**
21
+
22
+ Development
23
+ -----------
24
+
25
+ * Documentation hosted at [RubyDoc](http://rubydoc.info/github/guard/listen/master/frames).
26
+ * Source hosted at [GitHub](https://github.com/guard/listen).
27
+
28
+ Pull requests are very welcome! Please try to follow these simple rules if applicable:
29
+
30
+ * Please create a topic branch for every separate change you make.
31
+ * Make sure your patches are well tested. All specs run with `rake spec` must pass.
32
+ * Update the [Yard](http://yardoc.org/) documentation.
33
+ * Update the [README](https://github.com/guard/listen/blob/master/README.md).
34
+ * Update the [CHANGELOG](https://github.com/guard/listen/blob/master/CHANGELOG.md) for noteworthy changes.
35
+ * Please **do not change** the version number.
36
+
37
+ For questions please join us in our [Google group](http://groups.google.com/group/guard-dev) or on
38
+ `#guard` (irc.freenode.net).
@@ -1,9 +1,16 @@
1
+ require 'rbconfig'
2
+
1
3
  source :rubygems
2
4
 
3
5
  gemspec
4
6
 
5
7
  gem 'rake'
6
8
 
9
+ gem 'rb-kqueue', '~> 0.2' if RbConfig::CONFIG['target_os'] =~ /freebsd/i
10
+ gem 'rb-fsevent', '~> 0.9.1' if RbConfig::CONFIG['target_os'] =~ /darwin(1.+)?$/i
11
+ gem 'rb-inotify', '~> 0.8.8', :github => 'mbj/rb-inotify' if RbConfig::CONFIG['target_os'] =~ /linux/i
12
+ gem 'wdm', '~> 0.0.3' if RbConfig::CONFIG['target_os'] =~ /mswin|mingw/i
13
+
7
14
  group :development do
8
15
  platform :ruby do
9
16
  gem 'coolline'
@@ -20,4 +27,4 @@ end
20
27
 
21
28
  group :test do
22
29
  gem 'rspec'
23
- end
30
+ end
@@ -1,4 +1,4 @@
1
- guard :rspec, :all_on_start => false, :all_after_pass => false, :cli => '--fail-fast --format doc' do
1
+ guard :rspec, :all_on_start => false, :all_after_pass => false do
2
2
  watch(%r{^spec/.+_spec\.rb$})
3
3
  watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
4
4
  watch('spec/support/adapter_helper.rb') { "spec/listen/adapters" }
@@ -1,4 +1,4 @@
1
- Copyright (c) 2012 Thibaud Guillaume-Gentil
1
+ Copyright (c) 2013 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
@@ -6,10 +6,10 @@ The Listen gem listens to file modifications and notifies you about the changes.
6
6
 
7
7
  * Works everywhere!
8
8
  * Supports watching multiple directories from a single listener.
9
- * OS-specific adapters for Mac OS X 10.6+, Linux and Windows.
9
+ * OS-specific adapters for Mac OS X 10.6+, Linux, *BSD and Windows.
10
10
  * Automatic fallback to polling if OS-specific adapter doesn't work.
11
- * Detects files modification, addidation and removal.
12
- * Checksum comparaison for modifications made under the same second.
11
+ * Detects file modification, addition and removal.
12
+ * Checksum comparison for modifications made under the same second.
13
13
  * Allows supplying regexp-patterns to ignore and filter paths for better results.
14
14
  * Tested on all Ruby environments via [travis-ci](http://travis-ci.org/guard/listen).
15
15
 
@@ -215,6 +215,8 @@ with a directory-separator, otherwise they won't work as expected.
215
215
  As an example: to ignore the `build` directory in a C-project, use `%r{build/}`
216
216
  and not `%r{/build/}`.
217
217
 
218
+ Use `#filter!` and `#ignore!` methods to overwrites default patterns.
219
+
218
220
  ### Non-blocking listening to changes
219
221
 
220
222
  Starting a listener blocks the current thread by default. That means any code after the
@@ -240,7 +242,7 @@ block execution. See the "Block API" section for an example.
240
242
  ## Listen adapters
241
243
 
242
244
  The Listen gem has a set of adapters to notify it when there are changes.
243
- There are 3 OS-specific adapters to support Mac, Linux and Windows. These adapters are fast
245
+ There are 3 OS-specific adapters to support Mac, Linux, *BSD and Windows. These adapters are fast
244
246
  as they use some system-calls to implement the notifying function.
245
247
 
246
248
  There is also a polling adapter which is a cross-platform adapter and it will
@@ -251,7 +253,6 @@ want to force the use of the polling adapter, either use the `:force_polling` op
251
253
  while initializing the listener or call the `force_polling` method on your listener
252
254
  before starting it.
253
255
 
254
- <a name="fallback"/>
255
256
  ## Polling fallback
256
257
 
257
258
  When a OS-specific adapter doesn't work the Listen gem automatically falls back to the polling adapter.
@@ -286,6 +287,7 @@ For questions please join us in our [Google group](http://groups.google.com/grou
286
287
  * [Michael Kessler (netzpirat)][] for having written the [initial specs](https://github.com/guard/listen/commit/1e457b13b1bb8a25d2240428ce5ed488bafbed1f).
287
288
  * [Travis Tilley (ttilley)][] for this awesome work on [fssm][] & [rb-fsevent][].
288
289
  * [Nathan Weizenbaum (nex3)][] for [rb-inotify][], a thorough inotify wrapper.
290
+ * [Mathieu Arnold (mat813)][] for [rb-kqueue][], a simple kqueue wrapper.
289
291
  * [stereobooster][] for [rb-fchange][], windows support wouldn't exist without him.
290
292
  * [Yehuda Katz (wycats)][] for [vigilo][], that has been a great source of inspiration.
291
293
 
@@ -304,6 +306,7 @@ For questions please join us in our [Google group](http://groups.google.com/grou
304
306
  [Travis Tilley (ttilley)]: https://github.com/ttilley
305
307
  [fssm]: https://github.com/ttilley/fssm
306
308
  [rb-fsevent]: https://github.com/thibaudgg/rb-fsevent
309
+ [Mathieu Arnold (mat813)]: https://github.com/mat813
307
310
  [Nathan Weizenbaum (nex3)]: https://github.com/nex3
308
311
  [rb-inotify]: https://github.com/nex3/rb-inotify
309
312
  [stereobooster]: https://github.com/stereobooster
@@ -1,14 +1,16 @@
1
1
  module Listen
2
2
 
3
- autoload :Turnstile, 'listen/turnstile'
4
- autoload :Listener, 'listen/listener'
5
- autoload :MultiListener, 'listen/multi_listener'
6
- autoload :DirectoryRecord, 'listen/directory_record'
7
- autoload :Adapter, 'listen/adapter'
3
+ autoload :Turnstile, 'listen/turnstile'
4
+ autoload :Listener, 'listen/listener'
5
+ autoload :MultiListener, 'listen/multi_listener'
6
+ autoload :DirectoryRecord, 'listen/directory_record'
7
+ autoload :DependencyManager, 'listen/dependency_manager'
8
+ autoload :Adapter, 'listen/adapter'
8
9
 
9
10
  module Adapters
10
11
  autoload :Darwin, 'listen/adapters/darwin'
11
12
  autoload :Linux, 'listen/adapters/linux'
13
+ autoload :BSD, 'listen/adapters/bsd'
12
14
  autoload :Windows, 'listen/adapters/windows'
13
15
  autoload :Polling, 'listen/adapters/polling'
14
16
  end
@@ -10,8 +10,15 @@ module Listen
10
10
  # The default delay between checking for changes.
11
11
  DEFAULT_LATENCY = 0.25
12
12
 
13
+ # The default warning message when there is a missing dependency.
14
+ MISSING_DEPENDENCY_MESSAGE = <<-EOS.gsub(/^\s*/, '')
15
+ For a better performance, it's recommended that you satisfy the missing dependency.
16
+ EOS
17
+
13
18
  # The default warning message when falling back to polling adapter.
14
- POLLING_FALLBACK_MESSAGE = "WARNING: Listen has fallen back to polling, learn more at https://github.com/guard/listen#fallback."
19
+ POLLING_FALLBACK_MESSAGE = <<-EOS.gsub(/^\s*/, '')
20
+ Listen will be polling changes. Learn more at https://github.com/guard/listen#polling-fallback.
21
+ EOS
15
22
 
16
23
  # Selects the appropriate adapter implementation for the
17
24
  # current OS and initializes it.
@@ -31,18 +38,28 @@ module Listen
31
38
  def self.select_and_initialize(directories, options = {}, &callback)
32
39
  return Adapters::Polling.new(directories, options, &callback) if options.delete(:force_polling)
33
40
 
34
- if Adapters::Darwin.usable_and_works?(directories, options)
35
- Adapters::Darwin.new(directories, options, &callback)
36
- elsif Adapters::Linux.usable_and_works?(directories, options)
37
- Adapters::Linux.new(directories, options, &callback)
38
- elsif Adapters::Windows.usable_and_works?(directories, options)
39
- Adapters::Windows.new(directories, options, &callback)
40
- else
41
- unless options[:polling_fallback_message] == false
42
- Kernel.warn(options[:polling_fallback_message] || POLLING_FALLBACK_MESSAGE)
41
+ warning = ''
42
+
43
+ begin
44
+ if Adapters::Darwin.usable_and_works?(directories, options)
45
+ return Adapters::Darwin.new(directories, options, &callback)
46
+ elsif Adapters::Linux.usable_and_works?(directories, options)
47
+ return Adapters::Linux.new(directories, options, &callback)
48
+ elsif Adapters::BSD.usable_and_works?(directories, options)
49
+ return Adapters::BSD.new(directories, options, &callback)
50
+ elsif Adapters::Windows.usable_and_works?(directories, options)
51
+ return Adapters::Windows.new(directories, options, &callback)
43
52
  end
44
- Adapters::Polling.new(directories, options, &callback)
53
+ rescue DependencyManager::Error => e
54
+ warning += e.message + "\n" + MISSING_DEPENDENCY_MESSAGE
55
+ end
56
+
57
+ unless options[:polling_fallback_message] == false
58
+ warning += options[:polling_fallback_message] || POLLING_FALLBACK_MESSAGE
59
+ Kernel.warn "[Listen warning]:\n" + warning.gsub(/^(.*)/, ' \1')
45
60
  end
61
+
62
+ Adapters::Polling.new(directories, options, &callback)
46
63
  end
47
64
 
48
65
  # Initializes the adapter.
@@ -50,6 +67,7 @@ module Listen
50
67
  # @param [String, Array<String>] directories the directories to watch
51
68
  # @param [Hash] options the adapter options
52
69
  # @option options [Float] latency the delay between checking for changes in seconds
70
+ # @option options [Boolean] report_changes whether or not to automatically report changes (run the callback)
53
71
  #
54
72
  # @yield [changed_dirs, options] callback Callback called when a change happens
55
73
  # @yieldparam [Array<String>] changed_dirs the changed directories
@@ -60,12 +78,13 @@ module Listen
60
78
  def initialize(directories, options = {}, &callback)
61
79
  @directories = Array(directories)
62
80
  @callback = callback
63
- @latency ||= DEFAULT_LATENCY
64
- @latency = options[:latency] if options[:latency]
65
81
  @paused = false
66
82
  @mutex = Mutex.new
67
83
  @changed_dirs = Set.new
68
84
  @turnstile = Turnstile.new
85
+ @latency ||= DEFAULT_LATENCY
86
+ @latency = options[:latency] if options[:latency]
87
+ @report_changes = options[:report_changes].nil? ? true : options[:report_changes]
69
88
  end
70
89
 
71
90
  # Starts the adapter.
@@ -92,12 +111,37 @@ module Listen
92
111
  end
93
112
 
94
113
  # Blocks the main thread until the poll thread
95
- # calls the callback.
114
+ # runs the callback.
96
115
  #
97
116
  def wait_for_callback
98
117
  @turnstile.wait unless @paused
99
118
  end
100
119
 
120
+ # Blocks the main thread until N changes are
121
+ # detected.
122
+ #
123
+ def wait_for_changes(goal = 0)
124
+ changes = 0
125
+
126
+ loop do
127
+ @mutex.synchronize { changes = @changed_dirs.size }
128
+
129
+ return if @paused || @stop
130
+ return if changes >= goal
131
+
132
+ sleep(@latency)
133
+ end
134
+ end
135
+
136
+ # Checks if the adapter is usable on the current OS.
137
+ #
138
+ # @return [Boolean] whether usable or not
139
+ #
140
+ def self.usable?
141
+ load_depenencies
142
+ dependencies_loaded?
143
+ end
144
+
101
145
  # Checks if the adapter is usable and works on the current OS.
102
146
  #
103
147
  # @param [String, Array<String>] directories the directories to watch
@@ -124,7 +168,7 @@ module Listen
124
168
  def self.works?(directory, options = {})
125
169
  work = false
126
170
  test_file = "#{directory}/.listen_test"
127
- callback = lambda { |changed_dirs, options| work = true }
171
+ callback = lambda { |*| work = true }
128
172
  adapter = self.new(directory, options, &callback)
129
173
  adapter.start(false)
130
174
 
@@ -140,27 +184,30 @@ module Listen
140
184
  adapter.stop if adapter && adapter.started?
141
185
  end
142
186
 
187
+ # Runs the callback and passes it the changes if there are any.
188
+ #
189
+ def report_changes
190
+ changed_dirs = nil
191
+
192
+ @mutex.synchronize do
193
+ return if @changed_dirs.empty?
194
+ changed_dirs = @changed_dirs.to_a
195
+ @changed_dirs.clear
196
+ end
197
+
198
+ @callback.call(changed_dirs, {})
199
+ @turnstile.signal
200
+ end
201
+
143
202
  private
144
203
 
145
204
  # Polls changed directories and reports them back
146
205
  # when there are changes.
147
206
  #
148
- # @option [Boolean] recursive whether or not to pass the recursive option to the callback
149
- #
150
- def poll_changed_dirs(recursive = false)
207
+ def poll_changed_dirs
151
208
  until @stop
152
209
  sleep(@latency)
153
- next if @changed_dirs.empty?
154
-
155
- changed_dirs = []
156
-
157
- @mutex.synchronize do
158
- changed_dirs = @changed_dirs.to_a
159
- @changed_dirs.clear
160
- end
161
-
162
- @callback.call(changed_dirs, recursive ? {:recursive => recursive} : {})
163
- @turnstile.signal
210
+ report_changes
164
211
  end
165
212
  end
166
213
  end
@@ -0,0 +1,112 @@
1
+ module Listen
2
+ module Adapters
3
+
4
+ # Listener implementation for BSD's `kqueue`.
5
+ #
6
+ class BSD < Adapter
7
+ extend DependencyManager
8
+
9
+ # Declare the adapter's dependencies
10
+ dependency 'rb-kqueue', '~> 0.2'
11
+
12
+ # Watched kqueue events
13
+ #
14
+ # @see http://www.freebsd.org/cgi/man.cgi?query=kqueue
15
+ # @see https://github.com/nex3/rb-kqueue/blob/master/lib/rb-kqueue/queue.rb
16
+ #
17
+ EVENTS = [ :delete, :write, :extend, :attrib, :link, :rename, :revoke ]
18
+
19
+ # Initializes the Adapter. See {Listen::Adapter#initialize} for
20
+ # more info.
21
+ #
22
+ def initialize(directories, options = {}, &callback)
23
+ super
24
+ @kqueue = init_kqueue
25
+ end
26
+
27
+ # Starts the adapter.
28
+ #
29
+ # @param [Boolean] blocking whether or not to block the current thread after starting
30
+ #
31
+ def start(blocking = true)
32
+ @mutex.synchronize do
33
+ return if @stop == false
34
+ super
35
+ end
36
+
37
+ @kqueue_thread = Thread.new do
38
+ until @stop
39
+ @kqueue.poll
40
+ sleep(@latency)
41
+ end
42
+ end
43
+ @poll_thread = Thread.new { poll_changed_dirs } if @report_changes
44
+
45
+ @kqueue_thread.join if blocking
46
+ end
47
+
48
+ # Stops the adapter.
49
+ #
50
+ def stop
51
+ @mutex.synchronize do
52
+ return if @stop == true
53
+ super
54
+ end
55
+
56
+ @kqueue.stop
57
+ Thread.kill(@kqueue_thread) if @kqueue_thread
58
+ @poll_thread.join if @poll_thread
59
+ end
60
+
61
+ # Checks if the adapter is usable on the current OS.
62
+ #
63
+ # @return [Boolean] whether usable or not
64
+ #
65
+ def self.usable?
66
+ return false unless RbConfig::CONFIG['target_os'] =~ /freebsd/i
67
+ super
68
+ end
69
+
70
+ private
71
+
72
+ # Initializes a kqueue Queue and adds a watcher for each files in
73
+ # the directories passed to the adapter.
74
+ #
75
+ # @return [INotify::Notifier] initialized kqueue
76
+ #
77
+ def init_kqueue
78
+ require 'find'
79
+
80
+ callback = lambda do |event|
81
+ path = event.watcher.path
82
+ @mutex.synchronize do
83
+ # kqueue watches everything, but Listen only needs the
84
+ # directory where stuffs happens.
85
+ @changed_dirs << (File.directory?(path) ? path : File.dirname(path))
86
+
87
+ # If it is a directory, and it has a write flag, it means a
88
+ # file has been added so find out which and deal with it.
89
+ # No need to check for removed file, kqueue will forget them
90
+ # when the vfs does..
91
+ if File.directory?(path) && !(event.flags & [:write]).empty?
92
+ queue = event.watcher.queue
93
+ Find.find(path) do |file|
94
+ unless queue.watchers.detect {|k,v| v.path == file.to_s}
95
+ queue.watch_file(file, *EVENTS, &callback)
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
101
+
102
+ KQueue::Queue.new.tap do |queue|
103
+ @directories.each do |directory|
104
+ Find.find(directory) do |path|
105
+ queue.watch_file(path, *EVENTS, &callback)
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end
112
+ end