sass 3.2.7 → 3.3.0.rc.1

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.
Files changed (184) hide show
  1. data/MIT-LICENSE +2 -2
  2. data/README.md +14 -2
  3. data/Rakefile +25 -1
  4. data/VERSION +1 -1
  5. data/VERSION_DATE +1 -1
  6. data/VERSION_NAME +1 -1
  7. data/lib/sass/cache_stores/base.rb +4 -2
  8. data/lib/sass/cache_stores/chain.rb +2 -1
  9. data/lib/sass/cache_stores/filesystem.rb +2 -6
  10. data/lib/sass/cache_stores/memory.rb +1 -1
  11. data/lib/sass/cache_stores/null.rb +2 -2
  12. data/lib/sass/callbacks.rb +1 -0
  13. data/lib/sass/css.rb +10 -10
  14. data/lib/sass/engine.rb +403 -150
  15. data/lib/sass/environment.rb +136 -57
  16. data/lib/sass/error.rb +7 -7
  17. data/lib/sass/exec.rb +123 -39
  18. data/lib/sass/features.rb +41 -0
  19. data/lib/sass/importers/base.rb +33 -2
  20. data/lib/sass/importers/deprecated_path.rb +45 -0
  21. data/lib/sass/importers/filesystem.rb +25 -14
  22. data/lib/sass/importers.rb +1 -0
  23. data/lib/sass/logger/base.rb +3 -3
  24. data/lib/sass/logger/log_level.rb +4 -6
  25. data/lib/sass/media.rb +19 -19
  26. data/lib/sass/plugin/compiler.rb +141 -101
  27. data/lib/sass/plugin/configuration.rb +18 -22
  28. data/lib/sass/plugin/merb.rb +1 -1
  29. data/lib/sass/plugin/staleness_checker.rb +24 -8
  30. data/lib/sass/plugin.rb +4 -2
  31. data/lib/sass/repl.rb +3 -3
  32. data/lib/sass/script/css_lexer.rb +9 -4
  33. data/lib/sass/script/css_parser.rb +6 -2
  34. data/lib/sass/script/functions.rb +1343 -590
  35. data/lib/sass/script/lexer.rb +84 -52
  36. data/lib/sass/script/parser.rb +217 -97
  37. data/lib/sass/script/tree/funcall.rb +290 -0
  38. data/lib/sass/script/{interpolation.rb → tree/interpolation.rb} +34 -13
  39. data/lib/sass/script/tree/list_literal.rb +80 -0
  40. data/lib/sass/script/tree/literal.rb +47 -0
  41. data/lib/sass/script/tree/map_literal.rb +64 -0
  42. data/lib/sass/script/{node.rb → tree/node.rb} +22 -12
  43. data/lib/sass/script/{operation.rb → tree/operation.rb} +17 -25
  44. data/lib/sass/script/tree/selector.rb +30 -0
  45. data/lib/sass/script/{string_interpolation.rb → tree/string_interpolation.rb} +5 -4
  46. data/lib/sass/script/{unary_operation.rb → tree/unary_operation.rb} +14 -9
  47. data/lib/sass/script/tree/variable.rb +57 -0
  48. data/lib/sass/script/tree.rb +16 -0
  49. data/lib/sass/script/{arg_list.rb → value/arg_list.rb} +4 -24
  50. data/lib/sass/script/value/base.rb +248 -0
  51. data/lib/sass/script/value/bool.rb +36 -0
  52. data/lib/sass/script/{color.rb → value/color.rb} +239 -195
  53. data/lib/sass/script/value/helpers.rb +155 -0
  54. data/lib/sass/script/value/list.rb +119 -0
  55. data/lib/sass/script/value/map.rb +70 -0
  56. data/lib/sass/script/value/null.rb +45 -0
  57. data/lib/sass/script/{number.rb → value/number.rb} +91 -65
  58. data/lib/sass/script/{string.rb → value/string.rb} +9 -11
  59. data/lib/sass/script/value.rb +11 -0
  60. data/lib/sass/script.rb +35 -8
  61. data/lib/sass/scss/css_parser.rb +2 -1
  62. data/lib/sass/scss/parser.rb +338 -170
  63. data/lib/sass/scss/rx.rb +5 -6
  64. data/lib/sass/scss/script_lexer.rb +1 -0
  65. data/lib/sass/scss/script_parser.rb +1 -0
  66. data/lib/sass/scss/static_parser.rb +23 -6
  67. data/lib/sass/selector/abstract_sequence.rb +2 -2
  68. data/lib/sass/selector/comma_sequence.rb +21 -16
  69. data/lib/sass/selector/sequence.rb +60 -34
  70. data/lib/sass/selector/simple.rb +11 -12
  71. data/lib/sass/selector/simple_sequence.rb +55 -33
  72. data/lib/sass/selector.rb +52 -48
  73. data/lib/sass/source/map.rb +211 -0
  74. data/lib/sass/source/position.rb +39 -0
  75. data/lib/sass/source/range.rb +41 -0
  76. data/lib/sass/stack.rb +120 -0
  77. data/lib/sass/supports.rb +12 -13
  78. data/lib/sass/tree/at_root_node.rb +82 -0
  79. data/lib/sass/tree/comment_node.rb +3 -3
  80. data/lib/sass/tree/css_import_node.rb +11 -11
  81. data/lib/sass/tree/debug_node.rb +2 -2
  82. data/lib/sass/tree/directive_node.rb +13 -2
  83. data/lib/sass/tree/each_node.rb +8 -8
  84. data/lib/sass/tree/extend_node.rb +13 -6
  85. data/lib/sass/tree/for_node.rb +4 -4
  86. data/lib/sass/tree/function_node.rb +5 -4
  87. data/lib/sass/tree/if_node.rb +1 -1
  88. data/lib/sass/tree/import_node.rb +4 -5
  89. data/lib/sass/tree/media_node.rb +4 -14
  90. data/lib/sass/tree/mixin_def_node.rb +4 -4
  91. data/lib/sass/tree/mixin_node.rb +21 -8
  92. data/lib/sass/tree/node.rb +29 -12
  93. data/lib/sass/tree/prop_node.rb +38 -18
  94. data/lib/sass/tree/return_node.rb +3 -2
  95. data/lib/sass/tree/root_node.rb +19 -3
  96. data/lib/sass/tree/rule_node.rb +25 -17
  97. data/lib/sass/tree/supports_node.rb +0 -13
  98. data/lib/sass/tree/trace_node.rb +2 -1
  99. data/lib/sass/tree/variable_node.rb +9 -3
  100. data/lib/sass/tree/visitors/base.rb +6 -6
  101. data/lib/sass/tree/visitors/check_nesting.rb +12 -9
  102. data/lib/sass/tree/visitors/convert.rb +63 -38
  103. data/lib/sass/tree/visitors/cssize.rb +63 -23
  104. data/lib/sass/tree/visitors/deep_copy.rb +6 -5
  105. data/lib/sass/tree/visitors/extend.rb +7 -7
  106. data/lib/sass/tree/visitors/perform.rb +256 -151
  107. data/lib/sass/tree/visitors/set_options.rb +6 -6
  108. data/lib/sass/tree/visitors/to_css.rb +231 -81
  109. data/lib/sass/tree/warn_node.rb +2 -2
  110. data/lib/sass/tree/while_node.rb +2 -2
  111. data/lib/sass/util/multibyte_string_scanner.rb +2 -0
  112. data/lib/sass/util/normalized_map.rb +65 -0
  113. data/lib/sass/util/ordered_hash.rb +188 -0
  114. data/lib/sass/util/subset_map.rb +3 -2
  115. data/lib/sass/util/test.rb +9 -0
  116. data/lib/sass/util.rb +220 -34
  117. data/lib/sass/version.rb +9 -9
  118. data/lib/sass.rb +14 -7
  119. data/test/sass/compiler_test.rb +213 -0
  120. data/test/sass/conversion_test.rb +235 -9
  121. data/test/sass/engine_test.rb +230 -60
  122. data/test/sass/exec_test.rb +86 -0
  123. data/test/sass/extend_test.rb +215 -147
  124. data/test/sass/functions_test.rb +584 -99
  125. data/test/sass/importer_test.rb +165 -17
  126. data/test/sass/plugin_test.rb +19 -13
  127. data/test/sass/script_conversion_test.rb +40 -0
  128. data/test/sass/script_test.rb +231 -21
  129. data/test/sass/scss/css_test.rb +14 -5
  130. data/test/sass/scss/scss_test.rb +1266 -66
  131. data/test/sass/source_map_test.rb +879 -0
  132. data/test/sass/templates/bork5.sass +3 -0
  133. data/test/sass/util/normalized_map_test.rb +30 -0
  134. data/test/sass/util_test.rb +90 -0
  135. data/test/sass/value_helpers_test.rb +181 -0
  136. data/test/test_helper.rb +7 -2
  137. metadata +316 -291
  138. data/lib/sass/script/bool.rb +0 -18
  139. data/lib/sass/script/funcall.rb +0 -231
  140. data/lib/sass/script/list.rb +0 -84
  141. data/lib/sass/script/literal.rb +0 -239
  142. data/lib/sass/script/null.rb +0 -34
  143. data/lib/sass/script/variable.rb +0 -58
  144. data/test/Gemfile +0 -3
  145. data/vendor/listen/CHANGELOG.md +0 -221
  146. data/vendor/listen/CONTRIBUTING.md +0 -38
  147. data/vendor/listen/Gemfile +0 -30
  148. data/vendor/listen/Guardfile +0 -8
  149. data/vendor/listen/LICENSE +0 -20
  150. data/vendor/listen/README.md +0 -315
  151. data/vendor/listen/Rakefile +0 -47
  152. data/vendor/listen/Vagrantfile +0 -96
  153. data/vendor/listen/lib/listen/adapter.rb +0 -214
  154. data/vendor/listen/lib/listen/adapters/bsd.rb +0 -112
  155. data/vendor/listen/lib/listen/adapters/darwin.rb +0 -85
  156. data/vendor/listen/lib/listen/adapters/linux.rb +0 -113
  157. data/vendor/listen/lib/listen/adapters/polling.rb +0 -67
  158. data/vendor/listen/lib/listen/adapters/windows.rb +0 -87
  159. data/vendor/listen/lib/listen/dependency_manager.rb +0 -126
  160. data/vendor/listen/lib/listen/directory_record.rb +0 -371
  161. data/vendor/listen/lib/listen/listener.rb +0 -225
  162. data/vendor/listen/lib/listen/multi_listener.rb +0 -143
  163. data/vendor/listen/lib/listen/turnstile.rb +0 -28
  164. data/vendor/listen/lib/listen/version.rb +0 -3
  165. data/vendor/listen/lib/listen.rb +0 -40
  166. data/vendor/listen/listen.gemspec +0 -22
  167. data/vendor/listen/spec/listen/adapter_spec.rb +0 -183
  168. data/vendor/listen/spec/listen/adapters/bsd_spec.rb +0 -36
  169. data/vendor/listen/spec/listen/adapters/darwin_spec.rb +0 -37
  170. data/vendor/listen/spec/listen/adapters/linux_spec.rb +0 -47
  171. data/vendor/listen/spec/listen/adapters/polling_spec.rb +0 -68
  172. data/vendor/listen/spec/listen/adapters/windows_spec.rb +0 -30
  173. data/vendor/listen/spec/listen/dependency_manager_spec.rb +0 -107
  174. data/vendor/listen/spec/listen/directory_record_spec.rb +0 -1225
  175. data/vendor/listen/spec/listen/listener_spec.rb +0 -169
  176. data/vendor/listen/spec/listen/multi_listener_spec.rb +0 -174
  177. data/vendor/listen/spec/listen/turnstile_spec.rb +0 -56
  178. data/vendor/listen/spec/listen_spec.rb +0 -73
  179. data/vendor/listen/spec/spec_helper.rb +0 -21
  180. data/vendor/listen/spec/support/adapter_helper.rb +0 -629
  181. data/vendor/listen/spec/support/directory_record_helper.rb +0 -55
  182. data/vendor/listen/spec/support/fixtures_helper.rb +0 -29
  183. data/vendor/listen/spec/support/listeners_helper.rb +0 -156
  184. data/vendor/listen/spec/support/platform_helper.rb +0 -15
@@ -1,96 +0,0 @@
1
- # -*- mode: ruby -*-
2
- # vi: set ft=ruby :
3
-
4
- Vagrant::Config.run do |config|
5
- # All Vagrant configuration is done here. The most common configuration
6
- # options are documented and commented below. For a complete reference,
7
- # please see the online documentation at vagrantup.com.
8
-
9
- # Every Vagrant virtual environment requires a box to build off of.
10
- config.vm.box = "lucid32"
11
-
12
- # The url from where the 'config.vm.box' box will be fetched if it
13
- # doesn't already exist on the user's system.
14
- # config.vm.box_url = "http://domain.com/path/to/above.box"
15
-
16
- # Boot with a GUI so you can see the screen. (Default is headless)
17
- # config.vm.boot_mode = :gui
18
-
19
- # Assign this VM to a host-only network IP, allowing you to access it
20
- # via the IP. Host-only networks can talk to the host machine as well as
21
- # any other machines on the same network, but cannot be accessed (through this
22
- # network interface) by any external networks.
23
- # config.vm.network :hostonly, "33.33.33.10"
24
-
25
- # Assign this VM to a bridged network, allowing you to connect directly to a
26
- # network using the host's network device. This makes the VM appear as another
27
- # physical device on your network.
28
- # config.vm.network :bridged
29
-
30
- # Forward a port from the guest to the host, which allows for outside
31
- # computers to access the VM, whereas host only networking does not.
32
- # config.vm.forward_port 80, 8080
33
-
34
- # Share an additional folder to the guest VM. The first argument is
35
- # an identifier, the second is the path on the guest to mount the
36
- # folder, and the third is the path on the host to the actual folder.
37
- # config.vm.share_folder "v-data", "/vagrant_data", "../data"
38
-
39
- # Enable provisioning with Puppet stand alone. Puppet manifests
40
- # are contained in a directory path relative to this Vagrantfile.
41
- # You will need to create the manifests directory and a manifest in
42
- # the file lucid32.pp in the manifests_path directory.
43
- #
44
- # An example Puppet manifest to provision the message of the day:
45
- #
46
- # # group { "puppet":
47
- # # ensure => "present",
48
- # # }
49
- # #
50
- # # File { owner => 0, group => 0, mode => 0644 }
51
- # #
52
- # # file { '/etc/motd':
53
- # # content => "Welcome to your Vagrant-built virtual machine!
54
- # # Managed by Puppet.\n"
55
- # # }
56
- #
57
- # config.vm.provision :puppet do |puppet|
58
- # puppet.manifests_path = "manifests"
59
- # puppet.manifest_file = "lucid32.pp"
60
- # end
61
-
62
- # Enable provisioning with chef solo, specifying a cookbooks path (relative
63
- # to this Vagrantfile), and adding some recipes and/or roles.
64
- #
65
- # config.vm.provision :chef_solo do |chef|
66
- # chef.cookbooks_path = "cookbooks"
67
- # chef.add_recipe "mysql"
68
- # chef.add_role "web"
69
- #
70
- # # You may also specify custom JSON attributes:
71
- # chef.json = { :mysql_password => "foo" }
72
- # end
73
-
74
- # Enable provisioning with chef server, specifying the chef server URL,
75
- # and the path to the validation key (relative to this Vagrantfile).
76
- #
77
- # The Opscode Platform uses HTTPS. Substitute your organization for
78
- # ORGNAME in the URL and validation key.
79
- #
80
- # If you have your own Chef Server, use the appropriate URL, which may be
81
- # HTTP instead of HTTPS depending on your configuration. Also change the
82
- # validation key to validation.pem.
83
- #
84
- # config.vm.provision :chef_client do |chef|
85
- # chef.chef_server_url = "https://api.opscode.com/organizations/ORGNAME"
86
- # chef.validation_key_path = "ORGNAME-validator.pem"
87
- # end
88
- #
89
- # If you're using the Opscode platform, your validator client is
90
- # ORGNAME-validator, replacing ORGNAME with your organization name.
91
- #
92
- # IF you have your own Chef Server, the default validation client name is
93
- # chef-validator, unless you changed the configuration.
94
- #
95
- # chef.validation_client_name = "ORGNAME-validator"
96
- end
@@ -1,214 +0,0 @@
1
- require 'rbconfig'
2
- require 'thread'
3
- require 'set'
4
- require 'fileutils'
5
-
6
- module Listen
7
- class Adapter
8
- attr_accessor :directories, :latency, :paused
9
-
10
- # The default delay between checking for changes.
11
- DEFAULT_LATENCY = 0.25
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
-
18
- # The default warning message when falling back to polling adapter.
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
22
-
23
- # Selects the appropriate adapter implementation for the
24
- # current OS and initializes it.
25
- #
26
- # @param [String, Array<String>] directories the directories to watch
27
- # @param [Hash] options the adapter options
28
- # @option options [Boolean] force_polling to force polling or not
29
- # @option options [String, Boolean] polling_fallback_message to change polling fallback message or remove it
30
- # @option options [Float] latency the delay between checking for changes in seconds
31
- #
32
- # @yield [changed_dirs, options] callback Callback called when a change happens
33
- # @yieldparam [Array<String>] changed_dirs the changed directories
34
- # @yieldparam [Hash] options callback options (like :recursive => true)
35
- #
36
- # @return [Listen::Adapter] the chosen adapter
37
- #
38
- def self.select_and_initialize(directories, options = {}, &callback)
39
- return Adapters::Polling.new(directories, options, &callback) if options.delete(:force_polling)
40
-
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)
52
- end
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')
60
- end
61
-
62
- Adapters::Polling.new(directories, options, &callback)
63
- end
64
-
65
- # Initializes the adapter.
66
- #
67
- # @param [String, Array<String>] directories the directories to watch
68
- # @param [Hash] options the adapter options
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)
71
- #
72
- # @yield [changed_dirs, options] callback Callback called when a change happens
73
- # @yieldparam [Array<String>] changed_dirs the changed directories
74
- # @yieldparam [Hash] options callback options (like :recursive => true)
75
- #
76
- # @return [Listen::Adapter] the adapter
77
- #
78
- def initialize(directories, options = {}, &callback)
79
- @directories = Array(directories)
80
- @callback = callback
81
- @paused = false
82
- @mutex = Mutex.new
83
- @changed_dirs = Set.new
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]
88
- end
89
-
90
- # Starts the adapter.
91
- #
92
- # @param [Boolean] blocking whether or not to block the current thread after starting
93
- #
94
- def start(blocking = true)
95
- @stop = false
96
- end
97
-
98
- # Stops the adapter.
99
- #
100
- def stop
101
- @stop = true
102
- @turnstile.signal # ensure no thread is blocked
103
- end
104
-
105
- # Returns whether the adapter is statred or not
106
- #
107
- # @return [Boolean] whether the adapter is started or not
108
- #
109
- def started?
110
- @stop.nil? ? false : !@stop
111
- end
112
-
113
- # Blocks the main thread until the poll thread
114
- # runs the callback.
115
- #
116
- def wait_for_callback
117
- @turnstile.wait unless @paused
118
- end
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
-
145
- # Checks if the adapter is usable and works on the current OS.
146
- #
147
- # @param [String, Array<String>] directories the directories to watch
148
- # @param [Hash] options the adapter options
149
- # @option options [Float] latency the delay between checking for changes in seconds
150
- #
151
- # @return [Boolean] whether usable and work or not
152
- #
153
- def self.usable_and_works?(directories, options = {})
154
- usable? && Array(directories).all? { |d| works?(d, options) }
155
- end
156
-
157
- # Runs a tests to determine if the adapter can actually pick up
158
- # changes in a given directory and returns the result.
159
- #
160
- # @note This test takes some time depending the adapter latency.
161
- #
162
- # @param [String, Pathname] directory the directory to watch
163
- # @param [Hash] options the adapter options
164
- # @option options [Float] latency the delay between checking for changes in seconds
165
- #
166
- # @return [Boolean] whether the adapter works or not
167
- #
168
- def self.works?(directory, options = {})
169
- work = false
170
- test_file = "#{directory}/.listen_test"
171
- callback = lambda { |*| work = true }
172
- adapter = self.new(directory, options, &callback)
173
- adapter.start(false)
174
-
175
- FileUtils.touch(test_file)
176
-
177
- t = Thread.new { sleep(adapter.latency * 5); adapter.stop }
178
-
179
- adapter.wait_for_callback
180
- work
181
- ensure
182
- Thread.kill(t) if t
183
- FileUtils.rm(test_file) if File.exists?(test_file)
184
- adapter.stop if adapter && adapter.started?
185
- end
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
-
202
- private
203
-
204
- # Polls changed directories and reports them back
205
- # when there are changes.
206
- #
207
- def poll_changed_dirs
208
- until @stop
209
- sleep(@latency)
210
- report_changes
211
- end
212
- end
213
- end
214
- end
@@ -1,112 +0,0 @@
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
@@ -1,85 +0,0 @@
1
- module Listen
2
- module Adapters
3
-
4
- # Adapter implementation for Mac OS X `FSEvents`.
5
- #
6
- class Darwin < Adapter
7
- extend DependencyManager
8
-
9
- # Declare the adapter's dependencies
10
- dependency 'rb-fsevent', '~> 0.9.1'
11
-
12
- LAST_SEPARATOR_REGEX = /\/$/
13
-
14
- # Initializes the Adapter. See {Listen::Adapter#initialize} for more info.
15
- #
16
- def initialize(directories, options = {}, &callback)
17
- super
18
- @worker = init_worker
19
- end
20
-
21
- # Starts the adapter.
22
- #
23
- # @param [Boolean] blocking whether or not to block the current thread after starting
24
- #
25
- def start(blocking = true)
26
- @mutex.synchronize do
27
- return if @stop == false
28
- super
29
- end
30
-
31
- @worker_thread = Thread.new { @worker.run }
32
-
33
- # The FSEvent worker needs sometime to startup. Turnstiles can't
34
- # be used to wait for it as it runs in a loop.
35
- # TODO: Find a better way to block until the worker starts.
36
- sleep 0.1
37
-
38
- @poll_thread = Thread.new { poll_changed_dirs } if @report_changes
39
- @worker_thread.join if blocking
40
- end
41
-
42
- # Stops the adapter.
43
- #
44
- def stop
45
- @mutex.synchronize do
46
- return if @stop == true
47
- super
48
- end
49
-
50
- @worker.stop
51
- @worker_thread.join if @worker_thread
52
- @poll_thread.join if @poll_thread
53
- end
54
-
55
- # Checks if the adapter is usable on the current OS.
56
- #
57
- # @return [Boolean] whether usable or not
58
- #
59
- def self.usable?
60
- return false unless RbConfig::CONFIG['target_os'] =~ /darwin(1.+)?$/i
61
- super
62
- end
63
-
64
- private
65
-
66
- # Initializes a FSEvent worker and adds a watcher for
67
- # each directory passed to the adapter.
68
- #
69
- # @return [FSEvent] initialized worker
70
- #
71
- def init_worker
72
- FSEvent.new.tap do |worker|
73
- worker.watch(@directories.dup, :latency => @latency) do |changes|
74
- next if @paused
75
- @mutex.synchronize do
76
- changes.each { |path| @changed_dirs << path.sub(LAST_SEPARATOR_REGEX, '') }
77
- end
78
- end
79
- end
80
- end
81
-
82
- end
83
-
84
- end
85
- end
@@ -1,113 +0,0 @@
1
- module Listen
2
- module Adapters
3
-
4
- # Listener implementation for Linux `inotify`.
5
- #
6
- class Linux < Adapter
7
- extend DependencyManager
8
-
9
- # Declare the adapter's dependencies
10
- dependency 'rb-inotify', '~> 0.8.8'
11
-
12
- # Watched inotify events
13
- #
14
- # @see http://www.tin.org/bin/man.cgi?section=7&topic=inotify
15
- # @see https://github.com/nex3/rb-inotify/blob/master/lib/rb-inotify/notifier.rb#L99-L177
16
- #
17
- EVENTS = %w[recursive attrib create delete move close_write]
18
-
19
- # The message to show when the limit of inotify watchers is not enough
20
- #
21
- INOTIFY_LIMIT_MESSAGE = <<-EOS.gsub(/^\s*/, '')
22
- Listen error: unable to monitor directories for changes.
23
-
24
- Please head to https://github.com/guard/listen/wiki/Increasing-the-amount-of-inotify-watchers
25
- for information on how to solve this issue.
26
- EOS
27
-
28
- # Initializes the Adapter. See {Listen::Adapter#initialize} for more info.
29
- #
30
- def initialize(directories, options = {}, &callback)
31
- super
32
- @worker = init_worker
33
- rescue Errno::ENOSPC
34
- abort(INOTIFY_LIMIT_MESSAGE)
35
- end
36
-
37
- # Starts the adapter.
38
- #
39
- # @param [Boolean] blocking whether or not to block the current thread after starting
40
- #
41
- def start(blocking = true)
42
- @mutex.synchronize do
43
- return if @stop == false
44
- super
45
- end
46
-
47
- @worker_thread = Thread.new { @worker.run }
48
- @poll_thread = Thread.new { poll_changed_dirs } if @report_changes
49
-
50
- @worker_thread.join if blocking
51
- end
52
-
53
- # Stops the adapter.
54
- #
55
- def stop
56
- @mutex.synchronize do
57
- return if @stop == true
58
- super
59
- end
60
-
61
- @worker.stop
62
- Thread.kill(@worker_thread) if @worker_thread
63
- @poll_thread.join if @poll_thread
64
- end
65
-
66
- # Checks if the adapter is usable on the current OS.
67
- #
68
- # @return [Boolean] whether usable or not
69
- #
70
- def self.usable?
71
- return false unless RbConfig::CONFIG['target_os'] =~ /linux/i
72
- super
73
- end
74
-
75
- private
76
-
77
- # Initializes a INotify worker and adds a watcher for
78
- # each directory passed to the adapter.
79
- #
80
- # @return [INotify::Notifier] initialized worker
81
- #
82
- def init_worker
83
- callback = lambda do |event|
84
- if @paused || (
85
- # Event on root directory
86
- event.name == ""
87
- ) || (
88
- # INotify reports changes to files inside directories as events
89
- # on the directories themselves too.
90
- #
91
- # @see http://linux.die.net/man/7/inotify
92
- event.flags.include?(:isdir) and event.flags & [:close, :modify] != []
93
- )
94
- # Skip all of these!
95
- next
96
- end
97
-
98
- @mutex.synchronize do
99
- @changed_dirs << File.dirname(event.absolute_name)
100
- end
101
- end
102
-
103
- INotify::Notifier.new.tap do |worker|
104
- @directories.each do |directory|
105
- worker.watch(directory, *EVENTS.map(&:to_sym), &callback)
106
- end
107
- end
108
- end
109
-
110
- end
111
-
112
- end
113
- end
@@ -1,67 +0,0 @@
1
- module Listen
2
- module Adapters
3
-
4
- # The default delay between checking for changes.
5
- DEFAULT_POLLING_LATENCY = 1.0
6
-
7
- # Polling Adapter that works cross-platform and
8
- # has no dependencies. This is the adapter that
9
- # uses the most CPU processing power and has higher
10
- # file IO that the other implementations.
11
- #
12
- class Polling < Adapter
13
- extend DependencyManager
14
-
15
- # Initialize the Adapter. See {Listen::Adapter#initialize} for more info.
16
- #
17
- def initialize(directories, options = {}, &callback)
18
- @latency ||= DEFAULT_POLLING_LATENCY
19
- super
20
- end
21
-
22
- # Start the adapter.
23
- #
24
- # @param [Boolean] blocking whether or not to block the current thread after starting
25
- #
26
- def start(blocking = true)
27
- @mutex.synchronize do
28
- return if @stop == false
29
- super
30
- end
31
-
32
- @poll_thread = Thread.new { poll }
33
- @poll_thread.join if blocking
34
- end
35
-
36
- # Stop the adapter.
37
- #
38
- def stop
39
- @mutex.synchronize do
40
- return if @stop == true
41
- super
42
- end
43
-
44
- @poll_thread.join
45
- end
46
-
47
- private
48
-
49
- # Poll listener directory for file system changes.
50
- #
51
- def poll
52
- until @stop
53
- next if @paused
54
-
55
- start = Time.now.to_f
56
- @callback.call(@directories.dup, :recursive => true)
57
- @turnstile.signal
58
- nap_time = @latency - (Time.now.to_f - start)
59
- sleep(nap_time) if nap_time > 0
60
- end
61
- rescue Interrupt
62
- end
63
-
64
- end
65
-
66
- end
67
- end