class Sass::Plugin::StalenessChecker

as its instance-level caches are never explicitly expired.
WARNING: It is important not to retain the instance for too long,
the caches should make the whole process significantly faster.
and the instance-level {#stylesheet_needs_update?} method should be used.
a StalenessChecker instance should be created,
* For a series of staleness checks (e.g. checking all files for staleness)
should be used.
the class-level {stylesheet_needs_update?} method
* For a one-off staleness check of a single ‘.sss` file,
Usage:
These are only used by a single StalenessChecker instance.
and one for whether a file is stale during this particular run.
* Two short-lived instance-level caches, one for file mtimes
This is a long-lived cache that is reused by every StalenessChecker instance.
* A class-level dependency cache which stores @import paths for each file.
To speed things up two level of caches are employed:
The class handles `.sss` file staleness checks via their mtime timestamps.

def self.stylesheet_needs_update?(css_file, template_file)

Parameters:
  • template_file (String) -- The location of the Sass or SCSS template
  • css_file (String) -- The location of the CSS file to check.
def self.stylesheet_needs_update?(css_file, template_file)
  new.stylesheet_needs_update?(css_file, template_file)
end

def compute_dependencies(filename)

def compute_dependencies(filename)
  Files.tree_for(filename, Plugin.engine_options).grep(Tree::ImportNode) do |n|
    File.expand_path(n.full_filename) unless n.full_filename =~ /\.css$/
  end.compact
rescue Sass::SyntaxError => e
  [] # If the file has an error, we assume it has no dependencies
end

def dependencies(filename)

def dependencies(filename)
  stored_mtime, dependencies = @dependencies[filename]
  if !stored_mtime || stored_mtime < mtime(filename)
    @dependencies[filename] = [mtime(filename), dependencies = compute_dependencies(filename)]
  end
  dependencies
end

def dependencies_stale?(template_file, css_mtime)

def dependencies_stale?(template_file, css_mtime)
  timestamps = @dependencies_stale[template_file] ||= {}
  timestamps.each_pair do |checked_css_mtime, is_stale|
    if checked_css_mtime <= css_mtime && !is_stale
      return false
    elsif checked_css_mtime > css_mtime && is_stale
      return true
    end
  end
  timestamps[css_mtime] = dependencies(template_file).any?(&dependency_updated?(css_mtime))
end

def dependency_updated?(css_mtime)

def dependency_updated?(css_mtime)
  lambda do |dep|
    begin
      mtime(dep) > css_mtime || dependencies_stale?(dep, css_mtime)
    rescue Sass::SyntaxError
      # If there's an error finding depenencies, default to recompiling.
      true
    end
  end
end

def initialize

for checking the staleness of several stylesheets at once.
Creates a new StalenessChecker
def initialize
  @dependencies = self.class.dependencies_cache
  # Entries in the following instance-level caches are never explicitly expired.
  # Instead they are supposed to automaticaly go out of scope when a series of staleness checks
  # (this instance of StalenessChecker was created for) is finished.
  @mtimes, @dependencies_stale = {}, {}
end

def mtime(filename)

def mtime(filename)
  @mtimes[filename] ||= begin
    File.mtime(filename).to_i
  rescue Errno::ENOENT
    @dependencies.delete(filename)
    DELETED
  end
end

def stylesheet_needs_update?(css_file, template_file)

Parameters:
  • template_file (String) -- The location of the Sass or SCSS template
  • css_file (String) -- The location of the CSS file to check.
def stylesheet_needs_update?(css_file, template_file)
  template_file, css_mtime = File.expand_path(template_file), mtime(css_file)
  css_mtime == DELETED || dependency_updated?(css_mtime).call(template_file)
end