sass 3.2.0.alpha.101 → 3.2.0.alpha.102

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 (45) hide show
  1. data/REVISION +1 -1
  2. data/Rakefile +2 -2
  3. data/VERSION +1 -1
  4. data/lib/sass/plugin/compiler.rb +25 -32
  5. data/lib/sass/plugin/listener.rb +59 -0
  6. data/lib/sass/script/lexer.rb +1 -1
  7. data/lib/sass/script/list.rb +1 -0
  8. data/test/sass/conversion_test.rb +10 -0
  9. data/test/sass/scss/css_test.rb +9 -0
  10. data/vendor/listen/CHANGELOG.md +72 -0
  11. data/vendor/listen/Gemfile +35 -0
  12. data/vendor/listen/Guardfile +8 -0
  13. data/vendor/listen/LICENSE +20 -0
  14. data/vendor/listen/README.md +297 -0
  15. data/vendor/listen/Rakefile +47 -0
  16. data/vendor/listen/Vagrantfile +96 -0
  17. data/vendor/listen/lib/listen.rb +38 -0
  18. data/vendor/listen/lib/listen/adapter.rb +159 -0
  19. data/vendor/listen/lib/listen/adapters/darwin.rb +84 -0
  20. data/vendor/listen/lib/listen/adapters/linux.rb +99 -0
  21. data/vendor/listen/lib/listen/adapters/polling.rb +66 -0
  22. data/vendor/listen/lib/listen/adapters/windows.rb +82 -0
  23. data/vendor/listen/lib/listen/directory_record.rb +257 -0
  24. data/vendor/listen/lib/listen/listener.rb +186 -0
  25. data/vendor/listen/lib/listen/multi_listener.rb +121 -0
  26. data/vendor/listen/lib/listen/turnstile.rb +28 -0
  27. data/vendor/listen/lib/listen/version.rb +3 -0
  28. data/vendor/listen/listen.gemspec +26 -0
  29. data/vendor/listen/spec/listen/adapter_spec.rb +142 -0
  30. data/vendor/listen/spec/listen/adapters/darwin_spec.rb +31 -0
  31. data/vendor/listen/spec/listen/adapters/linux_spec.rb +30 -0
  32. data/vendor/listen/spec/listen/adapters/polling_spec.rb +68 -0
  33. data/vendor/listen/spec/listen/adapters/windows_spec.rb +24 -0
  34. data/vendor/listen/spec/listen/directory_record_spec.rb +807 -0
  35. data/vendor/listen/spec/listen/listener_spec.rb +151 -0
  36. data/vendor/listen/spec/listen/multi_listener_spec.rb +151 -0
  37. data/vendor/listen/spec/listen/turnstile_spec.rb +56 -0
  38. data/vendor/listen/spec/listen_spec.rb +73 -0
  39. data/vendor/listen/spec/spec_helper.rb +16 -0
  40. data/vendor/listen/spec/support/adapter_helper.rb +538 -0
  41. data/vendor/listen/spec/support/directory_record_helper.rb +35 -0
  42. data/vendor/listen/spec/support/fixtures_helper.rb +29 -0
  43. data/vendor/listen/spec/support/listeners_helper.rb +133 -0
  44. data/vendor/listen/spec/support/platform_helper.rb +11 -0
  45. metadata +41 -5
@@ -0,0 +1,47 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+ task :default => :spec
6
+
7
+ require 'rbconfig'
8
+ namespace(:spec) do
9
+ if RbConfig::CONFIG['host_os'] =~ /mswin|mingw/i
10
+ desc "Run all specs on multiple ruby versions (requires pik)"
11
+ task(:portability) do
12
+ %w[187 192 161].each do |version|
13
+ system "cmd /c echo -----------#{version}------------ & " +
14
+ "pik use #{version} & " +
15
+ "bundle install & " +
16
+ "bundle exec rspec spec"
17
+ end
18
+ end
19
+ else
20
+ desc "Run all specs on multiple ruby versions (requires rvm)"
21
+ task(:portability) do
22
+ travis_config_file = File.expand_path("../.travis.yml", __FILE__)
23
+ begin
24
+ travis_options ||= YAML::load_file(travis_config_file)
25
+ rescue => ex
26
+ puts "Travis config file '#{travis_config_file}' could not be found: #{ex.message}"
27
+ return
28
+ end
29
+
30
+ travis_options['rvm'].each do |version|
31
+ system <<-BASH
32
+ bash -c 'source ~/.rvm/scripts/rvm;
33
+ rvm #{version};
34
+ ruby_version_string_size=`ruby -v | wc -m`
35
+ echo;
36
+ for ((c=1; c<$ruby_version_string_size; c++)); do echo -n "="; done
37
+ echo;
38
+ echo "`ruby -v`";
39
+ for ((c=1; c<$ruby_version_string_size; c++)); do echo -n "="; done
40
+ echo;
41
+ RBXOPT="-Xrbc.db" bundle install;
42
+ RBXOPT="-Xrbc.db" bundle exec rspec spec -f doc 2>&1;'
43
+ BASH
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,96 @@
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
@@ -0,0 +1,38 @@
1
+ module Listen
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'
8
+
9
+ module Adapters
10
+ autoload :Darwin, 'listen/adapters/darwin'
11
+ autoload :Linux, 'listen/adapters/linux'
12
+ autoload :Windows, 'listen/adapters/windows'
13
+ autoload :Polling, 'listen/adapters/polling'
14
+ end
15
+
16
+ # Listens to filesystem modifications on a either single directory or multiple directories.
17
+ #
18
+ # @param (see Listen::Listener#new)
19
+ # @param (see Listen::MultiListener#new)
20
+ #
21
+ # @yield [modified, added, removed] the changed files
22
+ # @yieldparam [Array<String>] modified the list of modified files
23
+ # @yieldparam [Array<String>] added the list of added files
24
+ # @yieldparam [Array<String>] removed the list of removed files
25
+ #
26
+ # @return [Listen::Listener] the file listener if no block given
27
+ #
28
+ def self.to(*args, &block)
29
+ listener = if args.length == 1 || ! args[1].is_a?(String)
30
+ Listener.new(*args, &block)
31
+ else
32
+ MultiListener.new(*args, &block)
33
+ end
34
+
35
+ block ? listener.start : listener
36
+ end
37
+
38
+ end
@@ -0,0 +1,159 @@
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.1
12
+
13
+ # 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."
15
+
16
+ # Selects the appropriate adapter implementation for the
17
+ # current OS and initializes it.
18
+ #
19
+ # @param [String, Array<String>] directories the directories to watch
20
+ # @param [Hash] options the adapter options
21
+ # @option options [Boolean] force_polling to force polling or not
22
+ # @option options [String, Boolean] polling_fallback_message to change polling fallback message or remove it
23
+ # @option options [Float] latency the delay between checking for changes in seconds
24
+ #
25
+ # @yield [changed_dirs, options] callback Callback called when a change happens
26
+ # @yieldparam [Array<String>] changed_dirs the changed directories
27
+ # @yieldparam [Hash] options callback options (like :recursive => true)
28
+ #
29
+ # @return [Listen::Adapter] the chosen adapter
30
+ #
31
+ def self.select_and_initialize(directories, options = {}, &callback)
32
+ return Adapters::Polling.new(directories, options, &callback) if options.delete(:force_polling)
33
+
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)
43
+ end
44
+ Adapters::Polling.new(directories, options, &callback)
45
+ end
46
+ end
47
+
48
+ # Initializes the adapter.
49
+ #
50
+ # @param [String, Array<String>] directories the directories to watch
51
+ # @param [Hash] options the adapter options
52
+ # @option options [Float] latency the delay between checking for changes in seconds
53
+ #
54
+ # @yield [changed_dirs, options] callback Callback called when a change happens
55
+ # @yieldparam [Array<String>] changed_dirs the changed directories
56
+ # @yieldparam [Hash] options callback options (like :recursive => true)
57
+ #
58
+ # @return [Listen::Adapter] the adapter
59
+ #
60
+ def initialize(directories, options = {}, &callback)
61
+ @directories = Array(directories)
62
+ @callback = callback
63
+ @latency ||= DEFAULT_LATENCY
64
+ @latency = options[:latency] if options[:latency]
65
+ @paused = false
66
+ @mutex = Mutex.new
67
+ @changed_dirs = Set.new
68
+ @turnstile = Turnstile.new
69
+ end
70
+
71
+ # Starts the adapter.
72
+ #
73
+ # @param [Boolean] blocking whether or not to block the current thread after starting
74
+ #
75
+ def start(blocking = true)
76
+ @stop = false
77
+ end
78
+
79
+ # Stops the adapter.
80
+ #
81
+ def stop
82
+ @stop = true
83
+ @turnstile.signal # ensure no thread is blocked
84
+ end
85
+
86
+ # Blocks the main thread until the poll thread
87
+ # calls the callback.
88
+ #
89
+ def wait_for_callback
90
+ @turnstile.wait unless @paused
91
+ end
92
+
93
+ # Checks if the adapter is usable and works on the current OS.
94
+ #
95
+ # @param [String, Array<String>] directories the directories to watch
96
+ # @param [Hash] options the adapter options
97
+ # @option options [Float] latency the delay between checking for changes in seconds
98
+ #
99
+ # @return [Boolean] whether usable and work or not
100
+ #
101
+ def self.usable_and_works?(directories, options = {})
102
+ usable? && Array(directories).all? { |d| works?(d, options) }
103
+ end
104
+
105
+ # Runs a tests to determine if the adapter can actually pick up
106
+ # changes in a given directory and returns the result.
107
+ #
108
+ # @note This test takes some time depending the adapter latency.
109
+ #
110
+ # @param [String, Pathname] directory the directory to watch
111
+ # @param [Hash] options the adapter options
112
+ # @option options [Float] latency the delay between checking for changes in seconds
113
+ #
114
+ # @return [Boolean] whether the adapter works or not
115
+ #
116
+ def self.works?(directory, options = {})
117
+ work = false
118
+ test_file = "#{directory}/.listen_test"
119
+ callback = lambda { |changed_dirs, options| work = true }
120
+ adapter = self.new(directory, options, &callback)
121
+ adapter.start(false)
122
+
123
+ FileUtils.touch(test_file)
124
+
125
+ t = Thread.new { sleep(adapter.latency * 5); adapter.stop }
126
+
127
+ adapter.wait_for_callback
128
+ work
129
+ ensure
130
+ Thread.kill(t) if t
131
+ FileUtils.rm(test_file) if File.exists?(test_file)
132
+ adapter.stop
133
+ end
134
+
135
+ private
136
+
137
+ # Polls changed directories and reports them back
138
+ # when there are changes.
139
+ #
140
+ # @option [Boolean] recursive whether or not to pass the recursive option to the callback
141
+ #
142
+ def poll_changed_dirs(recursive = false)
143
+ until @stop
144
+ sleep(@latency)
145
+ next if @changed_dirs.empty?
146
+
147
+ changed_dirs = []
148
+
149
+ @mutex.synchronize do
150
+ changed_dirs = @changed_dirs.to_a
151
+ @changed_dirs.clear
152
+ end
153
+
154
+ @callback.call(changed_dirs, recursive ? {:recursive => recursive} : {})
155
+ @turnstile.signal
156
+ end
157
+ end
158
+ end
159
+ end
@@ -0,0 +1,84 @@
1
+ module Listen
2
+ module Adapters
3
+
4
+ # Adapter implementation for Mac OS X `FSEvents`.
5
+ #
6
+ class Darwin < Adapter
7
+
8
+ LAST_SEPARATOR_REGEX = /\/$/
9
+
10
+ # Initializes the Adapter. See {Listen::Adapter#initialize} for more info.
11
+ #
12
+ def initialize(directories, options = {}, &callback)
13
+ super
14
+ @worker = init_worker
15
+ end
16
+
17
+ # Starts the adapter.
18
+ #
19
+ # @param [Boolean] blocking whether or not to block the current thread after starting
20
+ #
21
+ def start(blocking = true)
22
+ @mutex.synchronize do
23
+ return if @stop == false
24
+ super
25
+ end
26
+
27
+ @worker_thread = Thread.new { @worker.run }
28
+ @poll_thread = Thread.new { poll_changed_dirs }
29
+
30
+ # The FSEvent worker needs sometime to startup. Turnstiles can't
31
+ # be used to wait for it as it runs in a loop.
32
+ # TODO: Find a better way to block until the worker starts.
33
+ sleep @latency
34
+ @poll_thread.join if blocking
35
+ end
36
+
37
+ # Stops the adapter.
38
+ #
39
+ def stop
40
+ @mutex.synchronize do
41
+ return if @stop == true
42
+ super
43
+ end
44
+
45
+ @worker.stop
46
+ Thread.kill(@worker_thread) if @worker_thread
47
+ @poll_thread.join
48
+ end
49
+
50
+ # Checks if the adapter is usable on the current OS.
51
+ #
52
+ # @return [Boolean] whether usable or not
53
+ #
54
+ def self.usable?
55
+ return false unless RbConfig::CONFIG['target_os'] =~ /darwin(1.+)?$/i
56
+
57
+ require 'rb-fsevent'
58
+ true
59
+ rescue LoadError
60
+ false
61
+ end
62
+
63
+ private
64
+
65
+ # Initializes a FSEvent worker and adds a watcher for
66
+ # each directory passed to the adapter.
67
+ #
68
+ # @return [FSEvent] initialized worker
69
+ #
70
+ def init_worker
71
+ FSEvent.new.tap do |worker|
72
+ worker.watch(@directories.dup, :latency => @latency) do |changes|
73
+ next if @paused
74
+ @mutex.synchronize do
75
+ changes.each { |path| @changed_dirs << path.sub(LAST_SEPARATOR_REGEX, '') }
76
+ end
77
+ end
78
+ end
79
+ end
80
+
81
+ end
82
+
83
+ end
84
+ end
@@ -0,0 +1,99 @@
1
+ module Listen
2
+ module Adapters
3
+
4
+ # Watched INotify EVENTS
5
+ #
6
+ # @see http://www.tin.org/bin/man.cgi?section=7&topic=inotify
7
+ # @see https://github.com/nex3/rb-inotify/blob/master/lib/rb-inotify/notifier.rb#L99-L177
8
+ #
9
+ EVENTS = %w[recursive attrib close modify move create delete delete_self move_self]
10
+
11
+ # Listener implementation for Linux `inotify`.
12
+ #
13
+ class Linux < Adapter
14
+
15
+ # Initializes the Adapter. See {Listen::Adapter#initialize} for more info.
16
+ #
17
+ def initialize(directories, options = {}, &callback)
18
+ super
19
+ @worker = init_worker
20
+ end
21
+
22
+ # Starts 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
+ @worker_thread = Thread.new { @worker.run }
33
+ @poll_thread = Thread.new { poll_changed_dirs }
34
+ @poll_thread.join if blocking
35
+ end
36
+
37
+ # Stops the adapter.
38
+ #
39
+ def stop
40
+ @mutex.synchronize do
41
+ return if @stop == true
42
+ super
43
+ end
44
+
45
+ @worker.stop
46
+ Thread.kill(@worker_thread) if @worker_thread
47
+ @poll_thread.join
48
+ end
49
+
50
+ # Check if the adapter is usable on the current OS.
51
+ #
52
+ # @return [Boolean] whether usable or not
53
+ #
54
+ def self.usable?
55
+ return false unless RbConfig::CONFIG['target_os'] =~ /linux/i
56
+
57
+ require 'rb-inotify'
58
+ true
59
+ rescue LoadError
60
+ false
61
+ end
62
+
63
+ private
64
+
65
+ # Initializes a INotify worker and adds a watcher for
66
+ # each directory passed to the adapter.
67
+ #
68
+ # @return [INotify::Notifier] initialized worker
69
+ #
70
+ def init_worker
71
+ worker = INotify::Notifier.new
72
+ @directories.each do |directory|
73
+ worker.watch(directory, *EVENTS.map(&:to_sym)) do |event|
74
+ if @paused || (
75
+ # Event on root directory
76
+ event.name == ""
77
+ ) || (
78
+ # INotify reports changes to files inside directories as events
79
+ # on the directories themselves too.
80
+ #
81
+ # @see http://linux.die.net/man/7/inotify
82
+ event.flags.include?(:isdir) and event.flags & [:close, :modify] != []
83
+ )
84
+ # Skip all of these!
85
+ next
86
+ end
87
+
88
+ @mutex.synchronize do
89
+ @changed_dirs << File.dirname(event.absolute_name)
90
+ end
91
+ end
92
+ end
93
+ worker
94
+ end
95
+
96
+ end
97
+
98
+ end
99
+ end