Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
denisdefreyne committed Jul 1, 2017
1 parent d6c6bf6 commit 1a12a41
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 44 deletions.
25 changes: 17 additions & 8 deletions lib/nanoc/base/entities/outdatedness_reasons.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,24 @@ def initialize(message, props = Nanoc::Int::Props.new)
Props.new(raw_content: true, compiled_content: true),
)

ItemCollectionExtended = Generic.new(
'A new item has been added to the site.',
Props.new(raw_content: true),
)
class DocumentCollectionExtended < Generic
attr_reader :objects

LayoutCollectionExtended = Generic.new(
'A new layout has been added to the site.',
Props.new(raw_content: true),
)
def initialize(objects)
super(
'New items/layouts have been added to the site.',
Props.new(raw_content: true),
)

@objects = objects
end
end

class ItemCollectionExtended < DocumentCollectionExtended
end

class LayoutCollectionExtended < DocumentCollectionExtended
end

class AttributesModified < Generic
attr_reader :attributes
Expand Down
13 changes: 10 additions & 3 deletions lib/nanoc/base/repos/dependency_store.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ def initialize(items, layouts, config, site: nil)
C_OBJ_SRC = Nanoc::Int::Item
C_OBJ_DST = C::Or[Nanoc::Int::Item, Nanoc::Int::Layout, Nanoc::Int::Configuration, Nanoc::Int::IdentifiableCollection]

def inspect
self.class.to_s + '(graph=' + @graph.inspect + ')'
end

contract C_OBJ_SRC => C::ArrayOf[Nanoc::Int::Dependency]
def dependencies_causing_outdatedness_of(object)
objects_causing_outdatedness_of(object).map do |other_object|
Expand Down Expand Up @@ -59,9 +63,12 @@ def layouts=(layouts)
add_vertex_for(layouts)
end

contract C::None => C::Bool
def any_new_objects?
@new_objects.any?
def new_items
@new_objects.select { |o| o.is_a?(Nanoc::Int::Item) }
end

def new_layouts
@new_objects.select { |o| o.is_a?(Nanoc::Int::Layout) }
end

# Returns the direct dependencies for the given object.
Expand Down
20 changes: 13 additions & 7 deletions lib/nanoc/base/services/outdatedness_checker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -191,19 +191,25 @@ def dependency_causes_outdatedness?(dependency)
status = basic.outdatedness_status_for(dependency.from)

active = status.props.active & dependency.props.active
if attributes_unaffected?(status, dependency)
active.delete(:attributes)
end
active.delete(:attributes) if attributes_unaffected?(status, dependency)
active.delete(:raw_content) if raw_content_unaffected?(status, dependency)

active.any?
end

def attributes_unaffected?(status, dependency)
attr_reason = status.reasons.find do |r|
r.is_a?(Nanoc::Int::OutdatednessReasons::AttributesModified)
end
reason = status.reasons.find { |r| r.is_a?(Nanoc::Int::OutdatednessReasons::AttributesModified) }
reason && dependency.props.attributes.is_a?(Enumerable) && (dependency.props.attributes & reason.attributes).empty?
end

def raw_content_unaffected?(status, dependency)
# hint: `dependency.from` potentially causes `dependency.to` to be outdated
# if dependency.from is an identifiable collection, is outdated, and the raw_content props of the given dependency match dependency.from, then affected
# new items: reason.objects
# items depended on: items matching anything in dependency.props.raw_content

attr_reason && dependency.props.attributes.is_a?(Enumerable) && (dependency.props.attributes & attr_reason.attributes).empty?
reason = status.reasons.find { |r| r.is_a?(Nanoc::Int::OutdatednessReasons::ItemCollectionExtended) }
reason && dependency.props.raw_content.is_a?(Enumerable) && dependency.props.raw_content.none? { |pat| reason.objects.any? { |obj| Nanoc::Int::Pattern.from(pat).match?(obj.identifier) } }
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ class ItemCollectionExtended < Nanoc::Int::OutdatednessRule

contract Nanoc::Int::ItemCollection, C::Named['Nanoc::Int::OutdatednessChecker'] => C::Maybe[Nanoc::Int::OutdatednessReasons::Generic]
def apply(_obj, outdatedness_checker)
if outdatedness_checker.dependency_store.any_new_objects?
Nanoc::Int::OutdatednessReasons::ItemCollectionExtended
new_items = outdatedness_checker.dependency_store.new_items

if new_items.any?
Nanoc::Int::OutdatednessReasons::ItemCollectionExtended.new(new_items)
end
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ class LayoutCollectionExtended < Nanoc::Int::OutdatednessRule

contract Nanoc::Int::LayoutCollection, C::Named['Nanoc::Int::OutdatednessChecker'] => C::Maybe[Nanoc::Int::OutdatednessReasons::Generic]
def apply(_obj, outdatedness_checker)
if outdatedness_checker.dependency_store.any_new_objects?
Nanoc::Int::OutdatednessReasons::LayoutCollectionExtended
new_layouts = outdatedness_checker.dependency_store.new_layouts

if new_layouts.any?
Nanoc::Int::OutdatednessReasons::LayoutCollectionExtended.new(new_layouts)
end
end
end
Expand Down
79 changes: 57 additions & 22 deletions spec/nanoc/base/services/outdatedness_checker_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@
dependency_store.load
end

it { is_expected.to eq(Nanoc::Int::OutdatednessReasons::ItemCollectionExtended) }
it { is_expected.to be_a(Nanoc::Int::OutdatednessReasons::ItemCollectionExtended) }
end
end

Expand All @@ -161,7 +161,7 @@
dependency_store.load
end

it { is_expected.to eq(Nanoc::Int::OutdatednessReasons::LayoutCollectionExtended) }
it { is_expected.to be_a(Nanoc::Int::OutdatednessReasons::LayoutCollectionExtended) }
end
end
end
Expand Down Expand Up @@ -532,43 +532,78 @@
end

context 'only item collection dependency' do
before do
dependency_store.record_dependency(item, items, raw_content: true)
end

context 'nothing changed' do
it { is_expected.not_to be }
end

context 'item added' do
context 'dependency on any new item' do
before do
dependency_tracker = Nanoc::Int::DependencyTracker.new(dependency_store)
dependency_tracker.enter(item)
dependency_tracker.bounce(items, raw_content: true)

dependency_store.store
end

new_item = Nanoc::Int::Item.new('stuff', {}, '/newblahz.md')
dependency_store.items = Nanoc::Int::ItemCollection.new(config, items.to_a + [new_item])
context 'nothing changed' do
it { is_expected.not_to be }
end

dependency_store.load
context 'item added' do
before do
new_item = Nanoc::Int::Item.new('stuff', {}, '/newblahz.md')
dependency_store.items = Nanoc::Int::ItemCollection.new(config, items.to_a + [new_item])
dependency_store.load
end

it { is_expected.to be }
end

it { is_expected.to be }
context 'item removed' do
before do
dependency_store.items = Nanoc::Int::ItemCollection.new(config, [])
dependency_store.load
end

it { is_expected.not_to be }
end
end

context 'item removed' do
context 'dependency on specific new items' do
before do
dependency_tracker = Nanoc::Int::DependencyTracker.new(dependency_store)
dependency_tracker.bounce(items, raw_content: true)

dependency_tracker.enter(item)
dependency_tracker.bounce(items, raw_content: ['/new*'])
dependency_store.store
end

dependency_store.items = Nanoc::Int::ItemCollection.new(config, [])
context 'nothing changed' do
it { is_expected.not_to be }
end

dependency_store.load
context 'matching item added' do
before do
new_item = Nanoc::Int::Item.new('stuff', {}, '/newblahz.md')
dependency_store.items = Nanoc::Int::ItemCollection.new(config, items.to_a + [new_item])
dependency_store.load
end

it { is_expected.to be }
end

it { is_expected.not_to be }
context 'non-matching item added' do
before do
new_item = Nanoc::Int::Item.new('stuff', {}, '/nublahz.md')
dependency_store.items = Nanoc::Int::ItemCollection.new(config, items.to_a + [new_item])
dependency_store.load
end

it { is_expected.not_to be }
end

context 'item removed' do
before do
dependency_store.items = Nanoc::Int::ItemCollection.new(config, [])
dependency_store.load
end

it { is_expected.not_to be }
end
end
end

Expand Down

0 comments on commit 1a12a41

Please sign in to comment.