def test_sort_decorated_packages(self):
        projects = {}
        sprojects = _sort_decorated_packages(projects)
        self.assertEqual([], sprojects)

        mock1 = Mock()
        mock1.depends_for_topological_order = set()

        mock1.message_generator = True

        mock2 = Mock()
        mock2.depends_for_topological_order = set()
        mock2.message_generator = False

        mock3 = Mock()
        mock3.depends_for_topological_order = set()
        mock3.message_generator = False

        projects = {'baz': mock3, 'bar': mock2, 'foo': mock1}
        sprojects = _sort_decorated_packages(projects)
        # mock1 has message generator, come first
        # mock2 before mock3 because of alphabetical ordering
        self.assertEqual([[mock1.path, mock1.package],
                          [mock2.path, mock2.package],
                          [mock3.path, mock3.package]], sprojects)
Esempio n. 2
0
    def test_sort_decorated_packages_cycles(self):
        def create_mock(path, depend):
            m = Mock()
            m.path = path
            m.depends_for_topological_order = set([depend])
            m.message_generator = False
            return m

        # creating a cycle for cycle detection
        mock1 = create_mock('mock1', 'mock2')
        mock2 = create_mock('mock2', 'mock3')
        mock3 = create_mock('mock3', 'mock4')
        mock4 = create_mock('mock4', 'mock2')

        projects = {'mock3': mock3, 'mock2': mock2, 'mock1': mock1, 'mock4': mock4}
        sprojects = _sort_decorated_packages(projects)
        self.assertEqual([[None, 'mock2, mock3, mock4']], sprojects)

        # remove cycle
        mock4.depends_for_topological_order = set()
        sprojects = _sort_decorated_packages(projects)

        # mock4 first since it has no dependencies
        # than mock3 since it only had mock4 as a dependency
        # than mock2 since it only had mock3 as a dependency
        # than mock1 since it only had mock2 as a dependency
        self.assertEqual(['mock4', 'mock3', 'mock2', 'mock1'], [path for path, _ in sprojects])
Esempio n. 3
0
    def test_sort_decorated_packages(self):
        projects = {}
        sprojects = _sort_decorated_packages(projects)
        self.assertEqual([], sprojects)

        mock1 = Mock()
        mock1.depends_for_topological_order = set()

        mock1.message_generator = True

        mock2 = Mock()
        mock2.depends_for_topological_order = set()
        mock2.message_generator = False

        mock3 = Mock()
        mock3.depends_for_topological_order = set()
        mock3.message_generator = False

        projects = {'baz': mock3, 'bar': mock2, 'foo': mock1}
        sprojects = _sort_decorated_packages(projects)
        # mock1 has message generator, come first
        # mock2 before mock3 because of alphabetical ordering
        self.assertEqual(
            [[mock1.path, mock1.package], [mock2.path, mock2.package],
             [mock3.path, mock3.package]], sprojects)
Esempio n. 4
0
    def test_sort_decorated_packages_cycles(self):
        def create_mock(path, depend):
            m = Mock()
            m.path = path
            m.depends_for_topological_order = set([depend])
            m.message_generator = False
            return m

        # creating a cycle for cycle detection
        mock1 = create_mock('mock1', 'mock2')
        mock2 = create_mock('mock2', 'mock3')
        mock3 = create_mock('mock3', 'mock4')
        mock4 = create_mock('mock4', 'mock2')

        projects = {'mock3': mock3, 'mock2': mock2, 'mock1': mock1, 'mock4': mock4}
        sprojects = _sort_decorated_packages(projects)
        self.assertEqual([[None, 'mock2, mock3, mock4']], sprojects)

        # remove cycle
        mock4.depends_for_topological_order = set()
        sprojects = _sort_decorated_packages(projects)

        # mock4 first since it has no dependencies
        # than mock3 since it only had mock4 as a dependency
        # than mock2 since it only had mock3 as a dependency
        # than mock1 since it only had mock2 as a dependency
        self.assertEqual(['mock4', 'mock3', 'mock2', 'mock1'], [path for path, _ in sprojects])
Esempio n. 5
0
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_sort_decorated_packages_cycles(self):
     mock1 = Mock()
     mock2 = Mock()
     mock3 = Mock()
     mock4 = Mock()
     # creating a cycle for cycle detection
     mock1.depends_for_topological_order = set(['mock3'])
     mock2.depends_for_topological_order = set(['mock1'])
     mock3.depends_for_topological_order = set(['mock2'])
     mock4.depends_for_topological_order = set(['mock3'])
     projects = {'mock3': mock3, 'mock2': mock2, 'mock1': mock1, 'mock4': mock4}
     sprojects = _sort_decorated_packages(projects)
     self.assertEqual([[None, 'mock1, mock2, mock3']], sprojects)
     # remove cycle
     mock1.depends_for_topological_order = set()
     sprojects = _sort_decorated_packages(projects)
     # mock1 has message generator, come first
     # mock2 before mock3 because of alphabetical ordering
     self.assertEqual([[mock1.path, mock1.package],
                       [mock2.path, mock2.package],
                       [mock3.path, mock3.package],
                       [mock4.path, mock4.package]], sprojects)
Esempio n. 7
0
    def test_sort_decorated_packages(self):
        projects = {}
        sprojects = _sort_decorated_packages(projects)
        self.assertEqual([], sprojects)

        def create_mock(path):
            m = Mock()
            m.path = path
            m.depends_for_topological_order = set()
            m.message_generator = False
            return m

        mock1 = create_mock('mock1')
        mock2 = create_mock('mock2')
        mock3 = create_mock('mock3')
        mock3.message_generator = True

        projects = {'mock3': mock3, 'mock2': mock2, 'mock1': mock1}
        sprojects = _sort_decorated_packages(projects)

        # mock3 first since it is a message generator
        # mock1 before mock2 due to alphabetic order 
        self.assertEqual(['mock3', 'mock1', 'mock2'], [path for path, _ in sprojects])
Esempio n. 8
0
    def test_sort_decorated_packages(self):
        projects = {}
        sprojects = _sort_decorated_packages(projects)
        self.assertEqual([], sprojects)

        def create_mock(path):
            m = Mock()
            m.path = path
            m.depends_for_topological_order = set()
            m.message_generator = False
            return m

        mock1 = create_mock('mock1')
        mock2 = create_mock('mock2')
        mock3 = create_mock('mock3')
        mock3.message_generator = True

        projects = {'mock3': mock3, 'mock2': mock2, 'mock1': mock1}
        sprojects = _sort_decorated_packages(projects)

        # mock3 first since it is a message generator
        # mock1 before mock2 due to alphabetic order
        self.assertEqual(['mock3', 'mock1', 'mock2'], [path for path, _ in sprojects])
Esempio n. 9
0
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
Esempio n. 10
0
    def test_sort_decorated_packages_favoring_message_generators(self):
        def create_mock(path):
            m = Mock()
            m.path = path
            m.depends_for_topological_order = set()
            m.message_generator = False
            return m

        mock1 = create_mock('mock1')
        mock2 = create_mock('mock2')
        mock3 = create_mock('mock3')
        mock3.depends_for_topological_order = set(['mock2'])
        mock3.message_generator = True

        projects = {'mock3': mock3, 'mock2': mock2, 'mock1': mock1}
        sprojects = _sort_decorated_packages(projects)

        # mock2 first since it is the dependency of a message generator
        # mock3 since it is a message generator
        # mock1 last, although having no dependencies and being first in alphabetic order 
        self.assertEqual(['mock2', 'mock3', 'mock1'], [path for path, _ in sprojects])
Esempio n. 11
0
    def test_sort_decorated_packages_favoring_message_generators(self):
        def create_mock(path):
            m = Mock()
            m.path = path
            m.depends_for_topological_order = set()
            m.message_generator = False
            return m

        mock1 = create_mock('mock1')
        mock2 = create_mock('mock2')
        mock3 = create_mock('mock3')
        mock3.depends_for_topological_order = set(['mock2'])
        mock3.message_generator = True

        projects = {'mock3': mock3, 'mock2': mock2, 'mock1': mock1}
        sprojects = _sort_decorated_packages(projects)

        # mock2 first since it is the dependency of a message generator
        # mock3 since it is a message generator
        # mock1 last, although having no dependencies and being first in alphabetic order
        self.assertEqual(['mock2', 'mock3', 'mock1'], [path for path, _ in sprojects])
Esempio n. 12
0
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