optimization: write static file to the destination only if source file timestamp differs
Also make sure static files get regenerated when they are missing in destination. This is useful in --server --auto mode when it reduces disk/cpu load and also plays nice with xrefresh-server (which was my main motivation) -> soft CSS refresh works again!
This commit is contained in:
parent
ace9911001
commit
f91954be76
|
@ -1,6 +1,8 @@
|
|||
module Jekyll
|
||||
|
||||
class StaticFile
|
||||
@@mtimes = Hash.new # the cache of last modification times [path] -> mtime
|
||||
|
||||
# Initialize a new StaticFile.
|
||||
# +site+ is the Site
|
||||
# +base+ is the String path to the <source>
|
||||
|
@ -15,13 +17,59 @@ module Jekyll
|
|||
@name = name
|
||||
end
|
||||
|
||||
# Write the static file to the destination directory.
|
||||
# Obtains source file path.
|
||||
#
|
||||
# Returns source file path.
|
||||
def path
|
||||
File.join(@base, @dir, @name)
|
||||
end
|
||||
|
||||
# Obtain destination path.
|
||||
# +dest+ is the String path to the destination dir
|
||||
#
|
||||
# Returns nothing
|
||||
# Returns destination file path.
|
||||
def destination(dest)
|
||||
File.join(dest, @dir, @name)
|
||||
end
|
||||
|
||||
# Obtain mtime of the source path.
|
||||
#
|
||||
# Returns last modifiaction time for this file.
|
||||
def mtime
|
||||
File.stat(path).mtime.to_i
|
||||
end
|
||||
|
||||
# Is source path modified?
|
||||
#
|
||||
# Returns true if modified since last write.
|
||||
def modified?
|
||||
@@mtimes[path] != mtime
|
||||
end
|
||||
|
||||
# Write the static file to the destination directory (if modified).
|
||||
# +dest+ is the String path to the destination dir
|
||||
#
|
||||
# Returns false if the file was not modified since last time (no-op).
|
||||
def write(dest)
|
||||
FileUtils.mkdir_p(File.join(dest, @dir))
|
||||
FileUtils.cp(File.join(@base, @dir, @name), File.join(dest, @dir, @name))
|
||||
dest_path = destination(dest)
|
||||
dest_dir = File.join(dest, @dir)
|
||||
|
||||
return false if File.exist? dest_path and !modified?
|
||||
@@mtimes[path] = mtime
|
||||
|
||||
FileUtils.mkdir_p(dest_dir)
|
||||
FileUtils.cp(path, dest_path)
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
# Reset the mtimes cache (for testing purposes).
|
||||
#
|
||||
# Returns nothing.
|
||||
def self.reset_cache
|
||||
@@mtimes = Hash.new
|
||||
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -34,6 +34,64 @@ class TestSite < Test::Unit::TestCase
|
|||
assert before_time <= @site.time
|
||||
end
|
||||
|
||||
should "write only modified static files" do
|
||||
clear_dest
|
||||
StaticFile.reset_cache
|
||||
|
||||
@site.process
|
||||
some_static_file = @site.static_files[0].path
|
||||
dest = File.expand_path(@site.static_files[0].destination(@site.dest))
|
||||
mtime1 = File.stat(dest).mtime.to_i # first run must generate dest file
|
||||
|
||||
# need to sleep because filesystem timestamps have best resolution in seconds
|
||||
sleep 1
|
||||
@site.process
|
||||
mtime2 = File.stat(dest).mtime.to_i
|
||||
assert_equal mtime1, mtime2
|
||||
|
||||
# simulate file modification by user
|
||||
FileUtils.touch some_static_file
|
||||
|
||||
sleep 1
|
||||
@site.process
|
||||
mtime3 = File.stat(dest).mtime.to_i
|
||||
assert_not_equal mtime2, mtime3 # must be regenerated!
|
||||
|
||||
sleep 1
|
||||
@site.process
|
||||
mtime4 = File.stat(dest).mtime.to_i
|
||||
assert_equal mtime3, mtime4 # no modifications, so must be the same
|
||||
end
|
||||
|
||||
should "write static files if not modified but missing in destination" do
|
||||
clear_dest
|
||||
StaticFile.reset_cache
|
||||
|
||||
@site.process
|
||||
some_static_file = @site.static_files[0].path
|
||||
dest = File.expand_path(@site.static_files[0].destination(@site.dest))
|
||||
mtime1 = File.stat(dest).mtime.to_i # first run must generate dest file
|
||||
|
||||
# need to sleep because filesystem timestamps have best resolution in seconds
|
||||
sleep 1
|
||||
@site.process
|
||||
mtime2 = File.stat(dest).mtime.to_i
|
||||
assert_equal mtime1, mtime2
|
||||
|
||||
# simulate destination file deletion
|
||||
File.unlink dest
|
||||
|
||||
sleep 1
|
||||
@site.process
|
||||
mtime3 = File.stat(dest).mtime.to_i
|
||||
assert_not_equal mtime2, mtime3 # must be regenerated and differ!
|
||||
|
||||
sleep 1
|
||||
@site.process
|
||||
mtime4 = File.stat(dest).mtime.to_i
|
||||
assert_equal mtime3, mtime4 # no modifications, so must be the same
|
||||
end
|
||||
|
||||
should "read layouts" do
|
||||
@site.read_layouts
|
||||
assert_equal ["default", "simple"].sort, @site.layouts.keys.sort
|
||||
|
|
Loading…
Reference in New Issue