Class: Sass::Plugin::Compiler

Inherits:
Object
  • Object
show all
Extends:
Sass::Callbacks
Includes:
Configuration, Sass::Util
Defined in:
/var/www/sass-pages/.sass/lib/sass/plugin/compiler.rb

Overview

The Compiler class handles compilation of multiple files and/or directories, including checking which CSS files are out-of-date and need to be updated and calling Sass to perform the compilation on those files.

Sass::Plugin uses this class to update stylesheets for a single application. Unlike Sass::Plugin, though, the Compiler class has no global state, and so multiple instances may be created and used independently.

If you need to compile a Sass string into CSS, please see the Sass::Engine class.

Unlike Sass::Plugin, this class doesn’t keep track of whether or how many times a stylesheet should be updated. Therefore, the following Sass::Plugin options are ignored by the Compiler:

  • :never_update
  • :always_check

Constant Summary

Constants included from Sass::Util

RUBY_ENGINE, RUBY_VERSION

Instance Method Summary

Methods included from Sass::Util

#abstract, #ap_geq?, #ap_geq_3?, #array_minus, #av_template_class, #caller_info, #check_encoding, #check_range, #check_sass_encoding, #destructure, #enum_cons, #enum_slice, #enum_with_index, #extract!, #extract_values, #flatten, #glob, #group_by_to_a, #has?, #hash_to_a, #inject_values, #inspect_obj, #intersperse, #ironruby?, #jruby1_6?, #jruby?, #jruby_version, #lcs, #macruby?, #map_hash, #map_keys, #map_vals, #merge_adjacent_strings, #ord, #paths, #powerset, #rails_env, #rails_root, #rbx?, #restrict, #ruby1?, #ruby1_8?, #ruby1_8_6?, #sass_warn, #scope, #set_eql?, #set_hash, #silence_sass_warnings, #silence_warnings, #strip_string_array, #subsequence?, #substitute, #to_hash, #undefined_conversion_error_char, #version_geq, #version_gt, #windows?, #with_extracted_values

Methods included from Configuration

#add_template_location, #default_options, #options, #options=, #remove_template_location, #reset!, #template_location_array

Constructor Details

- (Compiler) initialize(options = {})

Creates a new compiler.

Parameters:



37
38
39
# File '/var/www/sass-pages/.sass/lib/sass/plugin/compiler.rb', line 37

def initialize(options = {})
  self.options.merge!(options)
end

Instance Method Details

- ({Symbol => Object}) engine_options(additional_options = {})

Non-destructively modifies #options so that default values are properly set, and returns the result.

Parameters:

  • ({Symbol => Object}) additional_options (defaults to: {}) — An options hash with which to merge #options

Returns:

  • ({Symbol => Object}) — The modified options hash


302
303
304
305
306
# File '/var/www/sass-pages/.sass/lib/sass/plugin/compiler.rb', line 302

def engine_options(additional_options = {})
  opts = options.merge(additional_options)
  opts[:load_paths] = load_paths(opts)
  opts
end

- on_compilation_error {|error, template, css| ... }

This method returns an undefined value.

Register a callback to be run when there’s an error compiling a Sass file. This could include not only errors in the Sass document, but also errors accessing the file at all.

Yields:

  • (error, template, css) — When the callback is run

Yield Parameters:

  • (Exception) error — The exception that was raised.
  • (String) template — The location of the Sass/SCSS file being updated.
  • (String) css — The location of the CSS file being generated.


120
# File '/var/www/sass-pages/.sass/lib/sass/plugin/compiler.rb', line 120

define_callback :compilation_error

- on_creating_directory {|dirname| ... }

This method returns an undefined value.

Register a callback to be run when Sass creates a directory into which to put CSS files.

Note that even if multiple levels of directories need to be created, the callback may only be run once. For example, if “foo/” exists and “foo/bar/baz/” needs to be created, this may only be run for “foo/bar/baz/”. This is not a guarantee, however; it may also be run for “foo/bar/”.

Yields:

  • (dirname) — When the callback is run

Yield Parameters:

  • (String) dirname — The location of the directory that was created.


135
# File '/var/www/sass-pages/.sass/lib/sass/plugin/compiler.rb', line 135

define_callback :creating_directory

- on_deleting_css {|filename| ... }

This method returns an undefined value.

Register a callback to be run when Sass deletes a CSS file. This happens when the corresponding Sass/SCSS file has been deleted.

Yields:

  • (filename) — When the callback is run

Yield Parameters:

  • (String) filename — The location of the CSS file that was deleted.


170
# File '/var/www/sass-pages/.sass/lib/sass/plugin/compiler.rb', line 170

define_callback :deleting_css

- on_not_updating_stylesheet {|template, css| ... }

This method returns an undefined value.

Register a callback to be run when Sass decides not to update a stylesheet. In particular, the callback is run when Sass finds that the template file and none of its dependencies have been modified since the last compilation.

Note that this is not run when the :never_update option is set, nor when Sass decides not to compile a partial.

Yields:

  • (template, css) — When the callback is run

Yield Parameters:

  • (String) template — The location of the Sass/SCSS file not being updated.
  • (String) css — The location of the CSS file not being generated.


107
# File '/var/www/sass-pages/.sass/lib/sass/plugin/compiler.rb', line 107

define_callback :not_updating_stylesheet

- on_template_created {|template| ... }

This method returns an undefined value.

Register a callback to be run when Sass detects that a new template has been created. This is only run when using #watch.

Yields:

  • (template) — When the callback is run

Yield Parameters:

  • (String) template — The location of the template that was created.


153
# File '/var/www/sass-pages/.sass/lib/sass/plugin/compiler.rb', line 153

define_callback :template_created

- on_template_deleted {|template| ... }

This method returns an undefined value.

Register a callback to be run when Sass detects that a template has been deleted. This is only run when using #watch.

Yields:

  • (template) — When the callback is run

Yield Parameters:

  • (String) template — The location of the template that was deleted.


162
# File '/var/www/sass-pages/.sass/lib/sass/plugin/compiler.rb', line 162

define_callback :template_deleted

- on_template_modified {|template| ... }

This method returns an undefined value.

Register a callback to be run when Sass detects that a template has been modified. This is only run when using #watch.

Yields:

  • (template) — When the callback is run

Yield Parameters:

  • (String) template — The location of the template that was modified.


144
# File '/var/www/sass-pages/.sass/lib/sass/plugin/compiler.rb', line 144

define_callback :template_modified

- on_updated_stylesheet {|template, css| ... }

This method returns an undefined value.

Register a callback to be run after a single stylesheet is updated. The callback is only run if the stylesheet is really updated; if the CSS file is fresh, this won’t be run.

Even if the :full_exception option is enabled, this callback won’t be run when an exception CSS file is being written. To run an action for those files, use #on_compilation_error.

Yields:

  • (template, css) — When the callback is run

Yield Parameters:

  • (String) template — The location of the Sass/SCSS file being updated.
  • (String) css — The location of the CSS file being generated.


68
# File '/var/www/sass-pages/.sass/lib/sass/plugin/compiler.rb', line 68

define_callback :updated_stylesheet

- on_updating_stylesheet_with_deprecation_warning(&block) Also known as: on_updating_stylesheet



86
87
88
89
# File '/var/www/sass-pages/.sass/lib/sass/plugin/compiler.rb', line 86

def on_updating_stylesheet_with_deprecation_warning(&block)
  Sass::Util.sass_warn("Sass::Compiler#on_updating_stylesheet callback is deprecated and will be removed in a future release. Use Sass::Compiler#on_updated_stylesheet instead, which is run after stylesheet compilation.")
  on_updating_stylesheet_without_deprecation_warning(&block)
end

- on_updating_stylesheets {|individual_files| ... }

This method returns an undefined value.

Register a callback to be run after stylesheets are mass-updated. This is run whenever #update_stylesheets is called, unless the :never_update option is enabled.

Yields:

  • (individual_files) — When the callback is run

Yield Parameters:

  • (<(String, String)>) individual_files — Individual files to be updated, in addition to the directories specified in the options. The first element of each pair is the source file, the second is the target CSS file.


52
# File '/var/www/sass-pages/.sass/lib/sass/plugin/compiler.rb', line 52

define_callback :updating_stylesheets

- (Boolean) stylesheet_needs_update?(css_file, template_file)

Compass expects this to exist

Returns:

  • (Boolean)


309
310
311
# File '/var/www/sass-pages/.sass/lib/sass/plugin/compiler.rb', line 309

def stylesheet_needs_update?(css_file, template_file)
  StalenessChecker.stylesheet_needs_update?(css_file, template_file)
end

- update_stylesheets(individual_files = [])

Updates out-of-date stylesheets.

Checks each Sass/SCSS file in :template_location to see if it’s been modified more recently than the corresponding CSS file in :css_location. If it has, it updates the CSS file.

Parameters:

  • (Array<(String, String)>) individual_files (defaults to: []) — A list of files to check for updates in addition to those specified by the :template_location option. The first string in each pair is the location of the Sass/SCSS file, the second is the location of the CSS file that it should be compiled to.


185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
# File '/var/www/sass-pages/.sass/lib/sass/plugin/compiler.rb', line 185

def update_stylesheets(individual_files = [])
  individual_files = individual_files.dup
  Sass::Plugin.checked_for_updates = true
  staleness_checker = StalenessChecker.new(engine_options)

  template_location_array.each do |template_location, css_location|
    Sass::Util.glob(File.join(template_location, "**", "[^_]*.s[ca]ss")).sort.each do |file|
      # Get the relative path to the file
      name = file.sub(template_location.to_s.sub(/\/*$/, '/'), "")
      css = css_filename(name, css_location)
      individual_files << [file, css]
    end
  end

  run_updating_stylesheets individual_files

  individual_files.each do |file, css|
    if options[:always_update] || staleness_checker.stylesheet_needs_update?(css, file)
      update_stylesheet(file, css)
    else
      run_not_updating_stylesheet(file, css)
    end
  end
end

- watch(individual_files = [])

Watches the template directory (or directories) and updates the CSS files whenever the related Sass/SCSS files change. watch never returns.

Whenever a change is detected to a Sass/SCSS file in :template_location, the corresponding CSS file in :css_location will be recompiled. The CSS files of any Sass/SCSS files that import the changed file will also be recompiled.

Before the watching starts in earnest, watch calls #update_stylesheets.

Note that watch uses the Listen library to monitor the filesystem for changes. Listen isn’t loaded until watch is run. The version of Listen distributed with Sass is loaded by default, but if another version has already been loaded that will be used instead.

Parameters:

  • (Array<(String, String)>) individual_files (defaults to: []) — A list of files to watch for updates in addition to those specified by the :template_location option. The first string in each pair is the location of the Sass/SCSS file, the second is the location of the CSS file that it should be compiled to.


234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
# File '/var/www/sass-pages/.sass/lib/sass/plugin/compiler.rb', line 234

def watch(individual_files = [])
  update_stylesheets(individual_files)

  load_listen!

  template_paths = template_locations # cache the locations
  individual_files_hash = individual_files.inject({}) do |h, files|
    parent = File.dirname(files.first)
    (h[parent] ||= []) << files unless template_paths.include?(parent)
    h
  end
  directories = template_paths + individual_files_hash.keys +
    [{:relative_paths => true}]

  # TODO: Keep better track of what depends on what
  # so we don't have to run a global update every time anything changes.
  listener = Listen::MultiListener.new(*directories) do |modified, added, removed|
    modified.each do |f|
      parent = File.dirname(f)
      if files = individual_files_hash[parent]
        next unless files.first == f
      else
        next unless f =~ /\.s[ac]ss$/
      end
      run_template_modified(f)
    end

    added.each do |f|
      parent = File.dirname(f)
      if files = individual_files_hash[parent]
        next unless files.first == f
      else
        next unless f =~ /\.s[ac]ss$/
      end
      run_template_created(f)
    end

    removed.each do |f|
      parent = File.dirname(f)
      if files = individual_files_hash[parent]
        next unless files.first == f
        try_delete_css files[1]
      else
        next unless f =~ /\.s[ac]ss$/
        try_delete_css f.gsub(/\.s[ac]ss$/, '.css')
      end
      run_template_deleted(f)
    end

    update_stylesheets(individual_files)
  end

  # The native windows listener is much slower than the polling
  # option, according to https://github.com/nex3/sass/commit/a3031856b22bc834a5417dedecb038b7be9b9e3e#commitcomment-1295118
  listener.force_polling(true) if @options[:poll] || Sass::Util.windows?

  begin
    listener.start
  rescue Exception => e
    raise e unless e.is_a?(Interrupt)
  end
end