Class: Sass::Plugin::Compiler
- Inherits:
-
Object
- Object
- Sass::Plugin::Compiler
- Extended by:
- Callbacks
- Includes:
- Configuration
- Defined in:
- 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 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
Instance Method Summary collapse
-
#clean(individual_files = [])
Remove all output files that would be created by calling update_stylesheets, if they exist.
-
#engine_options(additional_options = {}) ⇒ {Symbol => Object}
Non-destructively modifies Sass::Plugin::Configuration#options so that default values are properly set, and returns the result.
-
#file_list(individual_files = []) ⇒ Array<(String, String, String)>
Construct a list of files that might need to be compiled from the provided individual_files and the template_locations.
-
#initialize(opts = {}) ⇒ Compiler
constructor
Creates a new compiler.
-
#stylesheet_needs_update?(css_file, template_file) ⇒ Boolean
Compass expects this to exist.
-
#update_stylesheets(individual_files = [])
Updates out-of-date stylesheets.
-
#watch(individual_files = [], options = {})
Watches the template directory (or directories) and updates the CSS files whenever the related Sass/SCSS files change.
Methods included from Callbacks
Methods included from Configuration
#add_template_location, #default_options, #options, #remove_template_location, #reset!, #template_location_array
Constructor Details
#initialize(opts = {}) ⇒ Compiler
Creates a new compiler.
35 36 37 |
# File 'lib/sass/plugin/compiler.rb', line 35
def initialize(opts = {})
options.merge!(opts)
end
|
Instance Method Details
#clean(individual_files = [])
Remove all output files that would be created by calling update_stylesheets, if they exist.
This method runs the deleting_css and deleting_sourcemap callbacks for the files that are deleted.
364 365 366 367 368 369 370 371 372 373 374 375 376 |
# File 'lib/sass/plugin/compiler.rb', line 364
def clean(individual_files = [])
file_list(individual_files).each do |(_, css_file, sourcemap_file)|
if File.exist?(css_file)
run_deleting_css css_file
File.delete(css_file)
end
if sourcemap_file && File.exist?(sourcemap_file)
run_deleting_sourcemap sourcemap_file
File.delete(sourcemap_file)
end
end
nil
end
|
#engine_options(additional_options = {}) ⇒ {Symbol => Object}
Non-destructively modifies Sass::Plugin::Configuration#options so that default values are properly set, and returns the result.
341 342 343 344 345 |
# File 'lib/sass/plugin/compiler.rb', line 341
def engine_options(additional_options = {})
opts = options.merge(additional_options)
opts[:load_paths] = load_paths(opts)
opts
end
|
#file_list(individual_files = []) ⇒ Array<(String, String, String)>
Construct a list of files that might need to be compiled from the provided individual_files and the template_locations.
Note: this method does not cache the results as they can change across invocations when sass files are added or removed.
239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 |
# File 'lib/sass/plugin/compiler.rb', line 239
def file_list(individual_files = [])
files = individual_files.map do |tuple|
if tuple.size < 3
[tuple[0], tuple[1], Sass::Util.sourcemap_name(tuple[1])]
else
tuple
end
end
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)
sourcemap = Sass::Util.sourcemap_name(css) if engine_options[:sourcemap]
files << [file, css, sourcemap]
end
end
files
end
|
#stylesheet_needs_update?(css_file, template_file) ⇒ Boolean
Compass expects this to exist
348 349 350 |
# File 'lib/sass/plugin/compiler.rb', line 348
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.
200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 |
# File 'lib/sass/plugin/compiler.rb', line 200
def update_stylesheets(individual_files = [])
Sass::Plugin.checked_for_updates = true
staleness_checker = StalenessChecker.new(engine_options)
files = file_list(individual_files)
run_updating_stylesheets(files)
updated_stylesheets = []
files.each do |file, css, sourcemap|
# TODO: Does staleness_checker need to check the sourcemap file as well?
if options[:always_update] || staleness_checker.stylesheet_needs_update?(css, file)
# XXX For consistency, this should return the sourcemap too, but it would
# XXX be an API change.
updated_stylesheets << [file, css]
update_stylesheet(file, css, sourcemap)
else
run_not_updating_stylesheet(file, css, sourcemap)
end
end
run_updated_stylesheets(updated_stylesheets)
end
|
#watch(individual_files = [], options = {})
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.
288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 |
# File 'lib/sass/plugin/compiler.rb', line 288
def watch(individual_files = [], options = {})
options, individual_files = individual_files, [] if individual_files.is_a?(Hash)
update_stylesheets(individual_files) unless options[:skip_initial_update]
directories = watched_paths
individual_files.each do |(source, _, _)|
directories << File.dirname(File.expand_path(source))
end
directories = remove_redundant_directories(directories)
# A Listen version prior to 2.0 will write a test file to a directory to
# see if a watcher supports watching that directory. That breaks horribly
# on read-only directories, so we filter those out.
unless Sass::Util.listen_geq_2?
directories = directories.select {|d| File.directory?(d) && File.writable?(d)}
end
# TODO: Keep better track of what depends on what
# so we don't have to run a global update every time anything changes.
# XXX The :additional_watch_paths option exists for Compass to use until
# a deprecated feature is removed. It may be removed without warning.
listener_args = directories +
Array(options[:additional_watch_paths]) +
[{:relative_paths => false}]
# The native windows listener is much slower than the polling option, according to
# https://github.com/nex3/sass/commit/a3031856b22bc834a5417dedecb038b7be9b9e3e
poll = @options[:poll] || Sass::Util.windows?
if poll && Sass::Util.listen_geq_2?
# In Listen 2.0.0 and on, :force_polling is an option. In earlier
# versions, it's a method on the listener (called below).
listener_args.last[:force_polling] = true
end
listener = create_listener(*listener_args) do |modified, added, removed|
on_file_changed(individual_files, modified, added, removed)
yield(modified, added, removed) if block_given?
end
if poll && !Sass::Util.listen_geq_2?
# In Listen 2.0.0 and on, :force_polling is an option (set above). In
# earlier versions, it's a method on the listener.
listener.force_polling(true)
end
listen_to(listener)
end
|