diff --git a/lib/harp-runtime/interpreter.rb b/lib/harp-runtime/interpreter.rb index d2a55b0..353b3f4 100644 --- a/lib/harp-runtime/interpreter.rb +++ b/lib/harp-runtime/interpreter.rb @@ -94,7 +94,9 @@ def create(resource_name) if ! advance() then return self end @@logger.debug "Launching resource: #{resource_name}." resource = @resourcer.get resource_name - created = @mutator.create(resource_name, resource) + deps = @resourcer.get_dep(resource_name) + deps.each {|ref| create(ref)} + created = @mutator.create(resource_name, resource) created.harp_script = @harp_script result = {:create => resource_name} args = {:action => :create} diff --git a/lib/harp-runtime/resourcer.rb b/lib/harp-runtime/resourcer.rb index be8dab3..d06738f 100644 --- a/lib/harp-runtime/resourcer.rb +++ b/lib/harp-runtime/resourcer.rb @@ -5,13 +5,17 @@ module Harp require "json" - + require "rgl/adjacency" + require "rgl/topsort" + # Resourcer keeps track of defined resources and provides lookup over them. class Resourcer @@logger = Logging.logger[self] def initialize(harp_id) + @dep_graph = RGL::DirectedAdjacencyGraph[] + @dependencies = Hash.new [] @harp_id = harp_id @resources = nil @config = nil @@ -37,14 +41,45 @@ def get_existing(resource_name) @resources[resource_name] end + # Retrieve a resource dependency list from the set + def get_dep(resource_name) + @@logger.debug "Looking for : #{resource_name}'s dependencies" + @dependencies[resource_name] + end + private def digest(content) json = JSON.parse(content) @config = json.has_key?("Config") ? json["Config"] : nil @resources = json.has_key?("Resources") ? json["Resources"] : nil - # TODO: parse into graph and determine dependencies. + parse_into_graph end - end + + def parse_into_graph + @resources.each do |name, content| + match_deps(name, content, "ref") + end + unless @dep_graph.acyclic? + raise "Found circular dependency" + end + end + + #Iterate over values to check for specified item + def match_deps(name, content, item) + content.each do |key, value| + if value.is_a?(Hash) + dep = value[item] + unless dep.nil? + content[key] = @resources.has_key?(dep) ? @resources[dep]["id"] : nil + @dependencies[name] += [dep] + @dep_graph.add_edge(dep, name) + end + end + end + + end + + end end \ No newline at end of file diff --git a/spec/lang_addon_spec.rb b/spec/lang_addon_spec.rb index ea171b8..8b3f48b 100644 --- a/spec/lang_addon_spec.rb +++ b/spec/lang_addon_spec.rb @@ -47,4 +47,4 @@ def copy() results = interpreter.play("copy", interpreter_context) expect(results).not_to be_empty end -end +end \ No newline at end of file diff --git a/spec/reference_spec.rb b/spec/reference_spec.rb new file mode 100644 index 0000000..2843fae --- /dev/null +++ b/spec/reference_spec.rb @@ -0,0 +1,50 @@ +require File.dirname(__FILE__) + '/spec_helper' +require "rubygems" +require "harp_runtime" +require "evalhook" + +ADDON_SCRIPT = <