Incremental regeneration
This commit is contained in:
parent
cb8a4b4d62
commit
11917645f2
|
@ -48,6 +48,7 @@ module Jekyll
|
||||||
autoload :Layout, 'jekyll/layout'
|
autoload :Layout, 'jekyll/layout'
|
||||||
autoload :LayoutReader, 'jekyll/layout_reader'
|
autoload :LayoutReader, 'jekyll/layout_reader'
|
||||||
autoload :LogAdapter, 'jekyll/log_adapter'
|
autoload :LogAdapter, 'jekyll/log_adapter'
|
||||||
|
autoload :Metadata, 'jekyll/metadata'
|
||||||
autoload :Page, 'jekyll/page'
|
autoload :Page, 'jekyll/page'
|
||||||
autoload :PluginManager, 'jekyll/plugin_manager'
|
autoload :PluginManager, 'jekyll/plugin_manager'
|
||||||
autoload :Post, 'jekyll/post'
|
autoload :Post, 'jekyll/post'
|
||||||
|
|
|
@ -21,7 +21,14 @@ module Jekyll
|
||||||
#
|
#
|
||||||
# Returns an Array of the file and directory paths
|
# Returns an Array of the file and directory paths
|
||||||
def obsolete_files
|
def obsolete_files
|
||||||
(existing_files - new_files - new_dirs + replaced_files).to_a
|
(existing_files - new_files - new_dirs + replaced_files + metadata_file).to_a
|
||||||
|
end
|
||||||
|
|
||||||
|
# Private: The metadata file storing dependency tree and build history
|
||||||
|
#
|
||||||
|
# Returns an Array with the metdata file as the only item
|
||||||
|
def metadata_file
|
||||||
|
[site.metadata.metadata_file]
|
||||||
end
|
end
|
||||||
|
|
||||||
# Private: The list of existing files, apart from those included in keep_files and hidden files.
|
# Private: The list of existing files, apart from those included in keep_files and hidden files.
|
||||||
|
|
|
@ -58,6 +58,7 @@ module Jekyll
|
||||||
c.option 'unpublished', '--unpublished', 'Render posts that were marked as unpublished'
|
c.option 'unpublished', '--unpublished', 'Render posts that were marked as unpublished'
|
||||||
c.option 'quiet', '-q', '--quiet', 'Silence output.'
|
c.option 'quiet', '-q', '--quiet', 'Silence output.'
|
||||||
c.option 'verbose', '-V', '--verbose', 'Print verbose output.'
|
c.option 'verbose', '-V', '--verbose', 'Print verbose output.'
|
||||||
|
c.option 'clean', '-c', '--clean', 'Clean the site before rebuilding.'
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -207,6 +207,12 @@ module Jekyll
|
||||||
info,
|
info,
|
||||||
File.join(site.config['layouts'], layout.name))
|
File.join(site.config['layouts'], layout.name))
|
||||||
|
|
||||||
|
# Add layout to dependency tree
|
||||||
|
site.metadata.add_dependency(
|
||||||
|
Jekyll.sanitized_path(site.source, path),
|
||||||
|
Jekyll.sanitized_path(site.source, layout.path)
|
||||||
|
)
|
||||||
|
|
||||||
if layout = layouts[layout.data["layout"]]
|
if layout = layouts[layout.data["layout"]]
|
||||||
if used.include?(layout)
|
if used.include?(layout)
|
||||||
layout = nil # avoid recursive chain
|
layout = nil # avoid recursive chain
|
||||||
|
|
|
@ -8,6 +8,9 @@ module Jekyll
|
||||||
# Gets the name of this layout.
|
# Gets the name of this layout.
|
||||||
attr_reader :name
|
attr_reader :name
|
||||||
|
|
||||||
|
# Gets the path to this layout.
|
||||||
|
attr_reader :path
|
||||||
|
|
||||||
# Gets/Sets the extension of this layout.
|
# Gets/Sets the extension of this layout.
|
||||||
attr_accessor :ext
|
attr_accessor :ext
|
||||||
|
|
||||||
|
@ -26,6 +29,7 @@ module Jekyll
|
||||||
@site = site
|
@site = site
|
||||||
@base = base
|
@base = base
|
||||||
@name = name
|
@name = name
|
||||||
|
@path = Jekyll.sanitized_path(site.source, File.join(base, name))
|
||||||
|
|
||||||
self.data = {}
|
self.data = {}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,87 @@
|
||||||
|
require 'set'
|
||||||
|
|
||||||
|
module Jekyll
|
||||||
|
class Metadata
|
||||||
|
attr_reader :site, :metadata
|
||||||
|
|
||||||
|
def initialize(site)
|
||||||
|
@site = site
|
||||||
|
|
||||||
|
# Initialize metadata store by reading YAML file,
|
||||||
|
# or an empty hash if file does not exist
|
||||||
|
@metadata = (File.file?(metadata_file) && !(site.config['clean'])) ? SafeYAML.load(File.read(metadata_file)) : {}
|
||||||
|
|
||||||
|
# Initialize cache to an empty hash
|
||||||
|
@cache = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
# Add a path to the metadata
|
||||||
|
#
|
||||||
|
# Returns true.
|
||||||
|
def add(path)
|
||||||
|
@metadata[path] = {
|
||||||
|
"mtime" => File.mtime(path),
|
||||||
|
"deps" => []
|
||||||
|
}
|
||||||
|
@cache[path] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
# Force a path to regenerate
|
||||||
|
#
|
||||||
|
# Returns true.
|
||||||
|
def force(path)
|
||||||
|
@cache[path] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
# Checks if a path should be regenerated
|
||||||
|
#
|
||||||
|
# Returns a boolean.
|
||||||
|
def regenerate?(path)
|
||||||
|
# Check for path in cache
|
||||||
|
if @cache.has_key? path
|
||||||
|
return @cache[path]
|
||||||
|
end
|
||||||
|
|
||||||
|
# Check path that exists in metadata
|
||||||
|
if (data = @metadata[path])
|
||||||
|
data["deps"].each do |dependency|
|
||||||
|
if regenerate?(dependency)
|
||||||
|
return @cache[dependency] = @cache[path] = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if data["mtime"] == File.mtime(path)
|
||||||
|
return @cache[path] = false
|
||||||
|
else
|
||||||
|
return add(path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Path does not exist in metadata, add it
|
||||||
|
return add(path)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Add a dependency of a path
|
||||||
|
#
|
||||||
|
# Returns true.
|
||||||
|
def add_dependency(path, dependency)
|
||||||
|
@metadata[path]["deps"] << dependency unless @metadata[path]["deps"].include? dependency
|
||||||
|
add(dependency)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Write the metadata to disk
|
||||||
|
#
|
||||||
|
# Returns nothing.
|
||||||
|
def write
|
||||||
|
File.open(metadata_file, 'w') do |f|
|
||||||
|
f.write(@metadata.to_yaml)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Produce the absolute path of the metadata file
|
||||||
|
#
|
||||||
|
# Returns the String path of the file.
|
||||||
|
def metadata_file
|
||||||
|
Jekyll.sanitized_path(site.source, '.jekyll-metadata')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -138,6 +138,12 @@ module Jekyll
|
||||||
File.join(site.config['layouts'], layout.name)
|
File.join(site.config['layouts'], layout.name)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Add layout to dependency tree
|
||||||
|
site.metadata.add_dependency(
|
||||||
|
Jekyll.sanitized_path(site.source, document.path),
|
||||||
|
Jekyll.sanitized_path(site.source, layout.path)
|
||||||
|
)
|
||||||
|
|
||||||
if layout = site.layouts[layout.data["layout"]]
|
if layout = site.layouts[layout.data["layout"]]
|
||||||
if used.include?(layout)
|
if used.include?(layout)
|
||||||
layout = nil # avoid recursive chain
|
layout = nil # avoid recursive chain
|
||||||
|
|
|
@ -11,6 +11,7 @@ module Jekyll
|
||||||
:gems, :plugin_manager
|
:gems, :plugin_manager
|
||||||
|
|
||||||
attr_accessor :converters, :generators
|
attr_accessor :converters, :generators
|
||||||
|
attr_accessor :metadata
|
||||||
|
|
||||||
# Public: Initialize a new Site.
|
# Public: Initialize a new Site.
|
||||||
#
|
#
|
||||||
|
@ -27,6 +28,9 @@ module Jekyll
|
||||||
@source = File.expand_path(config['source']).freeze
|
@source = File.expand_path(config['source']).freeze
|
||||||
@dest = File.expand_path(config['destination']).freeze
|
@dest = File.expand_path(config['destination']).freeze
|
||||||
|
|
||||||
|
# Build metadata
|
||||||
|
@metadata = Metadata.new(self)
|
||||||
|
|
||||||
self.plugin_manager = Jekyll::PluginManager.new(self)
|
self.plugin_manager = Jekyll::PluginManager.new(self)
|
||||||
self.plugins = plugin_manager.plugins_path
|
self.plugins = plugin_manager.plugins_path
|
||||||
|
|
||||||
|
@ -49,7 +53,7 @@ module Jekyll
|
||||||
read
|
read
|
||||||
generate
|
generate
|
||||||
render
|
render
|
||||||
cleanup
|
cleanup if config['clean']
|
||||||
write
|
write
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -289,13 +293,17 @@ module Jekyll
|
||||||
|
|
||||||
collections.each do |label, collection|
|
collections.each do |label, collection|
|
||||||
collection.docs.each do |document|
|
collection.docs.each do |document|
|
||||||
document.output = Jekyll::Renderer.new(self, document).run
|
if @metadata.regenerate?(document.path)
|
||||||
|
document.output = Jekyll::Renderer.new(self, document).run
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
payload = site_payload
|
payload = site_payload
|
||||||
[posts, pages].flatten.each do |page_or_post|
|
[posts, pages].flatten.each do |page_or_post|
|
||||||
page_or_post.render(layouts, payload)
|
if @metadata.regenerate?(Jekyll.sanitized_path(source, page_or_post.relative_path))
|
||||||
|
page_or_post.render(layouts, payload)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
rescue Errno::ENOENT => e
|
rescue Errno::ENOENT => e
|
||||||
# ignore missing layout dir
|
# ignore missing layout dir
|
||||||
|
@ -312,7 +320,12 @@ module Jekyll
|
||||||
#
|
#
|
||||||
# Returns nothing.
|
# Returns nothing.
|
||||||
def write
|
def write
|
||||||
each_site_file { |item| item.write(dest) }
|
each_site_file { |item|
|
||||||
|
if @metadata.regenerate? Jekyll.sanitized_path(source, item.path)
|
||||||
|
item.write(dest)
|
||||||
|
end
|
||||||
|
}
|
||||||
|
@metadata.write
|
||||||
end
|
end
|
||||||
|
|
||||||
# Construct a Hash of Posts indexed by the specified Post attribute.
|
# Construct a Hash of Posts indexed by the specified Post attribute.
|
||||||
|
|
|
@ -105,13 +105,20 @@ eos
|
||||||
end
|
end
|
||||||
|
|
||||||
def render(context)
|
def render(context)
|
||||||
|
site = context.registers[:site]
|
||||||
dir = resolved_includes_dir(context)
|
dir = resolved_includes_dir(context)
|
||||||
|
|
||||||
file = render_variable(context) || @file
|
file = render_variable(context) || @file
|
||||||
validate_file_name(file)
|
validate_file_name(file)
|
||||||
|
|
||||||
path = File.join(dir, file)
|
path = File.join(dir, file)
|
||||||
validate_path(path, dir, context.registers[:site].safe)
|
validate_path(path, dir, site.safe)
|
||||||
|
|
||||||
|
# Add include to dependency tree
|
||||||
|
site.metadata.add_dependency(
|
||||||
|
Jekyll.sanitized_path(site.source, context.registers[:page]["path"]),
|
||||||
|
path
|
||||||
|
)
|
||||||
|
|
||||||
begin
|
begin
|
||||||
partial = Liquid::Template.parse(source(path, context))
|
partial = Liquid::Template.parse(source(path, context))
|
||||||
|
|
|
@ -2,3 +2,4 @@ _site/
|
||||||
*.swp
|
*.swp
|
||||||
pkg/
|
pkg/
|
||||||
test/
|
test/
|
||||||
|
.jekyll-metadata
|
||||||
|
|
Loading…
Reference in New Issue