From f415ff5df5a78ed16cc57c8439cea0ddc71b92fc Mon Sep 17 00:00:00 2001 From: rzaitov Date: Mon, 11 Nov 2013 14:21:03 +0400 Subject: [PATCH] =?UTF-8?q?=D1=80=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D0=BB=20=D0=BA=D0=BB=D0=B0=D1=81=D1=81=20=D1=83?= =?UTF-8?q?=D0=B7=D0=BB=D0=B0=20=D0=B4=D0=BB=D1=8F=20=D0=B3=D1=80=D0=B0?= =?UTF-8?q?=D1=84=D0=B0=20=D0=B7=D0=B0=D0=B2=D0=B8=D1=81=D0=B8=D0=BC=D0=BE?= =?UTF-8?q?=D1=81=D1=82=D0=B5=D0=B9.=20=D0=9D=D0=B0=D0=BF=D0=B8=D1=81?= =?UTF-8?q?=D0=B0=D0=BB=20=D1=82=D0=B5=D1=81=D1=82=20=D1=80=D0=B0=D0=B7?= =?UTF-8?q?=D1=80=D0=B5=D1=88=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=B7=D0=B0=D0=B2?= =?UTF-8?q?=D0=B8=D1=81=D0=B8=D0=BC=D0=BE=D1=81=D1=82=D0=B5=D0=B9=20=D0=B4?= =?UTF-8?q?=D0=BB=D1=8F=20=D0=BE=D0=B4=D0=BD=D0=BE=D1=81=D0=B2=D1=8F=D0=B7?= =?UTF-8?q?=D0=B0=D0=BD=D0=BD=D0=BE=D0=B3=D0=BE=20=D0=B3=D1=80=D0=B0=D1=84?= =?UTF-8?q?=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DependencyResolver/DependencyResolver.py | 38 +++++++++++++++++++ .../Core/DependencyResolver/Node.py | 12 ++++++ .../Core/DependencyResolver/__init__.py | 1 + .../UnitTests/DependencyResolver/__init__.py | 1 + .../DependencyResolver/test_resolver.py | 31 +++++++++++++++ 5 files changed, 83 insertions(+) create mode 100644 scripts/TouchinBuild/Core/DependencyResolver/DependencyResolver.py create mode 100644 scripts/TouchinBuild/Core/DependencyResolver/Node.py create mode 100644 scripts/TouchinBuild/Core/DependencyResolver/__init__.py create mode 100644 scripts/TouchinBuild/Tests/UnitTests/DependencyResolver/__init__.py create mode 100644 scripts/TouchinBuild/Tests/UnitTests/DependencyResolver/test_resolver.py diff --git a/scripts/TouchinBuild/Core/DependencyResolver/DependencyResolver.py b/scripts/TouchinBuild/Core/DependencyResolver/DependencyResolver.py new file mode 100644 index 0000000..42dfbc2 --- /dev/null +++ b/scripts/TouchinBuild/Core/DependencyResolver/DependencyResolver.py @@ -0,0 +1,38 @@ +class DependencyResolver: + def __init__(self): + pass + + def resolve(self, unresolved): + assert unresolved is not None + resolved = [] + + while len(unresolved) > 0: + node = unresolved[0] + self.resolveNode(node, resolved, unresolved, []) + + return resolved + + def resolveNode(self, node, resolved, unresolved, seen): + assert node is not None + assert resolved is not None + assert seen is not None + + seen.append(node) + + for dependency in node.edges: + if dependency not in resolved: + self.guardNotCircularReference(node, dependency, seen) + self.resolveNode(dependency, resolved, unresolved, seen) + + resolved.append(node) + unresolved.remove(node) + seen.remove(node) + + def guardNotCircularReference(self, start, dependency, seen): + assert start is not None + assert dependency is not None + assert seen is not None + + if dependency in seen: + raise Exception('Circular reference detected: {0} -> {1}'.format(start.name, dependency.name)) + diff --git a/scripts/TouchinBuild/Core/DependencyResolver/Node.py b/scripts/TouchinBuild/Core/DependencyResolver/Node.py new file mode 100644 index 0000000..06e1726 --- /dev/null +++ b/scripts/TouchinBuild/Core/DependencyResolver/Node.py @@ -0,0 +1,12 @@ +class Node: + def __init__(self, name): + assert name is not None + + self.name = name + self.edges = [] + + def addEdge(self, node): + assert node is not None + assert node not in self.edges + + self.edges.append(node) \ No newline at end of file diff --git a/scripts/TouchinBuild/Core/DependencyResolver/__init__.py b/scripts/TouchinBuild/Core/DependencyResolver/__init__.py new file mode 100644 index 0000000..cc31abc --- /dev/null +++ b/scripts/TouchinBuild/Core/DependencyResolver/__init__.py @@ -0,0 +1 @@ +__author__ = 'rzaitov' diff --git a/scripts/TouchinBuild/Tests/UnitTests/DependencyResolver/__init__.py b/scripts/TouchinBuild/Tests/UnitTests/DependencyResolver/__init__.py new file mode 100644 index 0000000..cc31abc --- /dev/null +++ b/scripts/TouchinBuild/Tests/UnitTests/DependencyResolver/__init__.py @@ -0,0 +1 @@ +__author__ = 'rzaitov' diff --git a/scripts/TouchinBuild/Tests/UnitTests/DependencyResolver/test_resolver.py b/scripts/TouchinBuild/Tests/UnitTests/DependencyResolver/test_resolver.py new file mode 100644 index 0000000..23834c6 --- /dev/null +++ b/scripts/TouchinBuild/Tests/UnitTests/DependencyResolver/test_resolver.py @@ -0,0 +1,31 @@ +import unittest +from Core.DependencyResolver.DependencyResolver import DependencyResolver +from Core.DependencyResolver.Node import Node + + +class TestDependencyResolver(unittest.TestCase): + def setUp(self): + self.resolver = DependencyResolver() + + def test_OneConnectedness(self): + node1 = Node('node1') + node2 = Node('node2') + + node3 = Node('node3') + node3.addEdge(node1) + node3.addEdge(node2) + + node4 = Node('node4') + node4.addEdge(node3) + node4.addEdge(node1) + + unresolved = [node4, node3, node2, node1] + resolved = self.resolver.resolve(unresolved) + + self.assertEqual(4, len(resolved)) + + self.assertEqual(node1, resolved[0]) + self.assertEqual(node2, resolved[1]) + self.assertEqual(node3, resolved[2]) + self.assertEqual(node4, resolved[3]) +