Exemplo n.º 1
0
  def _topological_sort(self, phase_info_by_phase):
    dependees_by_phase = OrderedDict()

    def add_dependee(phase, dependee=None):
      dependees = dependees_by_phase.get(phase)
      if dependees is None:
        dependees = set()
        dependees_by_phase[phase] = dependees
      if dependee:
        dependees.add(dependee)

    for phase, phase_info in phase_info_by_phase.items():
      add_dependee(phase)
      for dependency in phase_info.phase_dependencies:
        add_dependee(dependency, phase)

    satisfied = set()
    while dependees_by_phase:
      count = len(dependees_by_phase)
      for phase, dependees in dependees_by_phase.items():
        unsatisfied = len(dependees - satisfied)
        if unsatisfied == 0:
          satisfied.add(phase)
          dependees_by_phase.pop(phase)
          yield phase_info_by_phase[phase]
          break
      if len(dependees_by_phase) == count:
        for dependees in dependees_by_phase.values():
          dependees.difference_update(satisfied)
        # TODO(John Sirois): Do a better job here and actually collect and print cycle paths
        # between Goals/Tasks.  The developer can most directly address that data.
        raise self.PhaseCycleError('Cycle detected in phase dependencies:\n\t{0}'
                                   .format('\n\t'.join('{0} <- {1}'.format(phase, list(dependees))
                                                       for phase, dependees
                                                       in dependees_by_phase.items())))
Exemplo n.º 2
0
  def _topological_sort(self, goal_info_by_goal):
    dependees_by_goal = OrderedDict()

    def add_dependee(goal, dependee=None):
      dependees = dependees_by_goal.get(goal)
      if dependees is None:
        dependees = set()
        dependees_by_goal[goal] = dependees
      if dependee:
        dependees.add(dependee)

    for goal, goal_info in goal_info_by_goal.items():
      add_dependee(goal)
      for dependency in goal_info.goal_dependencies:
        add_dependee(dependency, goal)

    satisfied = set()
    while dependees_by_goal:
      count = len(dependees_by_goal)
      for goal, dependees in dependees_by_goal.items():
        unsatisfied = len(dependees - satisfied)
        if unsatisfied == 0:
          satisfied.add(goal)
          dependees_by_goal.pop(goal)
          yield goal_info_by_goal[goal]
          break
      if len(dependees_by_goal) == count:
        for dependees in dependees_by_goal.values():
          dependees.difference_update(satisfied)
        # TODO(John Sirois): Do a better job here and actually collect and print cycle paths
        # between Goals/Tasks.  The developer can most directly address that data.
        raise self.GoalCycleError('Cycle detected in goal dependencies:\n\t{0}'
                                   .format('\n\t'.join('{0} <- {1}'.format(goal, list(dependees))
                                                       for goal, dependees
                                                       in dependees_by_goal.items())))