lib/dagger/vertex.rb in ruby-dagger-0.1.1 vs lib/dagger/vertex.rb in ruby-dagger-0.2.0
- old
+ new
@@ -1,59 +1,119 @@
+# frozen_string_literal: true
+
require 'key_tree'
+require 'key_tree/refinements'
require_relative 'default'
module Dagger
# Vertex class for Dagger, representing a filesystem directory
+ #
+ # dir/
+ # file.yaml => keytree
+ # prefix@file.yaml => prefix.keytree
+ #
+ # +forest+ = [ +meta+ = {},
+ # +local+ [ { file_keys }, ... ],
+ # [ { Default } ],
+ # +inherited+ = [ [ parent ], ... ]
+ # ]
+ #
class Vertex
- def initialize(name)
- initialize_forest
+ using KeyTree::Refinements
- meta['_meta.name'] = name
- meta['_meta.basename'] = File.basename(name)
- meta['_meta.dirname'] = File.dirname(name)
+ def initialize(name, cached: false)
+ @forest = initialize_forest(cached)
+ @meta['_meta.name'] = name
+ @meta['_meta.basename'] = File.basename(name)
+ @meta['_meta.dirname'] = File.dirname(name)
end
- attr_reader :inherited, :keys, :local, :meta
+ def to_key_forest
+ @forest
+ end
+ alias to_key_wood to_key_forest
def name
- meta['_meta.name']
+ @forest['_meta.name']
end
+ alias to_s name
def [](key)
- key = KeyTree::Path[key] unless key.is_a? KeyTree::Path
- return inherited[key[1..-1]] if key.prefix?(KeyTree::Path['^'])
- keys[key]
+ key = key.to_key_path
+ @inherited[key.drop(1)] if key.prefix?('^')
+ @forest[key]
end
- def fetch(key)
- keys.fetch(key)
+ def fetch(key, *default, &block)
+ key = key.to_key_path
+ @inherited.fetch(key.drop(1), *default, &block) if key.prefix?('^')
+ @forest.fetch(key, *default, &block)
end
def <<(keytree)
- local << keytree
+ @local << keytree
end
def edge_added(edge)
return unless edge.head?(self)
- inherited << edge.tail.keys
+ @inherited << edge.tail.to_key_wood
end
def edge_removed(edge)
return unless edge.head?(self)
- inherited.reject! { |tree| tree.equal?(edge.tail.keys) }
+ @inherited.reject! { |tree| tree.equal?(edge.tail.to_key_wood) }
end
- alias to_s name
+ def added_to_graph(graph)
+ raise %(belongs another graph) if @graph&.!= graph
+ @graph = graph
+ end
+ def removed_from_graph(graph)
+ raise %(not part of graph) if @graph&.!= graph
+ @graph = nil
+ end
+
+ def flatten(cleanup: true)
+ forest = initialize_forest(true)
+
+ forest.key_paths.select { |key| key.prefix?('_default') }.each do |key|
+ forest[key.drop(1)]
+ end
+
+ flattened = forest.flatten
+ return flattened unless cleanup
+ flattened.to_h.delete_if { |key| key.to_s.start_with?('_') }
+ flattened
+ end
+
+ def to_h
+ flatten(cleanup: true).to_h
+ end
+
+ def to_yaml
+ flatten(cleanup: true).to_yaml
+ end
+
+ def to_json
+ flatten(cleanup: true).to_json
+ end
+
private
- def initialize_forest
- @keys = KeyTree::Forest.new
- @keys << @meta = KeyTree::Tree.new
- @keys << @local = KeyTree::Forest.new
- @keys << @default = KeyTree::Forest.new
- @keys << @inherited = KeyTree::Forest.new
- default_proc = Default.new(self).default_proc
- @default << KeyTree::Tree.new(&default_proc)
+ def initialize_forest(cached)
+ forest = KeyTree::Forest.new
+ forest << @meta ||= KeyTree::Tree.new
+ forest << @local ||= KeyTree::Forest.new
+ forest << default = KeyTree::Forest.new
+ forest << @inherited ||= KeyTree::Forest.new
+ default << initialize_default_tree(cached)
+ forest
+ end
+
+ def initialize_default_tree(cached)
+ default_args = cached ? { cached: true, fallback: @inherited } : {}
+ default_proc = Default.proc(self, default_args)
+ KeyTree::Tree.new(&default_proc)
end
end
end