Class Sass::Plugin::StalenessChecker
In: lib/sass/plugin/staleness_checker.rb
Parent: Object
Haml::Util Engine Color SyntaxError UnitConversionError StandardError AbstractSequence CommaSequence Sequence SimpleSequence Simple Parent Universal Class SelectorPseudoClass Id Pseudo Attribute Interpolation Element Node Operation Literal UnaryOperation StringInterpolation Funcall Interpolation Variable Lexer CssLexer Number Bool String Parser Parser CssParser EvaluationContext StaticParser SassParser CssParser Node DebugNode IfNode CommentNode ForNode PropNode MixinNode DirectiveNode ExtendNode VariableNode WarnNode RootNode WhileNode RuleNode MixinDefNode Enumerable ImportNode Merb::BootLoader MerbBootLoader Repl CSS Environment Rack StalenessChecker lib/sass/repl.rb lib/sass/css.rb lib/sass/environment.rb lib/sass/error.rb lib/sass/engine.rb lib/sass/selector/simple_sequence.rb lib/sass/selector/abstract_sequence.rb lib/sass/selector/sequence.rb lib/sass/selector/comma_sequence.rb lib/sass/selector/simple.rb lib/sass/selector.rb Selector lib/sass/script/css_parser.rb lib/sass/script/lexer.rb lib/sass/script/color.rb lib/sass/script/string.rb lib/sass/script/unary_operation.rb lib/sass/script/variable.rb lib/sass/script/funcall.rb lib/sass/script/string_interpolation.rb lib/sass/script/operation.rb lib/sass/script/bool.rb lib/sass/script/parser.rb lib/sass/script/literal.rb lib/sass/script/node.rb lib/sass/script/interpolation.rb lib/sass/script/css_lexer.rb lib/sass/script/number.rb lib/sass/script/functions.rb Functions Script lib/sass/scss/sass_parser.rb lib/sass/scss/static_parser.rb lib/sass/scss/parser.rb lib/sass/scss/css_parser.rb ScriptLexer ScriptParser RX SCSS Files Callbacks lib/sass/tree/while_node.rb lib/sass/tree/if_node.rb lib/sass/tree/mixin_def_node.rb lib/sass/tree/debug_node.rb lib/sass/tree/root_node.rb lib/sass/tree/for_node.rb lib/sass/tree/import_node.rb lib/sass/tree/prop_node.rb lib/sass/tree/node.rb lib/sass/tree/comment_node.rb lib/sass/tree/extend_node.rb lib/sass/tree/mixin_node.rb lib/sass/tree/warn_node.rb lib/sass/tree/directive_node.rb lib/sass/tree/rule_node.rb lib/sass/tree/variable_node.rb Tree lib/sass/plugin/rack.rb lib/sass/plugin/staleness_checker.rb lib/sass/plugin/merb.rb Plugin Sass dot/m_85_0.png

The class handles `.s[ca]ss` file staleness checks via their mtime timestamps.

To speed things up two level of caches are employed:

  • A class-level dependency cache which stores @import paths for each file. This is a long-lived cache that is reused by every StalenessChecker instance.
  • Two short-lived instance-level caches, one for file mtimes and one for whether a file is stale during this particular run. These are only used by a single StalenessChecker instance.

Usage:

  • For a one-off staleness check of a single `.s[ca]ss` file, the class-level {stylesheet_needs_update?} method should be used.
  • For a series of staleness checks (e.g. checking all files for staleness) a StalenessChecker instance should be created, and the instance-level \{stylesheet_needs_update?} method should be used. the caches should make the whole process significantly faster. WARNING: It is important not to retain the instance for too long, as its instance-level caches are never explicitly expired.

Methods

Constants

DELETED = 1.0/0.0

Attributes

dependencies_cache  [RW]  @private

Public Class methods

Creates a new StalenessChecker for checking the staleness of several stylesheets at once.

[Source]

    # File lib/sass/plugin/staleness_checker.rb, line 35
35:       def initialize
36:         @dependencies = self.class.dependencies_cache
37: 
38:         # Entries in the following instance-level caches are never explicitly expired.
39:         # Instead they are supposed to automaticaly go out of scope when a series of staleness checks
40:         # (this instance of StalenessChecker was created for) is finished.
41:         @mtimes, @dependencies_stale = {}, {}
42:       end

Returns whether or not a given CSS file is out of date and needs to be regenerated.

The distinction between this method and the instance-level \{stylesheet_needs_update?} is that the instance method preserves mtime and stale-dependency caches, so it‘s better to use when checking multiple stylesheets at once.

@param css_file [String] The location of the CSS file to check. @param template_file [String] The location of the Sass or SCSS template

  that is compiled to `css_file`.

[Source]

    # File lib/sass/plugin/staleness_checker.rb, line 66
66:       def self.stylesheet_needs_update?(css_file, template_file)
67:         new.stylesheet_needs_update?(css_file, template_file)
68:       end

Public Instance methods

Returns whether or not a given CSS file is out of date and needs to be regenerated.

@param css_file [String] The location of the CSS file to check. @param template_file [String] The location of the Sass or SCSS template

  that is compiled to `css_file`.

[Source]

    # File lib/sass/plugin/staleness_checker.rb, line 50
50:       def stylesheet_needs_update?(css_file, template_file)
51:         template_file, css_mtime = File.expand_path(template_file), mtime(css_file)
52: 
53:         css_mtime == DELETED || dependency_updated?(css_mtime).call(template_file)
54:       end

Private Instance methods

[Source]

     # File lib/sass/plugin/staleness_checker.rb, line 114
114:       def compute_dependencies(filename)
115:         Files.tree_for(filename, Plugin.engine_options).grep(Tree::ImportNode) do |n|
116:           File.expand_path(n.full_filename) unless n.full_filename =~ /\.css$/
117:         end.compact
118:       rescue Sass::SyntaxError => e
119:         [] # If the file has an error, we assume it has no dependencies
120:       end

[Source]

     # File lib/sass/plugin/staleness_checker.rb, line 93
 93:       def dependencies(filename)
 94:         stored_mtime, dependencies = @dependencies[filename]
 95: 
 96:         if !stored_mtime || stored_mtime < mtime(filename)
 97:           @dependencies[filename] = [mtime(filename), dependencies = compute_dependencies(filename)]
 98:         end
 99: 
100:         dependencies
101:       end

[Source]

    # File lib/sass/plugin/staleness_checker.rb, line 72
72:       def dependencies_stale?(template_file, css_mtime)
73:         timestamps = @dependencies_stale[template_file] ||= {}
74:         timestamps.each_pair do |checked_css_mtime, is_stale|
75:           if checked_css_mtime <= css_mtime && !is_stale
76:             return false
77:           elsif checked_css_mtime > css_mtime && is_stale
78:             return true
79:           end
80:         end
81:         timestamps[css_mtime] = dependencies(template_file).any?(&dependency_updated?(css_mtime))
82:       end

[Source]

     # File lib/sass/plugin/staleness_checker.rb, line 103
103:       def dependency_updated?(css_mtime)
104:         lambda do |dep|
105:           begin
106:             mtime(dep) > css_mtime || dependencies_stale?(dep, css_mtime)
107:           rescue Sass::SyntaxError
108:             # If there's an error finding depenencies, default to recompiling.
109:             true
110:           end
111:         end
112:       end

[Source]

    # File lib/sass/plugin/staleness_checker.rb, line 84
84:       def mtime(filename)
85:         @mtimes[filename] ||= begin
86:           File.mtime(filename).to_i
87:         rescue Errno::ENOENT
88:           @dependencies.delete(filename)
89:           DELETED
90:         end
91:       end

[Validate]