#! /usr/bin/env python

# pdeps
#
# Find dependencies between a bunch of Python modules.
#
# Usage:
#       pdeps file1.py file2.py ...
#
# Output:
# Four tables separated by lines like '--- Closure ---':
# 1) Direct dependencies, listing which module imports which other modules
# 2) The inverse of (1)
# 3) Indirect dependencies, or the closure of the above
# 4) The inverse of (3)
#
# To do:
# - command line options to select output type
# - option to automatically scan the Python library for referenced modules
# - option to limit output to particular modules


import sys
import re
import os


# Main program
#
def main():
    args = sys.argv[1:]
    if not args:
        print('usage: pdeps file.py file.py ...')
        return 2
    #
    table = {}
    for arg in args:
        process(arg, table)
    #
    print('--- Uses ---')
    printresults(table)
    #
    print('--- Used By ---')
    inv = inverse(table)
    printresults(inv)
    #
    print('--- Closure of Uses ---')
    reach = closure(table)
    printresults(reach)
    #
    print('--- Closure of Used By ---')
    invreach = inverse(reach)
    printresults(invreach)
    #
    return 0


# Compiled regular expressions to search for import statements
#
m_import = re.compile('^[ \t]*from[ \t]+([^ \t]+)[ \t]+')
m_from = re.compile('^[ \t]*import[ \t]+([^#]+)')


# Collect data from one file
#
def process(filename, table):
    fp = open(filename, 'r')
    mod = os.path.basename(filename)
    if mod[-3:] == '.py':
        mod = mod[:-3]
    table[mod] = list = []
    while 1:
        line = fp.readline()
        if not line: break
        while line[-1:] == '\\':
            nextline = fp.readline()
            if not nextline: break
            line = line[:-1] + nextline
        if m_import.match(line) >= 0:
            (a, b), (a1, b1) = m_import.regs[:2]
        elif m_from.match(line) >= 0:
            (a, b), (a1, b1) = m_from.regs[:2]
        else: continue
        words = line[a1:b1].split(',')
        # print '#', line, words
        for word in words:
            word = word.strip()
            if word not in list:
                list.append(word)


# Compute closure (this is in fact totally general)
#
def closure(table):
    modules = list(table.keys())
    #
    # Initialize reach with a copy of table
    #
    reach = {}
    for mod in modules:
        reach[mod] = table[mod][:]
    #
    # Iterate until no more change
    #
    change = 1
    while change:
        change = 0
        for mod in modules:
            for mo in reach[mod]:
                if mo in modules:
                    for m in reach[mo]:
                        if m not in reach[mod]:
                            reach[mod].append(m)
                            change = 1
    #
    return reach


# Invert a table (this is again totally general).
# All keys of the original table are made keys of the inverse,
# so there may be empty lists in the inverse.
#
def inverse(table):
    inv = {}
    for key in table.keys():
        if not inv.has_key(key):
            inv[key] = []
        for item in table[key]:
            store(inv, item, key)
    return inv


# Store "item" in "dict" under "key".
# The dictionary maps keys to lists of items.
# If there is no list for the key yet, it is created.
#
def store(dict, key, item):
    if key in dict:
        dict[key].append(item)
    else:
        dict[key] = [item]


# Tabulate results neatly
#
def printresults(table):
    modules = sorted(table.keys())
    maxlen = 0
    for mod in modules: maxlen = max(maxlen, len(mod))
    for mod in modules:
        list = sorted(table[mod])
        print(mod.ljust(maxlen), ':', end=' ')
        if mod in list:
            print('(*)', end=' ')
        for ref in list:
            print(ref, end=' ')
        print()


# Call main and honor exit status
if __name__ == '__main__':
    try:
        sys.exit(main())
    except KeyboardInterrupt:
        sys.exit(1)
