Class: Sass::Plugin::Compiler
- Inherits:
- Object
- Object
- Sass::Plugin::Compiler
- Extended by:
- Callbacks
- Includes:
- Configuration
- Defined in:
- /Users/ceppstei/Projects/sass-lang/.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 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.
- - ({Symbol => Object}) engine_options(additional_options = {})
Non-destructively modifies Sass::Plugin::Configuration#options so that default values are properly set, and returns the result.
- - (Array<(String, String, String)>) file_list(individual_files = [])
Construct a list of files that might need to be compiled from the provided individual_files and the template_locations.
- - (Compiler) initialize(opts = {}) constructor
Creates a new compiler.
- - (Boolean) stylesheet_needs_update?(css_file, template_file)
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
- (Compiler) initialize(opts = {})
Creates a new compiler.
35 36 37 38 | # File '/Users/ceppstei/Projects/sass-lang/.sass/lib/sass/plugin/compiler.rb', line 35
def initialize(opts = {})
@watched_files = Set.new
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.
374 375 376 377 378 379 380 381 382 383 384 385 386 | # File '/Users/ceppstei/Projects/sass-lang/.sass/lib/sass/plugin/compiler.rb', line 374
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 |
- ({Symbol => Object}) engine_options(additional_options = {})
Non-destructively modifies Sass::Plugin::Configuration#options so that default values are properly set, and returns the result.
349 350 351 352 353 354 355 | # File '/Users/ceppstei/Projects/sass-lang/.sass/lib/sass/plugin/compiler.rb', line 349
def engine_options(additional_options = {})
opts = options.merge(additional_options)
opts[:load_paths] = load_paths(opts)
options[:sourcemap] = :auto if options[:sourcemap] == true
options[:sourcemap] = :none if options[:sourcemap] == false
opts
end |
- (Array<(String, String, String)>) file_list(individual_files = [])
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.
240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 | # File '/Users/ceppstei/Projects/sass-lang/.sass/lib/sass/plugin/compiler.rb', line 240
def file_list(individual_files = [])
files = individual_files.map do |tuple|
if engine_options[:sourcemap] == :none
tuple[0..1]
elsif tuple.size < 3
[tuple[0], tuple[1], Sass::Util.sourcemap_name(tuple[1])]
else
tuple.dup
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 = Sass::Util.relative_path_from(file, template_location).to_s
css = css_filename(name, css_location)
sourcemap = Sass::Util.sourcemap_name(css) unless engine_options[:sourcemap] == :none
files << [file, css, sourcemap]
end
end
files
end |
- (Boolean) stylesheet_needs_update?(css_file, template_file)
Compass expects this to exist
358 359 360 | # File '/Users/ceppstei/Projects/sass-lang/.sass/lib/sass/plugin/compiler.rb', line 358
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.
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 | # File '/Users/ceppstei/Projects/sass-lang/.sass/lib/sass/plugin/compiler.rb', line 201
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.
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 335 336 337 338 339 340 341 342 | # File '/Users/ceppstei/Projects/sass-lang/.sass/lib/sass/plugin/compiler.rb', line 291
def watch(individual_files = [], options = {})
@inferred_directories = []
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, _, _)|
source = File.expand_path(source)
@watched_files << Sass::Util.realpath(source).to_s
@inferred_directories << File.dirname(source)
end
directories += @inferred_directories
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 |