parent
17a5f815b5
commit
3e8c37b641
|
@ -26,3 +26,12 @@ Feature: Cache
|
|||
But the .jekyll-cache directory should not exist
|
||||
And the _site directory should exist
|
||||
And I should see "<p>Hello World</p>" in "_site/index.html"
|
||||
|
||||
Scenario: Disk usage in safe mode
|
||||
Given I have an "index.md" page that contains "{{ site.title }}"
|
||||
And I have a configuration file with "title" set to "Hello World"
|
||||
When I run jekyll build --safe
|
||||
Then I should get a zero exit status
|
||||
But the .jekyll-cache directory should not exist
|
||||
And the _site directory should exist
|
||||
And I should see "<p>Hello World</p>" in "_site/index.html"
|
||||
|
|
|
@ -4,9 +4,59 @@ require "digest"
|
|||
|
||||
module Jekyll
|
||||
class Cache
|
||||
# rubocop:disable Style/ClassVars
|
||||
@@caches = {}
|
||||
@@disk_cache_enabled = true
|
||||
# class-wide base cache
|
||||
@base_cache = {}
|
||||
|
||||
# class-wide directive to write cache to disk is enabled by default
|
||||
@disk_cache_enabled = true
|
||||
|
||||
class << self
|
||||
# class-wide cache location
|
||||
attr_accessor :cache_dir
|
||||
|
||||
# class-wide directive to write cache to disk
|
||||
attr_reader :disk_cache_enabled
|
||||
|
||||
# class-wide base cache reader
|
||||
attr_reader :base_cache
|
||||
|
||||
# Disable Marshaling cached items to disk
|
||||
def disable_disk_cache!
|
||||
@disk_cache_enabled = false
|
||||
end
|
||||
|
||||
# Clear all caches
|
||||
def clear
|
||||
delete_cache_files
|
||||
base_cache.each_value(&:clear)
|
||||
end
|
||||
|
||||
# Compare the current config to the cached config
|
||||
# If they are different, clear all caches
|
||||
#
|
||||
# Returns nothing.
|
||||
def clear_if_config_changed(config)
|
||||
config = config.inspect
|
||||
cache = Jekyll::Cache.new "Jekyll::Cache"
|
||||
return if cache.key?("config") && cache["config"] == config
|
||||
|
||||
clear
|
||||
cache = Jekyll::Cache.new "Jekyll::Cache"
|
||||
cache["config"] = config
|
||||
nil
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Delete all cached items from all caches
|
||||
#
|
||||
# Returns nothing.
|
||||
def delete_cache_files
|
||||
FileUtils.rm_rf(@cache_dir) if disk_cache_enabled
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
# Get an existing named cache, or create a new one if none exists
|
||||
#
|
||||
|
@ -14,27 +64,10 @@ module Jekyll
|
|||
#
|
||||
# Returns nothing.
|
||||
def initialize(name)
|
||||
@cache = @@caches[name] ||= {}
|
||||
@cache = Jekyll::Cache.base_cache[name] ||= {}
|
||||
@name = name.gsub(%r![^\w\s-]!, "-")
|
||||
end
|
||||
|
||||
# Set class-wide base_dir
|
||||
def self.base_dir=(dir_path)
|
||||
@@base_dir = dir_path
|
||||
end
|
||||
|
||||
# Disable Marshaling cached items to disk
|
||||
def self.disable_disk_cache!
|
||||
@@disk_cache_enabled = false
|
||||
end
|
||||
# rubocop:enable Style/ClassVars
|
||||
|
||||
# Clear all caches
|
||||
def self.clear
|
||||
delete_cache_files
|
||||
@@caches.each_value(&:clear)
|
||||
end
|
||||
|
||||
# Clear this particular cache
|
||||
def clear
|
||||
delete_cache_files
|
||||
|
@ -49,7 +82,7 @@ module Jekyll
|
|||
return @cache[key] if @cache.key?(key)
|
||||
|
||||
path = path_to(hash(key))
|
||||
if @@disk_cache_enabled && File.file?(path) && File.readable?(path)
|
||||
if disk_cache_enabled? && File.file?(path) && File.readable?(path)
|
||||
@cache[key] = load(path)
|
||||
else
|
||||
raise
|
||||
|
@ -61,7 +94,7 @@ module Jekyll
|
|||
# Returns nothing.
|
||||
def []=(key, value)
|
||||
@cache[key] = value
|
||||
return unless @@disk_cache_enabled
|
||||
return unless disk_cache_enabled?
|
||||
|
||||
path = path_to(hash(key))
|
||||
value = new Hash(value) if value.is_a?(Hash) && !value.default.nil?
|
||||
|
@ -70,9 +103,8 @@ module Jekyll
|
|||
Jekyll.logger.debug "Cache:", "Cannot dump object #{key}"
|
||||
end
|
||||
|
||||
# If an item already exists in the cache, retrieve it
|
||||
# Else execute code block, and add the result to the cache, and return that
|
||||
# result
|
||||
# If an item already exists in the cache, retrieve it.
|
||||
# Else execute code block, and add the result to the cache, and return that result.
|
||||
def getset(key)
|
||||
self[key]
|
||||
rescue StandardError
|
||||
|
@ -86,10 +118,7 @@ module Jekyll
|
|||
# Returns nothing.
|
||||
def delete(key)
|
||||
@cache.delete(key)
|
||||
return unless @@disk_cache_enabled
|
||||
|
||||
path = path_to(hash(key))
|
||||
File.delete(path)
|
||||
File.delete(path_to(hash(key))) if disk_cache_enabled?
|
||||
end
|
||||
|
||||
# Check if `key` already exists in this cache
|
||||
|
@ -100,40 +129,27 @@ module Jekyll
|
|||
return true if @cache.key?(key)
|
||||
# Otherwise, it might be cached on disk
|
||||
# but we should not consider the disk cache if it is disabled
|
||||
return false unless @@disk_cache_enabled
|
||||
return false unless disk_cache_enabled?
|
||||
|
||||
path = path_to(hash(key))
|
||||
File.file?(path) && File.readable?(path)
|
||||
end
|
||||
|
||||
# Compare the current config to the cached config
|
||||
# If they are different, clear all caches
|
||||
#
|
||||
# Returns nothing.
|
||||
def self.clear_if_config_changed(config)
|
||||
config = config.inspect
|
||||
cache = Jekyll::Cache.new "Jekyll::Cache"
|
||||
return if cache.key?("config") && cache["config"] == config
|
||||
|
||||
clear
|
||||
cache = Jekyll::Cache.new "Jekyll::Cache"
|
||||
cache["config"] = config
|
||||
nil
|
||||
def disk_cache_enabled?
|
||||
!!Jekyll::Cache.disk_cache_enabled
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Given a hashed key, return the path to where this item would be saved on
|
||||
# disk
|
||||
# Given a hashed key, return the path to where this item would be saved on disk.
|
||||
def path_to(hash = nil)
|
||||
@base_dir ||= File.join(@@base_dir, @name)
|
||||
@base_dir ||= File.join(Jekyll::Cache.cache_dir, @name)
|
||||
return @base_dir if hash.nil?
|
||||
|
||||
File.join(@base_dir, hash[0..1], hash[2..-1]).freeze
|
||||
end
|
||||
|
||||
# Given a key, return a SHA2 hash that can be used for caching this item to
|
||||
# disk
|
||||
# Given a key, return a SHA2 hash that can be used for caching this item to disk.
|
||||
def hash(key)
|
||||
Digest::SHA2.hexdigest(key).freeze
|
||||
end
|
||||
|
@ -142,22 +158,14 @@ module Jekyll
|
|||
#
|
||||
# Returns nothing.
|
||||
def delete_cache_files
|
||||
FileUtils.rm_rf(path_to) if @@disk_cache_enabled
|
||||
FileUtils.rm_rf(path_to) if disk_cache_enabled?
|
||||
end
|
||||
|
||||
# Delete all cached items from all caches
|
||||
#
|
||||
# Returns nothing.
|
||||
def self.delete_cache_files
|
||||
FileUtils.rm_rf(@@base_dir) if @@disk_cache_enabled
|
||||
end
|
||||
private_class_method :delete_cache_files
|
||||
|
||||
# Load `path` from disk and return the result
|
||||
# Load `path` from disk and return the result.
|
||||
# This MUST NEVER be called in Safe Mode
|
||||
# rubocop:disable Security/MarshalLoad
|
||||
def load(path)
|
||||
raise unless @@disk_cache_enabled
|
||||
raise unless disk_cache_enabled?
|
||||
|
||||
cached_file = File.open(path, "rb")
|
||||
value = Marshal.load(cached_file)
|
||||
|
@ -166,15 +174,14 @@ module Jekyll
|
|||
end
|
||||
# rubocop:enable Security/MarshalLoad
|
||||
|
||||
# Given a path and a value, save value to disk at path
|
||||
# Given a path and a value, save value to disk at path.
|
||||
# This should NEVER be called in Safe Mode
|
||||
#
|
||||
# Returns nothing.
|
||||
def dump(path, value)
|
||||
return unless @@disk_cache_enabled
|
||||
return unless disk_cache_enabled?
|
||||
|
||||
dir = File.dirname(path)
|
||||
FileUtils.mkdir_p(dir)
|
||||
FileUtils.mkdir_p(File.dirname(path))
|
||||
File.open(path, "wb") do |cached_file|
|
||||
Marshal.dump(value, cached_file)
|
||||
end
|
||||
|
|
|
@ -469,7 +469,7 @@ module Jekyll
|
|||
|
||||
# Disable Marshaling cache to disk in Safe Mode
|
||||
def configure_cache
|
||||
Jekyll::Cache.base_dir = in_source_dir(config["cache_dir"], "Jekyll/Cache")
|
||||
Jekyll::Cache.cache_dir = in_source_dir(config["cache_dir"], "Jekyll/Cache")
|
||||
Jekyll::Cache.disable_disk_cache! if safe
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue