summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorTodd Gamblin <tgamblin@llnl.gov>2014-12-26 13:52:31 -0800
committerTodd Gamblin <tgamblin@llnl.gov>2014-12-26 13:52:49 -0800
commit860f834aad0d6503057693b894d9996143dde312 (patch)
tree6c9b5d65e5d495d42942ec2a687f27b248a8ca7c /lib
parent9dabcc870385de329b9fcb6986d5d6688fa7dca8 (diff)
downloadspack-860f834aad0d6503057693b894d9996143dde312.tar.gz
spack-860f834aad0d6503057693b894d9996143dde312.tar.bz2
spack-860f834aad0d6503057693b894d9996143dde312.tar.xz
spack-860f834aad0d6503057693b894d9996143dde312.zip
spack graph allows plotting specific packages.
Diffstat (limited to 'lib')
-rw-r--r--lib/spack/llnl/util/lang.py22
-rw-r--r--lib/spack/spack/cmd/graph.py11
-rw-r--r--lib/spack/spack/packages.py16
-rw-r--r--lib/spack/spack/spec.py17
4 files changed, 54 insertions, 12 deletions
diff --git a/lib/spack/llnl/util/lang.py b/lib/spack/llnl/util/lang.py
index 049d158c6d..db15da0506 100644
--- a/lib/spack/llnl/util/lang.py
+++ b/lib/spack/llnl/util/lang.py
@@ -269,6 +269,28 @@ def in_function(function_name):
del stack
+def check_kwargs(kwargs, fun):
+ """Helper for making functions with kwargs. Checks whether the kwargs
+ are empty after all of them have been popped off. If they're
+ not, raises an error describing which kwargs are invalid.
+
+ Example::
+
+ def foo(self, **kwargs):
+ x = kwargs.pop('x', None)
+ y = kwargs.pop('y', None)
+ z = kwargs.pop('z', None)
+ check_kwargs(kwargs, self.foo)
+
+ # This raises a TypeError:
+ foo(w='bad kwarg')
+ """
+ if kwargs:
+ raise TypeError(
+ "'%s' is an invalid keyword argument for function %s()."
+ % (next(kwargs.iterkeys()), fun.__name__))
+
+
class RequiredAttributeError(ValueError):
def __init__(self, message):
super(RequiredAttributeError, self).__init__(message)
diff --git a/lib/spack/spack/cmd/graph.py b/lib/spack/spack/cmd/graph.py
index 39dbfbb150..955be51955 100644
--- a/lib/spack/spack/cmd/graph.py
+++ b/lib/spack/spack/cmd/graph.py
@@ -22,9 +22,18 @@
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
+from external import argparse
import spack
+import spack.cmd
description = "Write out inter-package dependencies in dot graph format"
+def setup_parser(subparser):
+ subparser.add_argument(
+ 'specs', nargs=argparse.REMAINDER,
+ help="specs of packages to graph. Default is all packages.")
+
+
def graph(parser, args):
- spack.db.graph_dependencies()
+ specs = spack.cmd.parse_specs(args.specs)
+ spack.db.graph_dependencies(*specs)
diff --git a/lib/spack/spack/packages.py b/lib/spack/spack/packages.py
index 25d01fe7eb..0aa8090b61 100644
--- a/lib/spack/spack/packages.py
+++ b/lib/spack/spack/packages.py
@@ -30,7 +30,7 @@ import imp
import llnl.util.tty as tty
from llnl.util.filesystem import join_path
-from llnl.util.lang import memoized
+from llnl.util.lang import *
import spack.error
import spack.spec
@@ -214,9 +214,12 @@ class PackageDB(object):
return cls
- def graph_dependencies(self, out=sys.stdout):
+ def graph_dependencies(self, *specs, **kwargs):
"""Print out a graph of all the dependencies between package.
Graph is in dot format."""
+ out = kwargs.pop('out', sys.stdout)
+ check_kwargs(kwargs, self.graph_dependencies)
+
out.write('digraph G {\n')
out.write(' label = "Spack Dependencies"\n')
out.write(' labelloc = "b"\n')
@@ -227,8 +230,15 @@ class PackageDB(object):
def quote(string):
return '"%s"' % string
+ if not specs:
+ packages = self.all_packages()
+ else:
+ packages = []
+ for spec in specs:
+ packages.extend(s.package for s in spec.normalized().traverse())
+
deps = []
- for pkg in self.all_packages():
+ for pkg in packages:
out.write(' %-30s [label="%s"]\n' % (quote(pkg.name), pkg.name))
# Add edges for each depends_on in the package.
diff --git a/lib/spack/spack/spec.py b/lib/spack/spack/spec.py
index 570bb1191c..5f1385cc1b 100644
--- a/lib/spack/spack/spec.py
+++ b/lib/spack/spack/spec.py
@@ -858,7 +858,7 @@ class Spec(object):
def normalized(self):
"""Return a normalized copy of this spec without modifying this spec."""
clone = self.copy()
- clone.normalized()
+ clone.normalize()
return clone
@@ -1289,12 +1289,13 @@ class Spec(object):
def tree(self, **kwargs):
"""Prints out this spec and its dependencies, tree-formatted
with indentation."""
- color = kwargs.get('color', False)
- depth = kwargs.get('depth', False)
- showid = kwargs.get('ids', False)
- cover = kwargs.get('cover', 'nodes')
- indent = kwargs.get('indent', 0)
- format = kwargs.get('format', '$_$@$%@$+$=')
+ color = kwargs.pop('color', False)
+ depth = kwargs.pop('depth', False)
+ showid = kwargs.pop('ids', False)
+ cover = kwargs.pop('cover', 'nodes')
+ indent = kwargs.pop('indent', 0)
+ fmt = kwargs.pop('format', '$_$@$%@$+$=')
+ check_kwargs(kwargs, self.tree)
out = ""
cur_id = 0
@@ -1311,7 +1312,7 @@ class Spec(object):
out += (" " * d)
if d > 0:
out += "^"
- out += node.format(format, color=color) + "\n"
+ out += node.format(fmt, color=color) + "\n"
return out