Make graph_ascii support deptypes.

- fix deptype support
- by default, graph command omits build depedencies
- update docs to use deptype args
This commit is contained in:
Todd Gamblin 2016-09-27 23:32:18 -04:00
parent f082d26ddd
commit 05d52752ff
6 changed files with 37 additions and 27 deletions

1
.gitignore vendored
View file

@ -1,3 +1,4 @@
/db
/var/spack/stage
/var/spack/cache
/var/spack/repos/*/index.yaml

View file

@ -207,7 +207,7 @@ supply ``-p`` to Spack on the command line, before any subcommands.
``spack --profile`` output looks like this:
.. command-output:: spack --profile graph dyninst
.. command-output:: spack --profile graph --deptype=nobuild dyninst
:ellipsis: 25
The bottom of the output shows the top most time consuming functions,

View file

@ -2888,9 +2888,22 @@ dependency graph. For example:
.. command-output:: spack graph mpileaks
At the top is the root package in the DAG, with dependency edges
emerging from it. On a color terminal, the edges are colored by which
dependency they lead to.
At the top is the root package in the DAG, with dependency edges emerging
from it. On a color terminal, the edges are colored by which dependency
they lead to.
.. command-output:: spack graph --deptype=all mpileaks
The ``deptype`` argument tells Spack what types of dependencies to graph.
By default it includes link and run dependencies but not build
dependencies. Supplying ``--deptype=all`` will show the build
dependencies as well. This is equivalent to
``--deptype=build,link,run``. Options for ``deptype`` include:
* Any combination of ``build``, ``link``, and ``run`` separated by
commas.
* ``nobuild``, ``nolink``, ``norun`` to omit one type.
* ``all`` or ``alldeps`` for all types of dependencies.
You can also use ``spack graph`` to generate graphs in the widely used
`Dot <http://www.graphviz.org/doc/info/lang.html>`_ format. For

View file

@ -83,7 +83,7 @@ def graph(parser, args):
setup_parser.parser.print_help()
return 1
deptype = alldeps
deptype = nobuild
if args.deptype:
deptype = tuple(args.deptype.split(','))
validate_deptype(deptype)
@ -93,7 +93,7 @@ def graph(parser, args):
graph_dot(specs, static=args.static, deptype=deptype)
elif specs: # ascii is default: user doesn't need to provide it explicitly
graph_ascii(specs[0], debug=spack.debug)
graph_ascii(specs[0], debug=spack.debug, deptype=deptype)
for spec in specs[1:]:
print # extra line bt/w independent graphs
graph_ascii(spec, debug=spack.debug)

View file

@ -72,16 +72,15 @@
__all__ = ['topological_sort', 'graph_ascii', 'AsciiGraph', 'graph_dot']
def topological_sort(spec, **kwargs):
def topological_sort(spec, reverse=False, deptype=None):
"""Topological sort for specs.
Return a list of dependency specs sorted topologically. The spec
argument is not modified in the process.
"""
reverse = kwargs.get('reverse', False)
# XXX(deptype): iterate over a certain kind of dependency. Maybe color
# edges based on the type of dependency?
deptype = canonical_deptype(deptype)
if not reverse:
parents = lambda s: s.dependents()
children = lambda s: s.dependencies()
@ -90,7 +89,7 @@ def topological_sort(spec, **kwargs):
children = lambda s: s.dependents()
# Work on a copy so this is nondestructive.
spec = spec.copy()
spec = spec.copy(deps=deptype)
nodes = spec.index()
topo_order = []
@ -142,6 +141,7 @@ def __init__(self):
self.node_character = '*'
self.debug = False
self.indent = 0
self.deptype = alldeps
# These are colors in the order they'll be used for edges.
# See llnl.util.tty.color for details on color characters.
@ -388,7 +388,7 @@ def write(self, spec, **kwargs):
self._out = ColorStream(sys.stdout, color=color)
# We'll traverse the spec in topo order as we graph it.
topo_order = topological_sort(spec, reverse=True)
topo_order = topological_sort(spec, reverse=True, deptype=self.deptype)
# Work on a copy to be nondestructive
spec = spec.copy()
@ -484,27 +484,23 @@ def write(self, spec, **kwargs):
# Replace node with its dependencies
self._frontier.pop(i)
if node.dependencies():
deps = sorted((d.name for d in node.dependencies()),
reverse=True)
deps = node.dependencies(self.deptype)
if deps:
deps = sorted((d.name for d in deps), reverse=True)
self._connect_deps(i, deps, "new-deps") # anywhere.
elif self._frontier:
self._collapse_line(i)
def graph_ascii(spec, **kwargs):
node_character = kwargs.get('node', 'o')
out = kwargs.pop('out', None)
debug = kwargs.pop('debug', False)
indent = kwargs.pop('indent', 0)
color = kwargs.pop('color', None)
check_kwargs(kwargs, graph_ascii)
def graph_ascii(spec, node='o', out=None, debug=False,
indent=0, color=None, deptype=None):
graph = AsciiGraph()
graph.debug = debug
graph.indent = indent
graph.node_character = node_character
graph.node_character = node
if deptype:
graph.deptype = canonical_deptype(deptype)
graph.write(spec, color=color, out=out)

View file

@ -194,6 +194,7 @@
norun = ('link', 'build')
special_types = {
'alldeps': alldeps,
'all': alldeps, # allow "all" as string but not symbol.
'nolink': nolink,
'nobuild': nobuild,
'norun': norun,
@ -1418,12 +1419,11 @@ def flat_dependencies_with_deptype(self, **kwargs):
# parser doesn't allow it. Spack must be broken!
raise InconsistentSpecError("Invalid Spec DAG: %s" % e.message)
def index(self):
def index(self, deptype=None):
"""Return DependencyMap that points to all the dependencies in this
spec."""
dm = DependencyMap()
# XXX(deptype): use a deptype kwarg.
for spec in self.traverse():
for spec in self.traverse(deptype=deptype):
dm[spec.name] = spec
return dm