From adce349d7a7a0754cb16b1064a7e96b6e26613ac Mon Sep 17 00:00:00 2001 From: Nicholas Burlett Date: Wed, 18 Mar 2015 10:18:37 -0700 Subject: [PATCH 1/3] Clear the regenerator cache every time we process To address part of #3591, clear the regenerator's cache every time the site is processed. This ensures that the regenerator doesn't incorrectly believe a file hasn't changed based on stale information. --- lib/jekyll/regenerator.rb | 8 ++++++++ lib/jekyll/site.rb | 1 + 2 files changed, 9 insertions(+) diff --git a/lib/jekyll/regenerator.rb b/lib/jekyll/regenerator.rb index 0616fdd9..b829a95c 100644 --- a/lib/jekyll/regenerator.rb +++ b/lib/jekyll/regenerator.rb @@ -59,6 +59,14 @@ module Jekyll @cache = {} end + + # Clear just the cache + # + # Returns nothing + def clear_cache + @cache = {} + end + # Checks if a path's (or one of its dependencies) # mtime has changed # diff --git a/lib/jekyll/site.rb b/lib/jekyll/site.rb index 96910255..3961669a 100644 --- a/lib/jekyll/site.rb +++ b/lib/jekyll/site.rb @@ -68,6 +68,7 @@ module Jekyll self.static_files = [] self.data = {} @collections = nil + @regenerator.clear_cache() if limit_posts < 0 raise ArgumentError, "limit_posts must be a non-negative number" From 15ebf929e107d430fa32ca5301ed176c44995478 Mon Sep 17 00:00:00 2001 From: Nicholas Burlett Date: Wed, 18 Mar 2015 22:30:31 -0700 Subject: [PATCH 2/3] Use the new clear_cache method Instead of assigning `@cache = {}`, clear the cache using `clear_cache` --- lib/jekyll/regenerator.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/jekyll/regenerator.rb b/lib/jekyll/regenerator.rb index b829a95c..76d720af 100644 --- a/lib/jekyll/regenerator.rb +++ b/lib/jekyll/regenerator.rb @@ -9,7 +9,7 @@ module Jekyll read_metadata # Initialize cache to an empty hash - @cache = {} + clear_cache end # Checks if a renderable object needs to be regenerated @@ -56,7 +56,7 @@ module Jekyll # Returns nothing def clear @metadata = {} - @cache = {} + clear_cache end From e770a080a7af3f379014dde1436e150edc967e44 Mon Sep 17 00:00:00 2001 From: Nicholas Burlett Date: Thu, 19 Mar 2015 09:41:05 -0700 Subject: [PATCH 3/3] Regenerator cache clearing tests Two tests for the regenerator cache clearing changes: 1. Intrusively test that the regnerator.clear_cache actually clears the cache ( in test/test_regenerator.rb ) 2. Test that incremental building regenerates files that have changed that previously were unchanged ( in test/test_site.rb ) --- test/test_regenerator.rb | 9 +++++++++ test/test_site.rb | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/test/test_regenerator.rb b/test/test_regenerator.rb index 15819487..87312333 100644 --- a/test/test_regenerator.rb +++ b/test/test_regenerator.rb @@ -75,6 +75,15 @@ class TestRegenerator < JekyllUnitTest assert @regenerator.cache[@path] end + should "clear the cache on clear_cache" do + # @path will be in the cache because the + # site will have processed it + assert @regenerator.cache[@path] + + @regenerator.clear_cache + assert_equal @regenerator.cache, {} + end + should "write to the metadata file" do @regenerator.clear @regenerator.add(@path) diff --git a/test/test_site.rb b/test/test_site.rb index 4bc7ddb2..7888f330 100644 --- a/test/test_site.rb +++ b/test/test_site.rb @@ -459,5 +459,43 @@ class TestSite < JekyllUnitTest end end + context "incremental build" do + setup do + @site = Site.new(site_configuration({ + 'full_rebuild' => false + })) + @site.read + end + + should "build incrementally" do + contacts_html = @site.pages.find { |p| p.name == "contacts.html" } + @site.process + + source = @site.in_source_dir(contacts_html.path) + dest = File.expand_path(contacts_html.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 # no modifications, so remain the same + + # simulate file modification by user + FileUtils.touch source + + sleep 1 + @site.process + mtime3 = File.stat(dest).mtime.to_i + refute_equal mtime2, mtime3 # must be regenerated + + sleep 1 + @site.process + mtime4 = File.stat(dest).mtime.to_i + assert_equal mtime3, mtime4 # no modifications, so remain the same + end + + end + end end