view python/unroll_deps.py @ 694:ebca6d85213a

File "/usr/lib/python3/dist-packages/IPython/config/__init__.py", line 16, in <module> from .application import * File "/usr/lib/python3/dist-packages/IPython/config/application.py", line 31, in <module> from IPython.config.configurable import SingletonConfigurable File "/usr/lib/python3/dist-packages/IPython/config/configurable.py", line 33, in <module> from IPython.utils.text import indent, wrap_paragraphs File "/usr/lib/python3/dist-packages/IPython/utils/text.py", line 28, in <module> from IPython.external.path import path File "/usr/lib/python3/dist-packages/IPython/external/path/__init__.py", line 2, in <module> from path import * File "/home/jhammel/python/path.py", line 25 print root(path) ^
author Jeff Hammel <k0scist@gmail.com>
date Wed, 09 Jul 2014 16:26:49 -0700
parents 3fe1024377ca
children
line wrap: on
line source

#!/usr/bin/env python

"""
unroll a set of dependencies
"""

import sys

def cycle_check(order, dependencies):
    """ensure no cyclic dependencies"""
    order_dict = dict([(j, i) for i, j in enumerate(order)])
    for package, deps in dependencies.items():
        index = order_dict[package]
        for d in deps:
            assert index > order_dict[d], "Cyclic dependencies detected"


def unroll_dependencies(dependencies):
    """unroll dependencies"""
    order = []

    # unroll the dependencies
    for package, deps in dependencies.items():
        try:
            index = order.index(package)
        except ValueError:
            order.append(package)
            index = len(order) - 1
        for dep in deps:
            try:
                dep_index = order.index(dep)
                if dep_index > index:
                    order.insert(dep_index+1, package)
                    order.pop(index)
                    index = dep_index
            except ValueError:
                order.insert(index, dep)

    cycle_check(order, dependencies)
    return order

def unroll_dependencies2(dependencies):
    """a variation"""
    order = []

    # flatten all
    packages = set(dependencies.keys())
    for deps in dependencies.values():
        packages.update(deps)

    while len(order) != len(packages):

        for package in packages.difference(order):
            if dependencies.get(package, set()).issubset(order):
                order.append(package)
                break
        else:
            raise AssertionError("Cyclic dependencies detected")

    cycle_check(order, dependencies) # sanity

    return order


### testing and CLI

def main(args=sys.argv[:1]):

    # testing set of dependencies
    deps = {'packageA': set(['packageB', 'packageC', 'packageF']),
            'packageB': set(['packageC', 'packageD', 'packageE', 'packageG']),
            'packageC': set(['packageE']),
            'packageE': set(['packageF', 'packageG']),
            'packageF': set(['packageG']),
            'packageX': set(['packageA', 'packageG'])}
    unrolled = unroll_dependencies(deps)
    print ('{}'.format(unrolled))

    unrolled = unroll_dependencies2(deps)
    print unrolled

    # ensure cycle check works
    deps['packageD'] = set(['packageX'])
    try:
        unroll_dependencies(deps)
        raise Exception("Missed a cyclic dependency!")
    except AssertionError:
        pass

    try:
        unroll_dependencies2(deps)
        raise Exception("Missed a cyclic dependency!")
    except AssertionError:
        pass

if __name__ == '__main__':
    main()