# Copyright (C) IBM Corp. 2016. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. from collections import OrderedDict import logging LOG = logging.getLogger(__name__) class Scheduler(object): """ A *very primitive* scheduler just to deal with dependencies between the packages we build. This class basically returns a tuple containing the best order to build things. """ def _dfs(self, packages, visited): """ Perform a depth-first search to order packages by dependencies Args: packages ([Package]): all packages visited ([Package]): visited packages Returns: [Package]: ordered list of packages """ order = [] try: p = packages[0] except IndexError: pass else: if p not in visited: visited.append(p) # runtime dependencies do not need to be built before the package, # they can be built anytime. We randomly chose to prioritize building # installation dependencies before the package. if p.install_dependencies: order.extend(self._dfs(p.install_dependencies, visited)) if p.build_dependencies: order.extend(self._dfs(p.build_dependencies, visited)) order.append(p) order.extend(self._dfs(packages[1:], visited)) return list(OrderedDict.fromkeys(order)) def schedule(self, packages): """ Order packages by dependencies Args: packages ([Package]): packages Returns: (Package): ordered tuple of packages """ self.packages = packages LOG.info("Scheduling packages and their dependencies: %s" % packages) ordered_packages = self._dfs(packages, []) LOG.debug("Scheduled order: %s" % ordered_packages) return tuple(ordered_packages)