Move all regenerate? checking to Regenerator

This commit is contained in:
Alfred Xing 2015-01-18 11:05:06 -08:00
parent e58f8776b9
commit fe5f0d124c
12 changed files with 239 additions and 180 deletions

View File

@ -51,11 +51,11 @@ module Jekyll
autoload :Layout, 'jekyll/layout'
autoload :LayoutReader, 'jekyll/layout_reader'
autoload :LogAdapter, 'jekyll/log_adapter'
autoload :Metadata, 'jekyll/metadata'
autoload :Page, 'jekyll/page'
autoload :PluginManager, 'jekyll/plugin_manager'
autoload :Post, 'jekyll/post'
autoload :Publisher, 'jekyll/publisher'
autoload :Regenerator, 'jekyll/regenerator'
autoload :RelatedPosts, 'jekyll/related_posts'
autoload :Renderer, 'jekyll/renderer'
autoload :Site, 'jekyll/site'

View File

@ -29,7 +29,7 @@ module Jekyll
#
# Returns an Array with the metdata file as the only item
def metadata_file
[site.metadata.metadata_file]
[site.regenerator.metadata_file]
end
# Private: The list of existing files, apart from those included in keep_files and hidden files.

View File

@ -168,15 +168,6 @@ module Jekyll
true
end
# Determine whether to regenerate the file based on metadata.
#
# Returns true if file needs to be regenerated
def regenerate?
asset_file? ||
data['regenerate'] ||
site.metadata.regenerate?(site.in_source_dir(relative_path))
end
# Determine whether the file should be placed into layouts.
#
# Returns false if the document is an asset file.
@ -217,7 +208,7 @@ module Jekyll
File.join(site.config['layouts'], layout.name))
# Add layout to dependency tree
site.metadata.add_dependency(
site.regenerator.add_dependency(
site.in_source_dir(path),
site.in_source_dir(layout.path)
)

View File

@ -107,13 +107,6 @@ module Jekyll
!(coffeescript_file? || yaml_file?)
end
# Determine whether the document should be regenerated based on metadata.
#
# Returns true if the document needs to be regenerated.
def regenerate?
data['regenerate'] || site.metadata.regenerate?(path, write?)
end
# Determine whether the file should be placed into layouts.
#
# Returns false if the document is either an asset file or a yaml file,

View File

@ -1,5 +1,5 @@
module Jekyll
class Metadata
class Regenerator
attr_reader :site, :metadata, :cache
def initialize(site)
@ -12,6 +12,25 @@ module Jekyll
@cache = {}
end
# Checks if a renderable object needs to be regenerated
#
# Returns a boolean.
def regenerate?(document)
case document
when Post, Page
document.asset_file? || document.data['regenerate'] ||
modified?(site.in_source_dir(document.relative_path))
when Document
!document.write? || document.data['regenerate'] || modified?(document.path)
else
if document.respond_to?(:path)
modified?(document.path)
else
true
end
end
end
# Add a path to the metadata
#
# Returns true, also on failure.
@ -40,10 +59,11 @@ module Jekyll
@cache = {}
end
# Checks if a path should be regenerated
# Checks if a path's (or one of its dependencies)
# mtime has changed
#
# Returns a boolean.
def regenerate?(path, add = true)
def modified?(path)
return true if disabled?
# Check for path in cache
@ -55,19 +75,19 @@ module Jekyll
data = metadata[path]
if data
data["deps"].each do |dependency|
if regenerate?(dependency)
if modified?(dependency)
return cache[dependency] = cache[path] = true
end
end
if data["mtime"].eql? File.mtime(path)
return cache[path] = false
else
return !add || add(path)
return add(path)
end
end
# Path does not exist in metadata, add it
return !add || add(path)
return add(path)
end
# Add a dependency of a path

View File

@ -140,7 +140,7 @@ module Jekyll
)
# Add layout to dependency tree
site.metadata.add_dependency(
site.regenerator.add_dependency(
site.in_source_dir(document.path),
site.in_source_dir(layout.path)
) if document.write?

View File

@ -11,7 +11,7 @@ module Jekyll
:gems, :plugin_manager
attr_accessor :converters, :generators
attr_reader :metadata
attr_reader :regenerator
# Public: Initialize a new Site.
#
@ -28,8 +28,8 @@ module Jekyll
@source = File.expand_path(config['source']).freeze
@dest = File.expand_path(config['destination']).freeze
# Build metadata
@metadata = Metadata.new(self)
# Initialize incremental regenerator
@regenerator = Regenerator.new(self)
self.plugin_manager = Jekyll::PluginManager.new(self)
self.plugins = plugin_manager.plugins_path
@ -295,13 +295,17 @@ module Jekyll
payload = site_payload
collections.each do |label, collection|
collection.docs.each do |document|
document.output = Jekyll::Renderer.new(self, document, payload).run if document.regenerate?
if regenerator.regenerate?(document)
document.output = Jekyll::Renderer.new(self, document, payload).run
end
end
end
payload = site_payload
[posts, pages].flatten.each do |page_or_post|
page_or_post.render(layouts, payload) if page_or_post.regenerate?
if regenerator.regenerate?(page_or_post)
page_or_post.render(layouts, payload)
end
end
rescue Errno::ENOENT
# ignore missing layout dir
@ -319,9 +323,9 @@ module Jekyll
# Returns nothing.
def write
each_site_file { |item|
item.write(dest) if item.regenerate?
item.write(dest) if regenerator.regenerate?(item)
}
metadata.write unless full_rebuild?
regenerator.write unless full_rebuild?
end
# Construct a Hash of Posts indexed by the specified Post attribute.
@ -487,7 +491,7 @@ module Jekyll
@frontmatter_defaults ||= FrontmatterDefaults.new(self)
end
# Whether to perform a full rebuild without metadata
# Whether to perform a full rebuild without incremental regeneration
#
# Returns a Boolean: true for a full rebuild, false for normal build
def full_rebuild?(override = {})

View File

@ -65,8 +65,6 @@ module Jekyll
true
end
alias_method :regenerate?, :write?
# Write the static file to the destination directory (if modified).
#
# dest - The String path to the destination dir.

View File

@ -116,7 +116,7 @@ eos
# Add include to dependency tree
if context.registers[:page] and context.registers[:page].has_key? "path"
site.metadata.add_dependency(
site.regenerator.add_dependency(
site.in_source_dir(context.registers[:page]["path"]),
path
)

View File

@ -1,140 +0,0 @@
require 'helper'
class TestMetadata < Test::Unit::TestCase
context "The site metadata" do
setup do
FileUtils.rm_rf(source_dir(".jekyll-metadata"))
@site = Site.new(Jekyll.configuration({
"source" => source_dir,
"destination" => dest_dir
}))
@site.process
@path = @site.in_source_dir(@site.pages.first.path)
@metadata = @site.metadata
end
should "store modification times" do
assert_equal File.mtime(@path), @metadata.metadata[@path]["mtime"]
end
should "cache processed entries" do
assert @metadata.cache[@path]
end
should "write to the metadata file" do
@metadata.clear
@metadata.add(@path)
@metadata.write
assert File.file?(source_dir(".jekyll-metadata"))
end
should "read from the metadata file" do
@metadata = Metadata.new(@site)
assert_equal File.mtime(@path), @metadata.metadata[@path]["mtime"]
end
# Methods
should "be able to add a path to the metadata" do
@metadata.clear
@metadata.add(@path)
assert_equal File.mtime(@path), @metadata.metadata[@path]["mtime"]
assert_equal [], @metadata.metadata[@path]["deps"]
assert @metadata.cache[@path]
end
should "return true on nonexistent path" do
@metadata.clear
assert @metadata.add("/bogus/path.md")
assert @metadata.regenerate?("/bogus/path.md")
end
should "be able to force a path to regenerate" do
@metadata.clear
@metadata.force(@path)
assert @metadata.cache[@path]
assert @metadata.regenerate?(@path)
end
should "be able to clear metadata and cache" do
@metadata.clear
@metadata.add(@path)
assert_equal 1, @metadata.metadata.length
assert_equal 1, @metadata.cache.length
@metadata.clear
assert_equal 0, @metadata.metadata.length
assert_equal 0, @metadata.cache.length
end
should "not regenerate a path if it is not modified" do
@metadata.clear
@metadata.add(@path)
@metadata.write
@metadata = Metadata.new(@site)
assert !@metadata.regenerate?(@path)
end
should "not regenerate if path in cache is false" do
@metadata.clear
@metadata.add(@path)
@metadata.write
@metadata = Metadata.new(@site)
assert !@metadata.regenerate?(@path)
assert !@metadata.cache[@path]
assert !@metadata.regenerate?(@path)
end
should "regenerate if path in not in metadata" do
@metadata.clear
@metadata.add(@path)
assert @metadata.regenerate?(@path)
end
should "regenerate if path in cache is true" do
@metadata.clear
@metadata.add(@path)
assert @metadata.regenerate?(@path)
assert @metadata.cache[@path]
assert @metadata.regenerate?(@path)
end
should "regenerate if file is modified" do
@metadata.clear
@metadata.add(@path)
@metadata.metadata[@path]["mtime"] = Time.at(0)
@metadata.write
@metadata = Metadata.new(@site)
assert_not_same File.mtime(@path), @metadata.metadata[@path]["mtime"]
assert @metadata.regenerate?(@path)
end
should "regenerate if dependency is modified" do
@metadata.clear
@metadata.add(@path)
@metadata.write
@metadata = Metadata.new(@site)
@metadata.add_dependency(@path, "new.dependency")
assert_equal ["new.dependency"], @metadata.metadata[@path]["deps"]
assert @metadata.regenerate?("new.dependency")
assert @metadata.regenerate?(@path)
end
should "regenerate everything if metadata is disabled" do
@site.config["full_rebuild"] = true
@metadata.clear
@metadata.add(@path)
@metadata.write
@metadata = Metadata.new(@site)
assert @metadata.regenerate?(@path)
end
end
end

193
test/test_regenerator.rb Normal file
View File

@ -0,0 +1,193 @@
require 'helper'
class TestRegenerator < Test::Unit::TestCase
context "The site regenerator" do
setup do
FileUtils.rm_rf(source_dir(".jekyll-metadata"))
@site = Site.new(Jekyll.configuration({
"source" => source_dir,
"destination" => dest_dir,
"collections" => {
"methods" => {
"output" => true
}
}
}))
@site.read
@page = @site.pages.first
@post = @site.posts.first
@document = @site.docs_to_write.first
@asset_file = @site.pages.find(&:asset_file?)
@regenerator = @site.regenerator
end
should "regenerate documents and assets if changed or not in metadata" do
assert @regenerator.regenerate?(@page)
assert @regenerator.regenerate?(@post)
assert @regenerator.regenerate?(@document)
assert @regenerator.regenerate?(@asset_file)
end
should "not regenerate if not changed" do
# Process files
@regenerator.regenerate?(@page)
@regenerator.regenerate?(@post)
@regenerator.regenerate?(@document)
@regenerator.regenerate?(@asset_file)
@regenerator.write
@regenerator = Regenerator.new(@site)
assert !@regenerator.regenerate?(@page)
assert !@regenerator.regenerate?(@post)
assert !@regenerator.regenerate?(@document)
end
should "always regenerate asset files" do
assert @regenerator.regenerate?(@asset_file)
end
should "always regenerate objects that don't respond to :path" do
assert @regenerator.regenerate?(Object.new)
end
end
context "The site metadata" do
setup do
FileUtils.rm_rf(source_dir(".jekyll-metadata"))
@site = Site.new(Jekyll.configuration({
"source" => source_dir,
"destination" => dest_dir
}))
@site.process
@path = @site.in_source_dir(@site.pages.first.path)
@regenerator = @site.regenerator
end
should "store modification times" do
assert_equal File.mtime(@path), @regenerator.metadata[@path]["mtime"]
end
should "cache processed entries" do
assert @regenerator.cache[@path]
end
should "write to the metadata file" do
@regenerator.clear
@regenerator.add(@path)
@regenerator.write
assert File.file?(source_dir(".jekyll-metadata"))
end
should "read from the metadata file" do
@regenerator = Regenerator.new(@site)
assert_equal File.mtime(@path), @regenerator.metadata[@path]["mtime"]
end
# Methods
should "be able to add a path to the metadata" do
@regenerator.clear
@regenerator.add(@path)
assert_equal File.mtime(@path), @regenerator.metadata[@path]["mtime"]
assert_equal [], @regenerator.metadata[@path]["deps"]
assert @regenerator.cache[@path]
end
should "return true on nonexistent path" do
@regenerator.clear
assert @regenerator.add("/bogus/path.md")
assert @regenerator.modified?("/bogus/path.md")
end
should "be able to force a path to regenerate" do
@regenerator.clear
@regenerator.force(@path)
assert @regenerator.cache[@path]
assert @regenerator.modified?(@path)
end
should "be able to clear metadata and cache" do
@regenerator.clear
@regenerator.add(@path)
assert_equal 1, @regenerator.metadata.length
assert_equal 1, @regenerator.cache.length
@regenerator.clear
assert_equal 0, @regenerator.metadata.length
assert_equal 0, @regenerator.cache.length
end
should "not regenerate a path if it is not modified" do
@regenerator.clear
@regenerator.add(@path)
@regenerator.write
@regenerator = Regenerator.new(@site)
assert !@regenerator.modified?(@path)
end
should "not regenerate if path in cache is false" do
@regenerator.clear
@regenerator.add(@path)
@regenerator.write
@regenerator = Regenerator.new(@site)
assert !@regenerator.modified?(@path)
assert !@regenerator.cache[@path]
assert !@regenerator.modified?(@path)
end
should "regenerate if path in not in metadata" do
@regenerator.clear
@regenerator.add(@path)
assert @regenerator.modified?(@path)
end
should "regenerate if path in cache is true" do
@regenerator.clear
@regenerator.add(@path)
assert @regenerator.modified?(@path)
assert @regenerator.cache[@path]
assert @regenerator.modified?(@path)
end
should "regenerate if file is modified" do
@regenerator.clear
@regenerator.add(@path)
@regenerator.metadata[@path]["mtime"] = Time.at(0)
@regenerator.write
@regenerator = Regenerator.new(@site)
assert_not_same File.mtime(@path), @regenerator.metadata[@path]["mtime"]
assert @regenerator.modified?(@path)
end
should "regenerate if dependency is modified" do
@regenerator.clear
@regenerator.add(@path)
@regenerator.write
@regenerator = Regenerator.new(@site)
@regenerator.add_dependency(@path, "new.dependency")
assert_equal ["new.dependency"], @regenerator.metadata[@path]["deps"]
assert @regenerator.modified?("new.dependency")
assert @regenerator.modified?(@path)
end
should "regenerate everything if metadata is disabled" do
@site.config["full_rebuild"] = true
@regenerator.clear
@regenerator.add(@path)
@regenerator.write
@regenerator = Regenerator.new(@site)
assert @regenerator.modified?(@path)
end
end
end

View File

@ -99,7 +99,7 @@ class TestSite < Test::Unit::TestCase
should "write only modified static files" do
clear_dest
StaticFile.reset_cache
@site.metadata.clear
@site.regenerator.clear
@site.process
some_static_file = @site.static_files[0].path
@ -129,7 +129,7 @@ class TestSite < Test::Unit::TestCase
should "write static files if not modified but missing in destination" do
clear_dest
StaticFile.reset_cache
@site.metadata.clear
@site.regenerator.clear
@site.process
dest = File.expand_path(@site.static_files[0].destination(@site.dest))
@ -243,7 +243,7 @@ class TestSite < Test::Unit::TestCase
context 'with orphaned files in destination' do
setup do
clear_dest
@site.metadata.clear
@site.regenerator.clear
@site.process
# generate some orphaned files:
# single file