diff --git a/lib/nanoc/base/repos/checksum_store.rb b/lib/nanoc/base/repos/checksum_store.rb index 06ad488976..0b6c093942 100644 --- a/lib/nanoc/base/repos/checksum_store.rb +++ b/lib/nanoc/base/repos/checksum_store.rb @@ -6,11 +6,14 @@ module Nanoc::Int class ChecksumStore < ::Nanoc::Int::Store include Nanoc::Int::ContractsSupport + attr_accessor :objects + # @param [Nanoc::Int::Site] site - def initialize(site: nil) + def initialize(site: nil, objects:) super(Nanoc::Int::Store.tmp_path_for(env_name: (site.config.env_name if site), store_name: 'checksums'), 1) - @site = site + @site = site # TODO: Remove + @objects = objects @checksums = {} end @@ -53,7 +56,14 @@ def data end def data=(new_data) - @checksums = new_data + references = Set.new(@objects.map(&:reference)) + + @checksums = {} + new_data.each_pair do |key, checksum| + if references.include?(key) || references.include?(key.first) + @checksums[key] = checksum + end + end end end end diff --git a/lib/nanoc/base/services/compiler.rb b/lib/nanoc/base/services/compiler.rb index d88688d809..b4c5d7a6cf 100644 --- a/lib/nanoc/base/services/compiler.rb +++ b/lib/nanoc/base/services/compiler.rb @@ -83,9 +83,10 @@ def run end def load_stores - # FIXME: icky hack to update the dependency store’s list of objects + # FIXME: icky hack to update the dependency/checksum store’s list of objects # (does not include preprocessed objects otherwise) dependency_store.objects = site.items.to_a + site.layouts.to_a + checksum_store.objects = site.items.to_a + site.layouts.to_a + site.code_snippets + [site.config] stores.each(&:load) end diff --git a/lib/nanoc/base/services/compiler_loader.rb b/lib/nanoc/base/services/compiler_loader.rb index e7423acc9e..77fde3a413 100644 --- a/lib/nanoc/base/services/compiler_loader.rb +++ b/lib/nanoc/base/services/compiler_loader.rb @@ -7,8 +7,10 @@ def load(site, action_provider: nil) dependency_store = Nanoc::Int::DependencyStore.new(site.items.to_a + site.layouts.to_a, env_name: site.config.env_name) + objects = site.items.to_a + site.layouts.to_a + site.code_snippets + [site.config] + checksum_store = - Nanoc::Int::ChecksumStore.new(site: site) + Nanoc::Int::ChecksumStore.new(site: site, objects: objects) item_rep_repo = Nanoc::Int::ItemRepRepo.new diff --git a/spec/nanoc/base/repos/checksum_store_spec.rb b/spec/nanoc/base/repos/checksum_store_spec.rb new file mode 100644 index 0000000000..24f8f5a9d6 --- /dev/null +++ b/spec/nanoc/base/repos/checksum_store_spec.rb @@ -0,0 +1,133 @@ +describe Nanoc::Int::ChecksumStore do + let(:store) { described_class.new(objects: objects) } + + let(:objects) { [item, code_snippet] } + + let(:item) { Nanoc::Int::Item.new('asdf', {}, '/foo.md') } + let(:other_item) { Nanoc::Int::Item.new('asdf', {}, '/sneaky.md') } + + let(:code_snippet) { Nanoc::Int::CodeSnippet.new('def hi ; end', 'lib/foo.rb') } + let(:other_code_snippet) { Nanoc::Int::CodeSnippet.new('def ho ; end', 'lib/bar.rb') } + + context 'nothing added' do + it 'has no checksum' do + expect(store[item]).to be_nil + end + + it 'has no content checksum' do + expect(store.content_checksum_for(item)).to be_nil + end + + it 'has no attributes checksum' do + expect(store.attributes_checksum_for(item)).to be_nil + end + end + + context 'setting content on known non-document' do + before { store.add(code_snippet) } + + it 'has checksum' do + expect(store[code_snippet]).not_to be_nil + end + + it 'has no content checksum' do + expect(store.content_checksum_for(code_snippet)).to be_nil + end + + it 'has no attributes checksum' do + expect(store.attributes_checksum_for(code_snippet)).to be_nil + end + + context 'after storing and loading' do + before do + store.store + store.load + end + + it 'has checksum' do + expect(store[code_snippet]).not_to be_nil + end + end + end + + context 'setting content on unknown non-document' do + before { store.add(other_code_snippet) } + + it 'has checksum' do + expect(store[other_code_snippet]).not_to be_nil + end + + it 'has no content checksum' do + expect(store.content_checksum_for(other_code_snippet)).to be_nil + end + + it 'has no attributes checksum' do + expect(store.attributes_checksum_for(other_code_snippet)).to be_nil + end + + context 'after storing and loading' do + before do + store.store + store.load + end + + it 'has no checksum' do + expect(store[other_code_snippet]).to be_nil + end + end + end + + context 'setting content on known item' do + before { store.add(item) } + + it 'has checksum' do + expect(store[item]).not_to be_nil + end + + it 'has content checksum' do + expect(store.content_checksum_for(item)).not_to be_nil + end + + it 'has attributes checksum' do + expect(store.attributes_checksum_for(item)).not_to be_nil + end + + context 'after storing and loading' do + before do + store.store + store.load + end + + it 'has checksum' do + expect(store[item]).not_to be_nil + end + end + end + + context 'setting content on unknown item' do + before { store.add(other_item) } + + it 'has checksum' do + expect(store[other_item]).not_to be_nil + end + + it 'has content checksum' do + expect(store.content_checksum_for(other_item)).not_to be_nil + end + + it 'has attributes checksum' do + expect(store.attributes_checksum_for(other_item)).not_to be_nil + end + + context 'after storing and loading' do + before do + store.store + store.load + end + + it 'has no checksum' do + expect(store[other_item]).to be_nil + end + end + end +end diff --git a/spec/nanoc/base/services/outdatedness_checker_spec.rb b/spec/nanoc/base/services/outdatedness_checker_spec.rb index 95d44a6674..46a76bd63b 100644 --- a/spec/nanoc/base/services/outdatedness_checker_spec.rb +++ b/spec/nanoc/base/services/outdatedness_checker_spec.rb @@ -35,6 +35,8 @@ let(:item_rep) { Nanoc::Int::ItemRep.new(item, :default) } let(:item) { Nanoc::Int::Item.new('stuff', {}, '/foo.md') } + let(:objects) { [item] } + before do reps << item_rep rule_memory_store[item_rep] = old_memory_for_item_rep.serialize @@ -45,9 +47,7 @@ describe '#basic_outdatedness_reason_for' do subject { outdatedness_checker.send(:basic_outdatedness_reason_for, obj) } - let(:checksum_store) do - Nanoc::Int::ChecksumStore.new - end + let(:checksum_store) { Nanoc::Int::ChecksumStore.new(objects: objects) } let(:config) { Nanoc::Int::Configuration.new } @@ -106,9 +106,7 @@ Nanoc::Int::DependencyStore.new(objects) end - let(:checksum_store) do - Nanoc::Int::ChecksumStore.new - end + let(:checksum_store) { Nanoc::Int::ChecksumStore.new(objects: objects) } let(:other_item) { Nanoc::Int::Item.new('other stuff', {}, '/other.md') } let(:other_item_rep) { Nanoc::Int::ItemRep.new(other_item, :default) } diff --git a/spec/nanoc/base/services/outdatedness_rules_spec.rb b/spec/nanoc/base/services/outdatedness_rules_spec.rb index b287e7122f..235f089ad5 100644 --- a/spec/nanoc/base/services/outdatedness_rules_spec.rb +++ b/spec/nanoc/base/services/outdatedness_rules_spec.rb @@ -21,12 +21,13 @@ let(:site) { double(:site) } let(:config) { Nanoc::Int::Configuration.new } let(:code_snippets) { [] } + let(:objects) { [config] + code_snippets + [item] } let(:action_provider) { double(:action_provider) } let(:reps) { Nanoc::Int::ItemRepRepo.new } let(:dependency_store) { Nanoc::Int::DependencyStore.new(dependency_store_objects) } let(:rule_memory_store) { Nanoc::Int::RuleMemoryStore.new } - let(:checksum_store) { Nanoc::Int::ChecksumStore.new } + let(:checksum_store) { Nanoc::Int::ChecksumStore.new(objects: objects) } let(:dependency_store_objects) { [item] } @@ -317,8 +318,6 @@ ].map { |c| !c.instance.apply(new_obj, outdatedness_checker) } end - let(:checksum_store) { Nanoc::Int::ChecksumStore.new } - let(:stored_obj) { raise 'override me' } let(:new_obj) { raise 'override me' } diff --git a/test/base/test_checksum_store.rb b/test/base/test_checksum_store.rb deleted file mode 100644 index a3785b0c30..0000000000 --- a/test/base/test_checksum_store.rb +++ /dev/null @@ -1,28 +0,0 @@ -class Nanoc::Int::ChecksumStoreTest < Nanoc::TestCase - def test_get_with_existing_object - require 'pstore' - - # Create store - FileUtils.mkdir_p('tmp') - pstore = PStore.new('tmp/checksums') - pstore.transaction do - pstore[:data] = { [:item, '/moo/'] => 'zomg' } - pstore[:version] = 1 - end - - # Check - store = Nanoc::Int::ChecksumStore.new - store.load - obj = Nanoc::Int::Item.new('Moo?', {}, '/moo/') - assert_equal 'zomg', store[obj] - end - - def test_get_with_nonexistant_object - store = Nanoc::Int::ChecksumStore.new - store.load - - # Check - obj = Nanoc::Int::Item.new('Moo?', {}, '/animals/cow/') - assert_equal nil, store[obj] - end -end diff --git a/test/base/test_compiler.rb b/test/base/test_compiler.rb index 5c66e15156..c3c40dac55 100644 --- a/test/base/test_compiler.rb +++ b/test/base/test_compiler.rb @@ -11,9 +11,11 @@ def new_compiler(site = nil) action_provider = Nanoc::Int::ActionProvider.named(:rule_dsl).for(site) + objects = site.items.to_a + site.layouts.to_a + params = { compiled_content_cache: Nanoc::Int::CompiledContentCache.new(items: site.items), - checksum_store: Nanoc::Int::ChecksumStore.new(site: site), + checksum_store: Nanoc::Int::ChecksumStore.new(site: site, objects: objects), rule_memory_store: Nanoc::Int::RuleMemoryStore.new, dependency_store: Nanoc::Int::DependencyStore.new( site.items.to_a + site.layouts.to_a,