haml-edge 2.3.198 → 2.3.199
Sign up to get free protection for your applications and to get access to all the features.
- 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
|