class Nanoc::Core::DependencyStore

@api private

Constants

C_ATTR
C_KEYWORD_PROPS
C_OBJ_DST
C_OBJ_SRC
C_RAW_CONTENT

Attributes

items[R]
layouts[R]

Public Class Methods

new(items, layouts, config) click to toggle source
Calls superclass method Nanoc::Core::Store::new
# File lib/nanoc/core/dependency_store.rb, line 19
def initialize(items, layouts, config)
  super(Nanoc::Core::Store.tmp_path_for(config: config, store_name: 'dependencies'), 5)

  @items = items
  @layouts = layouts

  @refs2objs = {}
  items.each   { |o| add_vertex_for(o) }
  layouts.each { |o| add_vertex_for(o) }
  add_vertex_for(config)
  add_vertex_for(items)
  add_vertex_for(layouts)

  @new_objects = []
  @graph = Nanoc::Core::DirectedGraph.new([nil] + objs2refs(@items) + objs2refs(@layouts))
end

Public Instance Methods

add_vertex_for(obj) click to toggle source
# File lib/nanoc/core/dependency_store.rb, line 123
def add_vertex_for(obj)
  @refs2objs[obj2ref(obj)] = obj
end
dependencies_causing_outdatedness_of(object) click to toggle source
# File lib/nanoc/core/dependency_store.rb, line 37
def dependencies_causing_outdatedness_of(object)
  objects_causing_outdatedness_of(object).map do |other_object|
    props = props_for(other_object, object)

    Nanoc::Core::Dependency.new(
      other_object,
      object,
      Nanoc::Core::DependencyProps.new(
        raw_content: props.fetch(:raw_content, false),
        attributes: props.fetch(:attributes, false),
        compiled_content: props.fetch(:compiled_content, false),
        path: props.fetch(:path, false),
      ),
    )
  end
end
forget_dependencies_for(object) click to toggle source

Empties the list of dependencies for the given object. This is necessary before recompiling the given object, because otherwise old dependencies will stick around and new dependencies will appear twice. This function removes all incoming edges for the given vertex.

@param [Nanoc::Core::Item, Nanoc::Core::Layout] object The object for which to

forget all dependencies

@return [void]

# File lib/nanoc/core/dependency_store.rb, line 136
def forget_dependencies_for(object)
  @graph.delete_edges_to(obj2ref(object))
end
items=(items) click to toggle source
# File lib/nanoc/core/dependency_store.rb, line 54
def items=(items)
  @items = items
  items.each { |o| @refs2objs[obj2ref(o)] = o }
  add_vertex_for(items)
end
layouts=(layouts) click to toggle source
# File lib/nanoc/core/dependency_store.rb, line 60
def layouts=(layouts)
  @layouts = layouts
  layouts.each { |o| @refs2objs[obj2ref(o)] = o }
  add_vertex_for(layouts)
end
new_items() click to toggle source
# File lib/nanoc/core/dependency_store.rb, line 66
def new_items
  @new_objects.select { |o| o.is_a?(Nanoc::Core::Item) }
end
new_layouts() click to toggle source
# File lib/nanoc/core/dependency_store.rb, line 70
def new_layouts
  @new_objects.select { |o| o.is_a?(Nanoc::Core::Layout) }
end
objects_causing_outdatedness_of(object) click to toggle source

Returns the direct dependencies for the given object.

The direct dependencies of the given object include the items and layouts that, when outdated will cause the given object to be marked as outdated. Indirect dependencies will not be returned (e.g. if A depends on B which depends on C, then the direct dependencies of A do not include C).

The direct predecessors can include nil, which indicates an item that is no longer present in the site.

@param [Nanoc::Core::Item, Nanoc::Core::Layout] object The object for

which to fetch the direct predecessors

@return [Array<Nanoc::Core::Item, Nanoc::Core::Layout, nil>] The direct predecessors of

the given object
# File lib/nanoc/core/dependency_store.rb, line 91
def objects_causing_outdatedness_of(object)
  refs2objs(@graph.direct_predecessors_of(obj2ref(object)))
end
record_dependency(src, dst, raw_content: false, attributes: false, compiled_content: false, path: false) click to toggle source

Records a dependency from `src` to `dst` in the dependency graph. When `dst` is oudated, `src` will also become outdated.

@param [Nanoc::Core::Item, Nanoc::Core::Layout] src The source of the dependency,

i.e. the object that will become outdated if dst is outdated

@param [Nanoc::Core::Item, Nanoc::Core::Layout] dst The destination of the

dependency, i.e. the object that will cause the source to become
outdated if the destination is outdated

@return [void]

# File lib/nanoc/core/dependency_store.rb, line 107
def record_dependency(src, dst, raw_content: false, attributes: false, compiled_content: false, path: false)
  return if src == dst

  add_vertex_for(src)
  add_vertex_for(dst)

  src_ref = obj2ref(src)
  dst_ref = obj2ref(dst)

  existing_props = Nanoc::Core::DependencyProps.new(**(@graph.props_for(dst_ref, src_ref) || {}))
  new_props = Nanoc::Core::DependencyProps.new(raw_content: raw_content, attributes: attributes, compiled_content: compiled_content, path: path)
  props = existing_props.merge(new_props)

  @graph.add_edge(dst_ref, src_ref, props: props.to_h)
end

Protected Instance Methods

data() click to toggle source
# File lib/nanoc/core/dependency_store.rb, line 172
def data
  {
    edges: @graph.edges,
    vertices: @graph.vertices,
  }
end
data=(new_data) click to toggle source
# File lib/nanoc/core/dependency_store.rb, line 179
def data=(new_data)
  objects = Set.new(@items.to_a + @layouts.to_a)
  refs = objs2refs(objects)

  # Create new graph
  @graph = Nanoc::Core::DirectedGraph.new([nil] + refs)

  # Load vertices
  previous_objects = refs2objs(new_data[:vertices])
  previous_refs = objs2refs(previous_objects)

  # Load edges
  new_data[:edges].each do |edge|
    from_index, to_index, props = *edge
    from = from_index && previous_refs[from_index]
    to   = to_index && previous_refs[to_index]
    @graph.add_edge(from, to, props: props)
  end

  # Record dependency from all items on new items
  @new_objects = objects - previous_objects
end
obj2ref(obj) click to toggle source
# File lib/nanoc/core/dependency_store.rb, line 142
def obj2ref(obj)
  obj&.reference
end
objs2refs(objs) click to toggle source
# File lib/nanoc/core/dependency_store.rb, line 154
def objs2refs(objs)
  objs.map { |o| obj2ref(o) }
end
props_for(from, to) click to toggle source
# File lib/nanoc/core/dependency_store.rb, line 162
def props_for(from, to)
  props = @graph.props_for(obj2ref(from), obj2ref(to)) || {}

  if props.values.any? { |v| v }
    props
  else
    { raw_content: true, attributes: true, compiled_content: true, path: true }
  end
end
ref2obj(reference) click to toggle source
# File lib/nanoc/core/dependency_store.rb, line 146
def ref2obj(reference)
  if reference
    @refs2objs[reference]
  else
    nil
  end
end
refs2objs(refs) click to toggle source
# File lib/nanoc/core/dependency_store.rb, line 158
def refs2objs(refs)
  refs.map { |r| ref2obj(r) }
end