Skip to content

Commit

Permalink
added simple add-on dependency solver
Browse files Browse the repository at this point in the history
to solve the registration order according to the dependencies
  • Loading branch information
lslezak committed Mar 12, 2014
1 parent bcc5347 commit 87ec47d
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 1 deletion.
27 changes: 26 additions & 1 deletion src/lib/registration/addon.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# To change this template file, choose Tools | Templates
# and open the template in the editor.

require 'set'
require 'tsort'

module Registration
class Addon
Expand Down Expand Up @@ -35,4 +35,29 @@ def required_addons
end
end

# @see TSort example http://ruby-doc.org/stdlib-2.1.0/libdoc/tsort/rdoc/TSort.html#module-TSort-label-A+Simple+Example
class AddonSorter < Hash
include TSort

alias tsort_each_node each_key

def tsort_each_child(node, &block)
fetch(node).each(&block)
end

def self.registration_order(addons)
solver = AddonSorter.new

# solve the name dependencies
addons.each do |a|
solver[a.name] = a.depends_on.map(&:name)
end

solved = solver.tsort

# convert names back to addons
solved.map{|name| addons.find{|a| a.name == name}}
end
end

end
34 changes: 34 additions & 0 deletions test/addon_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,37 @@
end

end

describe Registration::AddonSorter do
describe ".registration_order" do
it "returns registration order according to the dependencies" do
addon1 = Registration::Addon.new("SUSE_ADDON1", "12", "x86_64")
addon2 = Registration::Addon.new("SUSE_ADDON2", "12", "x86_64")
addon3 = Registration::Addon.new("SUSE_ADDON3", "12", "x86_64", depends_on: [addon1, addon2])
addon4 = Registration::Addon.new("SUSE_ADDON4", "12", "x86_64")
addon5 = Registration::Addon.new("SUSE_ADDON5", "12", "x86_64")
addon6 = Registration::Addon.new("SUSE_ADDON6", "12", "x86_64", depends_on: [addon4, addon5])
addon7 = Registration::Addon.new("SUSE_ADDON7", "12", "x86_64", depends_on: [addon3, addon6])

# deliberately use an order which does not follow dependencies to make sure it is changed
addons = [addon7, addon2, addon3, addon5, addon4, addon6, addon1]

solved = Registration::AddonSorter.registration_order(addons)

# check the order, iterate over the list and check for missing dependencies
registered = []
solved.each do |a|
# check that all dependendent add-ons are already registered
expect(a.depends_on - registered).to be_empty
registered << a
end
end

it "raises KeyError exception when there is an unresolved dependency" do
addon1 = Registration::Addon.new("SUSE_ADDON1", "12", "x86_64")
addon2 = Registration::Addon.new("SUSE_ADDON3", "12", "x86_64", depends_on: [addon1])

expect{Registration::AddonSorter.registration_order([addon2])}.to raise_error(KeyError)
end
end
end

0 comments on commit 87ec47d

Please sign in to comment.