haml-edge 2.3.198 → 2.3.199
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/EDGE_GEM_VERSION +1 -1
- data/VERSION +1 -1
- data/lib/sass/plugin/staleness_checker.rb +123 -0
- data/lib/sass/plugin.rb +6 -27
- data/test/sass/plugin_test.rb +3 -8
- metadata +2 -1
data/EDGE_GEM_VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.3.
|
1
|
+
2.3.199
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.3.
|
1
|
+
2.3.199
|
@@ -0,0 +1,123 @@
|
|
1
|
+
module Sass
|
2
|
+
module Plugin
|
3
|
+
# The class handles `.s[ca]ss` file staleness checks via their mtime timestamps.
|
4
|
+
#
|
5
|
+
# To speed things up two level of caches are employed:
|
6
|
+
#
|
7
|
+
# * A class-level dependency cache which stores @import paths for each file.
|
8
|
+
# This is a long-lived cache that is reused by every StalenessChecker instance.
|
9
|
+
# * Two short-lived instance-level caches, one for file mtimes
|
10
|
+
# and one for whether a file is stale during this particular run.
|
11
|
+
# These are only used by a single StalenessChecker instance.
|
12
|
+
#
|
13
|
+
# Usage:
|
14
|
+
#
|
15
|
+
# * For a one-off staleness check of a single `.s[ca]ss` file,
|
16
|
+
# the class-level {stylesheet_needs_update?} method
|
17
|
+
# should be used.
|
18
|
+
# * For a series of staleness checks (e.g. checking all files for staleness)
|
19
|
+
# a StalenessChecker instance should be created,
|
20
|
+
# and the instance-level \{#stylesheet\_needs\_update?} method should be used.
|
21
|
+
# the caches should make the whole process significantly faster.
|
22
|
+
# *WARNING*: It is important not to retain the instance for too long,
|
23
|
+
# as its instance-level caches are never explicitly expired.
|
24
|
+
class StalenessChecker
|
25
|
+
@dependencies_cache = {}
|
26
|
+
|
27
|
+
class << self
|
28
|
+
# @private
|
29
|
+
attr_accessor :dependencies_cache
|
30
|
+
end
|
31
|
+
|
32
|
+
# Creates a new StalenessChecker
|
33
|
+
# for checking the staleness of several stylesheets at once.
|
34
|
+
def initialize
|
35
|
+
@dependencies = self.class.dependencies_cache
|
36
|
+
|
37
|
+
# Entries in the following instance-level caches are never explicitly expired.
|
38
|
+
# Instead they are supposed to automaticaly go out of scope when a series of staleness checks
|
39
|
+
# (this instance of StalenessChecker was created for) is finished.
|
40
|
+
@mtimes, @dependencies_stale = {}, {}
|
41
|
+
end
|
42
|
+
|
43
|
+
# Returns whether or not a given CSS file is out of date
|
44
|
+
# and needs to be regenerated.
|
45
|
+
#
|
46
|
+
# @param css_file [String] The location of the CSS file to check.
|
47
|
+
# @param template_file [String] The location of the Sass or SCSS template
|
48
|
+
# that is compiled to `css_file`.
|
49
|
+
def stylesheet_needs_update?(css_file, template_file)
|
50
|
+
template_file = File.expand_path(template_file)
|
51
|
+
|
52
|
+
unless File.exists?(css_file) && File.exists?(template_file)
|
53
|
+
@dependencies.delete(template_file)
|
54
|
+
true
|
55
|
+
else
|
56
|
+
css_mtime = mtime(css_file)
|
57
|
+
mtime(template_file) > css_mtime || dependencies_stale?(template_file, css_mtime)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Returns whether or not a given CSS file is out of date
|
62
|
+
# and needs to be regenerated.
|
63
|
+
#
|
64
|
+
# The distinction between this method and the instance-level \{#stylesheet\_needs\_update?}
|
65
|
+
# is that the instance method preserves mtime and stale-dependency caches,
|
66
|
+
# so it's better to use when checking multiple stylesheets at once.
|
67
|
+
#
|
68
|
+
# @param css_file [String] The location of the CSS file to check.
|
69
|
+
# @param template_file [String] The location of the Sass or SCSS template
|
70
|
+
# that is compiled to `css_file`.
|
71
|
+
def self.stylesheet_needs_update?(css_file, template_file)
|
72
|
+
new.stylesheet_needs_update?(css_file, template_file)
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def dependencies_stale?(template_file, css_mtime)
|
78
|
+
timestamps = @dependencies_stale[template_file] ||= {}
|
79
|
+
timestamps.each_pair do |checked_css_mtime, is_stale|
|
80
|
+
if checked_css_mtime <= css_mtime && !is_stale
|
81
|
+
return false
|
82
|
+
elsif checked_css_mtime > css_mtime && is_stale
|
83
|
+
return true
|
84
|
+
end
|
85
|
+
end
|
86
|
+
timestamps[css_mtime] = dependencies(template_file).any?(&dependency_updated?(css_mtime))
|
87
|
+
end
|
88
|
+
|
89
|
+
def mtime(filename)
|
90
|
+
@mtimes[filename] ||= File.mtime(filename)
|
91
|
+
end
|
92
|
+
|
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
|
102
|
+
|
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
|
113
|
+
|
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
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
data/lib/sass/plugin.rb
CHANGED
@@ -3,6 +3,7 @@ require 'rbconfig'
|
|
3
3
|
|
4
4
|
require 'sass'
|
5
5
|
require 'sass/callbacks'
|
6
|
+
require 'sass/plugin/staleness_checker'
|
6
7
|
|
7
8
|
module Sass
|
8
9
|
# This module handles the compilation of Sass/SCSS files.
|
@@ -211,6 +212,8 @@ module Sass
|
|
211
212
|
individual_files.each {|t, c| update_stylesheet(t, c)}
|
212
213
|
|
213
214
|
@checked_for_updates = true
|
215
|
+
staleness_checker = StalenessChecker.new
|
216
|
+
|
214
217
|
template_locations.zip(css_locations).each do |template_location, css_location|
|
215
218
|
|
216
219
|
Dir.glob(File.join(template_location, "**", "*.s[ca]ss")).each do |file|
|
@@ -219,7 +222,7 @@ module Sass
|
|
219
222
|
css = css_filename(name, css_location)
|
220
223
|
|
221
224
|
next if forbid_update?(name)
|
222
|
-
if options[:always_update] || stylesheet_needs_update?(css, file)
|
225
|
+
if options[:always_update] || staleness_checker.stylesheet_needs_update?(css, file)
|
223
226
|
update_stylesheet file, css
|
224
227
|
else
|
225
228
|
run_not_updating_stylesheet file, css
|
@@ -374,33 +377,9 @@ module Sass
|
|
374
377
|
name.sub(/^.*\//, '')[0] == ?_
|
375
378
|
end
|
376
379
|
|
380
|
+
# Compass expects this to exist
|
377
381
|
def stylesheet_needs_update?(css_file, template_file)
|
378
|
-
|
379
|
-
|
380
|
-
css_mtime = File.mtime(css_file)
|
381
|
-
File.mtime(template_file) > css_mtime ||
|
382
|
-
dependencies(template_file).any?(&dependency_updated?(css_mtime))
|
383
|
-
end
|
384
|
-
|
385
|
-
def dependency_updated?(css_mtime)
|
386
|
-
lambda do |dep|
|
387
|
-
begin
|
388
|
-
File.mtime(dep) > css_mtime ||
|
389
|
-
dependencies(dep).any?(&dependency_updated?(css_mtime))
|
390
|
-
rescue Sass::SyntaxError
|
391
|
-
# If there's an error finding depenencies, default to recompiling.
|
392
|
-
true
|
393
|
-
end
|
394
|
-
end
|
395
|
-
end
|
396
|
-
|
397
|
-
def dependencies(filename)
|
398
|
-
Files.tree_for(filename, engine_options).select {|n| n.is_a?(Tree::ImportNode)}.map do |n|
|
399
|
-
next if n.full_filename =~ /\.css$/
|
400
|
-
n.full_filename
|
401
|
-
end.compact
|
402
|
-
rescue Sass::SyntaxError => e
|
403
|
-
[] # If the file has an error, we assume it has no dependencies
|
382
|
+
StalenessChecker.stylesheet_needs_update?(css_file, template_file)
|
404
383
|
end
|
405
384
|
end
|
406
385
|
end
|
data/test/sass/plugin_test.rb
CHANGED
@@ -347,12 +347,12 @@ CSS
|
|
347
347
|
end
|
348
348
|
|
349
349
|
def assert_needs_update(name)
|
350
|
-
assert(Sass::Plugin.stylesheet_needs_update?(tempfile_loc(name), template_loc(name)),
|
350
|
+
assert(Sass::Plugin::StalenessChecker.stylesheet_needs_update?(tempfile_loc(name), template_loc(name)),
|
351
351
|
"Expected #{template_loc(name)} to need an update.")
|
352
352
|
end
|
353
353
|
|
354
354
|
def assert_doesnt_need_update(name)
|
355
|
-
assert(!Sass::Plugin.stylesheet_needs_update?(tempfile_loc(name), template_loc(name)),
|
355
|
+
assert(!Sass::Plugin::StalenessChecker.stylesheet_needs_update?(tempfile_loc(name), template_loc(name)),
|
356
356
|
"Expected #{template_loc(name)} not to need an update.")
|
357
357
|
end
|
358
358
|
|
@@ -361,6 +361,7 @@ CSS
|
|
361
361
|
end
|
362
362
|
|
363
363
|
def reset_mtimes
|
364
|
+
Sass::Plugin::StalenessChecker.dependencies_cache = {}
|
364
365
|
atime = Time.now
|
365
366
|
mtime = Time.now - 5
|
366
367
|
Dir["{#{template_loc},#{tempfile_loc}}/**/*.{css,sass,scss}"].each {|f| File.utime(atime, mtime, f)}
|
@@ -407,12 +408,6 @@ CSS
|
|
407
408
|
end
|
408
409
|
end
|
409
410
|
|
410
|
-
module Sass::Plugin
|
411
|
-
class << self
|
412
|
-
public :stylesheet_needs_update?
|
413
|
-
end
|
414
|
-
end
|
415
|
-
|
416
411
|
class Sass::Engine
|
417
412
|
alias_method :old_render, :render
|
418
413
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: haml-edge
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.3.
|
4
|
+
version: 2.3.199
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nathan Weizenbaum
|
@@ -85,6 +85,7 @@ files:
|
|
85
85
|
- lib/sass/plugin/merb.rb
|
86
86
|
- lib/sass/plugin/rack.rb
|
87
87
|
- lib/sass/plugin/rails.rb
|
88
|
+
- lib/sass/plugin/staleness_checker.rb
|
88
89
|
- lib/sass/script.rb
|
89
90
|
- lib/sass/scss.rb
|
90
91
|
- lib/sass/script/bool.rb
|