docs: def resolve_dependencies(nodes):
      """ Figure out which order the nodes in the graph can be executed
      in to satisfy all requirements. """
      done = set()
      while True:
          if len(done) == len(nodes):
              break
          for node in nodes:
              if node.name not in done:
                  match = done.intersection(node.requires)
                  if len(match) == len(node.requires):
                      done.add(node.name)
                      yield node
                      break
          else:
              raise ConfigException('Invalid requirements in pipeline!')