def test_calculate_depends_for_topological_order(self): def create_mock(name, run_depends): m = Mock() m.name = name m.build_depends = [] m.buildtool_depends = [] m.run_depends = run_depends m.exports = [] return m mockproject1 = _PackageDecorator(create_mock('n1', []), 'p1') mockproject2 = _PackageDecorator(create_mock('n2', []), 'p2') mockproject3 = _PackageDecorator(create_mock('n3', []), 'p3') mockproject4 = _PackageDecorator(create_mock('n4', []), 'p4') mockproject5 = _PackageDecorator(create_mock('n5', [mockproject4]), 'p5') mockproject6 = _PackageDecorator(create_mock('n6', [mockproject5]), 'p6') mockproject7 = _PackageDecorator(create_mock('n7', []), 'p7') mockproject = Mock() mockproject.build_depends = [mockproject1, mockproject2] mockproject.buildtool_depends = [mockproject3, mockproject6] mockproject.run_depends = [mockproject7] mockproject.exports = [] pd = _PackageDecorator(mockproject, 'foo/bar') # 2 and 3 as external dependencies packages = {mockproject1.name: mockproject1, mockproject4.name: mockproject4, mockproject5.name: mockproject5, mockproject6.name: mockproject6} pd.calculate_depends_for_topological_order(packages) self.assertEqual(set([mockproject1.name, mockproject4.name, mockproject5.name, mockproject6.name]), pd.depends_for_topological_order)
def test_calculate_depends_for_topological_order(self): def create_mock(name, run_depends): m = Mock() m.name = name m.build_depends = [] m.buildtool_depends = [] m.run_depends = run_depends m.exports = [] return m mockproject1 = _PackageDecorator(create_mock('n1', []), 'p1') mockproject2 = _PackageDecorator(create_mock('n2', []), 'p2') mockproject3 = _PackageDecorator(create_mock('n3', []), 'p3') mockproject4 = _PackageDecorator(create_mock('n4', []), 'p4') mockproject5 = _PackageDecorator(create_mock('n5', [mockproject4]), 'p5') mockproject6 = _PackageDecorator(create_mock('n6', [mockproject5]), 'p6') mockproject7 = _PackageDecorator(create_mock('n7', []), 'p7') mockproject = Mock() mockproject.build_depends = [mockproject1, mockproject2] mockproject.buildtool_depends = [mockproject3, mockproject6] mockproject.run_depends = [mockproject7] mockproject.test_depends = [] mockproject.exports = [] pd = _PackageDecorator(mockproject, 'foo/bar') # 2 and 3 as external dependencies packages = {mockproject1.name: mockproject1, mockproject4.name: mockproject4, mockproject5.name: mockproject5, mockproject6.name: mockproject6} pd.calculate_depends_for_topological_order(packages) self.assertEqual(set([mockproject1.name, mockproject4.name, mockproject5.name, mockproject6.name]), pd.depends_for_topological_order)
def topological_order_packages(packages): """ Order packages topologically. First returning packages which have message generators and then the rest based on all direct depends and indirect recursive run_depends. :param packages: A dict mapping relative paths to ``Package`` objects ``dict`` :returns: A list of tuples containing the relative path and a ``Package`` object, ``list`` """ from catkin_pkg.topological_order import _PackageDecorator from catkin_pkg.topological_order import _sort_decorated_packages decorators_by_name = {} for path, package in packages.items(): decorators_by_name[package.name] = _PackageDecorator(package, path) # calculate transitive dependencies for decorator in decorators_by_name.values(): decorator.depends_for_topological_order = set([]) all_depends = \ decorator.package.build_depends + decorator.package.buildtool_depends + \ decorator.package.run_depends + decorator.package.test_depends # skip external dependencies, meaning names that are not known packages for name in [d.name for d in all_depends if d.name in decorators_by_name.keys()]: decorators_by_name[name]._add_recursive_run_depends( decorators_by_name, decorator.depends_for_topological_order) ordered_pkg_tuples = _sort_decorated_packages(decorators_by_name) for pkg_path, pkg in ordered_pkg_tuples: if pkg_path is None: raise RuntimeError('Circular dependency in: %s' % pkg) return ordered_pkg_tuples
def test_package_decorator_init(self): mockproject = Mock() mockexport = Mock() mockexport.tagname = 'message_generator' mockexport.content = 'foolang' mockproject.exports = [mockexport] pd = _PackageDecorator(mockproject, 'foo/bar') self.assertEqual(mockproject.name, pd.name) self.assertEqual('foo/bar', pd.path) self.assertFalse(pd.is_metapackage) self.assertEqual(mockexport.content, pd.message_generator) self.assertIsNotNone(str(pd))
def topological_order_packages(packages): """ Order packages topologically. First returning packages which have message generators and then the rest based on all direct depends and indirect recursive run_depends. :param packages: A dict mapping relative paths to ``Package`` objects ``dict`` :returns: A list of tuples containing the relative path and a ``Package`` object, ``list`` """ from catkin_pkg.topological_order import _PackageDecorator from catkin_pkg.topological_order import _sort_decorated_packages decorators_by_name = {} for path, package in packages.items(): decorators_by_name[package.name] = _PackageDecorator(package, path) # calculate transitive dependencies for decorator in decorators_by_name.values(): decorator.depends_for_topological_order = set([]) all_depends = \ decorator.package.build_depends + decorator.package.buildtool_depends + \ decorator.package.run_depends + decorator.package.test_depends # skip external dependencies, meaning names that are not known packages unique_depend_names = set([ d.name for d in all_depends if d.name in decorators_by_name.keys() and d.evaluated_condition is not False ]) unique_depend_names.update([ m for d in decorator.package.group_depends for m in d.members if d.evaluated_condition is not False ]) for name in unique_depend_names: if name in decorator.depends_for_topological_order: # avoid function call to improve performance # check within the loop since the set changes every cycle continue decorators_by_name[name]._add_recursive_run_depends( decorators_by_name, decorator.depends_for_topological_order) ordered_pkg_tuples = _sort_decorated_packages(decorators_by_name) for pkg_path, pkg in ordered_pkg_tuples: if pkg_path is None: raise RuntimeError('Circular dependency in: %s' % pkg) return ordered_pkg_tuples
def test_calculate_depends_for_topological_order(self): def create_mock(name, run_depends): m = Mock() m.name = name m.build_depends = [] m.buildtool_depends = [] m.run_depends = run_depends m.exports = [] return m mockproject1 = _PackageDecorator(create_mock("n1", []), "p1") mockproject2 = _PackageDecorator(create_mock("n2", []), "p2") mockproject3 = _PackageDecorator(create_mock("n3", []), "p3") mockproject4 = _PackageDecorator(create_mock("n4", []), "p4") mockproject5 = _PackageDecorator(create_mock("n5", [mockproject4]), "p5") mockproject6 = _PackageDecorator(create_mock("n6", [mockproject5]), "p6") mockproject7 = _PackageDecorator(create_mock("n7", []), "p7") mockproject = Mock() mockproject.build_depends = [mockproject1, mockproject2] mockproject.buildtool_depends = [mockproject3, mockproject6] mockproject.run_depends = [mockproject7] mockproject.test_depends = [] mockproject.exports = [] pd = _PackageDecorator(mockproject, "foo/bar") # 2 and 3 as external dependencies packages = { mockproject1.name: mockproject1, mockproject4.name: mockproject4, mockproject5.name: mockproject5, mockproject6.name: mockproject6, } pd.calculate_depends_for_topological_order(packages) self.assertEqual( set([mockproject1.name, mockproject4.name, mockproject5.name, mockproject6.name]), pd.depends_for_topological_order, )
def topological_order_packages(packages): """ Order packages topologically. First returning packages which have message generators and then the rest based on all direct depends and indirect recursive run_depends. :param packages: A dict mapping relative paths to ``Package`` objects ``dict`` :returns: A list of tuples containing the relative path and a ``Package`` object, ``list`` """ from catkin_pkg.topological_order import _PackageDecorator from catkin_pkg.topological_order import _sort_decorated_packages decorators_by_name = {} for path, package in packages.items(): decorators_by_name[package.name] = _PackageDecorator(package, path) # calculate transitive dependencies for decorator in decorators_by_name.values(): decorator.depends_for_topological_order = set([]) all_depends = \ decorator.package.build_depends + decorator.package.buildtool_depends + \ decorator.package.run_depends + decorator.package.test_depends # skip external dependencies, meaning names that are not known packages for name in [ d.name for d in all_depends if d.name in decorators_by_name.keys() ]: decorators_by_name[name]._add_recursive_run_depends( decorators_by_name, decorator.depends_for_topological_order) ordered_pkg_tuples = _sort_decorated_packages(decorators_by_name) for pkg_path, pkg in ordered_pkg_tuples: if pkg_path is None: raise RuntimeError('Circular dependency in: %s' % pkg) return ordered_pkg_tuples