#!/usr/bin/python

# Usage (the graphviz package must be installed in your distribution)
#  ./scripts/graph-depends [package-name] > test.dot
#  dot -Tpdf test.dot -o test.pdf
#
# With no arguments, graph-depends will draw a complete graph of
# dependencies for the current configuration. With an argument,
# graph-depends will draw a graph of dependencies for the given
# package name.
#
# Limitations
#
#  * Some packages have dependencies that depend on the Buildroot
#    configuration. For example, many packages have a dependency on
#    openssl if openssl has been enabled. This tool will graph the
#    dependencies as they are with the current Buildroot
#    configuration.
#
#  * The X.org package definitions are only included when
#    BR2_PACKAGE_XORG7 is enabled, so if this option is not enabled,
#    it isn't possible to graph the dependencies of X.org stack
#    components.
#
# Copyright (C) 2010 Thomas Petazzoni <thomas.petazzoni@free-electrons.com>

import sys
import subprocess

# In FULL_MODE, we draw the full dependency graph for all selected
# packages
FULL_MODE = 1

# In PKG_MODE, we only draw the dependency graph for a given package
PKG_MODE  = 2

mode = 0

if len(sys.argv) == 1:
    mode = FULL_MODE
elif len(sys.argv) == 2:
    mode = PKG_MODE
    rootpkg  = sys.argv[1]
else:
    print "Usage: graph-depends [package-name]"
    sys.exit(1)

allpkgs = []
unknownpkgs = []

# Execute the "make show-targets" command to get the list of the main
# Buildroot TARGETS and return it formatted as a Python list. This
# list is used as the starting point for full dependency graphs
def get_targets():
    sys.stderr.write("Getting targets\n")
    cmd = ["make", "-s", "show-targets"]
    p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    output = p.communicate()[0].strip()
    if p.returncode != 0:
        return None
    if output == '':
        return []
    return output.split(' ')

# Execute the "make <pkg>-show-depends" command to get the list of
# dependencies of a given package, and return the list of dependencies
# formatted as a Python list.
def get_depends(pkg):
    sys.stderr.write("Getting dependencies for %s\n" % pkg)
    cmd = ["make", "-s", "%s-show-depends" % pkg]
    p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    output = p.communicate()[0].strip()
    if p.returncode != 0:
        return None
    if output == '':
        return []
    return output.split(' ')

# Recursive function that builds the tree of dependencies for a given
# package. The dependencies are built in a list called 'dependencies',
# which contains tuples of the form (pkg1 ->
# pkg2_on_which_pkg1_depends) and the function finally returns this
# list.
def get_all_depends(pkg):
    dependencies = []

    # We already have the dependencies for this package
    if pkg in allpkgs:
        return
    allpkgs.append(pkg)
    depends = get_depends(pkg)

    # We couldn't get the dependencies of this package, because it
    # doesn't use the generic or autotools infrastructure. Add it to
    # unknownpkgs so that it is later rendered in red color to warn
    # the user.
    if depends == None:
        unknownpkgs.append(pkg)
        return

    # This package has no dependency.
    if depends == []:
        return

    # Add dependencies to the list of dependencies
    for dep in depends:
        dependencies.append((pkg, dep))

    # Recurse into the dependencies
    for dep in depends:
        newdeps = get_all_depends(dep)
        if newdeps != None:
            dependencies += newdeps

    return dependencies

# The Graphviz "dot" utility doesn't like dashes in node names. So for
# node names, we strip all dashes.
def pkg_node_name(pkg):
    return pkg.replace("-","")

# In full mode, start with the result of get_targets() to get the main
# targets and then use get_all_depends() for each individual target.
if mode == FULL_MODE:
    targets = get_targets()
    dependencies = []
    allpkgs.append('all')
    for tg in targets:
        # Skip uninteresting targets
        if tg == 'target-generic-issue' or \
                tg == 'target-generic-getty-busybox' or \
                tg == 'target-generic-do-remount-rw' or \
                tg == 'target-finalize' or \
                tg == 'erase-fakeroots' or \
                tg == 'target-generic-hostname':
            continue
        dependencies.append(('all', tg))
        deps = get_all_depends(tg)
        if deps != None:
            dependencies += deps

# In pkg mode, start directly with get_all_depends() on the requested
# package
elif mode == PKG_MODE:
    dependencies = get_all_depends(rootpkg)

# Start printing the graph data
print "digraph G {"

# First, the dependencies. Usage of set allows to remove duplicated
# dependencies in the graph
for dep in set(dependencies):
    print "%s -> %s" % (pkg_node_name(dep[0]), pkg_node_name(dep[1]))

# Then, the node attributes: color, style and label.
for pkg in allpkgs:
    if pkg == 'all':
        print "all [label = \"ALL\"]"
        print "all [color=lightblue,style=filled]"
        continue

    print "%s [label = \"%s\"]" % (pkg_node_name(pkg), pkg)

    if pkg in unknownpkgs:
        print "%s [color=red,style=filled]" % pkg_node_name(pkg)
    elif mode == PKG_MODE and pkg == rootpkg:
        print "%s [color=lightblue,style=filled]" % pkg_node_name(rootpkg)
    else:
        print "%s [color=grey,style=filled]" % pkg_node_name(pkg)

print "}"
