class Jekyll::Regenerator
def add(path)
Add a path to the metadata
def add(path) return true unless File.exist?(path) metadata[path] = { "mtime" => File.mtime(path), "deps" => [], } cache[path] = true end
def add_dependency(path, dependency)
Add a dependency of a path
def add_dependency(path, dependency) return if metadata[path].nil? || disabled unless metadata[path]["deps"].include? dependency metadata[path]["deps"] << dependency add(dependency) unless metadata.include?(dependency) end regenerate? dependency end
def clear
Clear the metadata and cache
def clear @metadata = {} clear_cache end
def clear_cache
Clear just the cache
def clear_cache @cache = {} end
def disabled?
Check if metadata has been disabled
def disabled? self.disabled = !site.incremental? if disabled.nil? disabled end
def existing_file_modified?(path)
def existing_file_modified?(path) # If one of this file dependencies have been modified, # set the regeneration bit for both the dependency and the file to true metadata[path]["deps"].each do |dependency| return cache[dependency] = cache[path] = true if modified?(dependency) end if File.exist?(path) && metadata[path]["mtime"].eql?(File.mtime(path)) # If this file has not been modified, set the regeneration bit to false cache[path] = false else # If it has been modified, set it to true add(path) end end
def force(path)
Force a path to regenerate
def force(path) cache[path] = true end
def initialize(site)
def initialize(site) @site = site # Read metadata from file read_metadata # Initialize cache to an empty hash clear_cache end
def metadata_file
Produce the absolute path of the metadata file
def metadata_file @metadata_file ||= site.in_source_dir(".jekyll-metadata") end
def modified?(path)
mtime has changed
Checks if a path's (or one of its dependencies)
def modified?(path) return true if disabled? # objects that don't have a path are always regenerated return true if path.nil? # Check for path in cache return cache[path] if cache.key? path if metadata[path] # If we have seen this file before, # check if it or one of its dependencies has been modified existing_file_modified?(path) else # If we have not seen this file before, add it to the metadata and regenerate it add(path) end end
def read_metadata
initialize with an empty hash
Read metadata from the metadata file, if no file is found,
def read_metadata @metadata = if !disabled? && File.file?(metadata_file) content = File.binread(metadata_file) begin Marshal.load(content) rescue TypeError SafeYAML.load(content) rescue ArgumentError => e Jekyll.logger.warn("Failed to load #{metadata_file}: #{e}") {} end else {} end end
def regenerate?(document)
Checks if a renderable object needs to be regenerated
def regenerate?(document) return true if disabled case document when Page regenerate_page?(document) when Document regenerate_document?(document) else source_path = document.respond_to?(:path) ? document.path : nil dest_path = document.destination(@site.dest) if document.respond_to?(:destination) source_modified_or_dest_missing?(source_path, dest_path) end end
def regenerate_document?(document)
def regenerate_document?(document) !document.write? || document.data["regenerate"] || source_modified_or_dest_missing?( document.path, document.destination(@site.dest) ) end
def regenerate_page?(document)
def regenerate_page?(document) document.asset_file? || document.data["regenerate"] || source_modified_or_dest_missing?( site.in_source_dir(document.relative_path), document.destination(@site.dest) ) end
def source_modified_or_dest_missing?(source_path, dest_path)
destination is missing
Checks if the source has been modified or the
def source_modified_or_dest_missing?(source_path, dest_path) modified?(source_path) || (dest_path && !File.exist?(dest_path)) end
def write_metadata
Write the metadata to disk
def write_metadata unless disabled? Jekyll.logger.debug "Writing Metadata:", ".jekyll-metadata" File.binwrite(metadata_file, Marshal.dump(metadata)) end end