Figure out which order the nodes in the graph can be executed
    in to satisfy all requirements.

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!')