From f2ddcfac5f526c331185fb92fe9ce6dd85494c74 Mon Sep 17 00:00:00 2001 From: Todd Gamblin Date: Mon, 12 Jun 2017 01:07:29 -0700 Subject: [PATCH] Add --all argument to `spack dependents` --all causes spack dependents to list all possible dependents for a package, rather than actual dependents for an installed spec. --- lib/spack/spack/cmd/dependents.py | 62 ++++++++++++++++++++++++++++--- 1 file changed, 56 insertions(+), 6 deletions(-) diff --git a/lib/spack/spack/cmd/dependents.py b/lib/spack/spack/cmd/dependents.py index e8f8fc0d0b..94b9ffd9c5 100644 --- a/lib/spack/spack/cmd/dependents.py +++ b/lib/spack/spack/cmd/dependents.py @@ -25,6 +25,7 @@ import argparse import llnl.util.tty as tty +from llnl.util.tty.colify import colify import spack import spack.store @@ -36,20 +37,69 @@ def setup_parser(subparser): + subparser.add_argument( + '-a', '--all', action='store_true', default=False, + help="List all potential dependents of the package instead of actual " + "dependents of an installed spec") subparser.add_argument( 'spec', nargs=argparse.REMAINDER, help="specs to list dependencies of") +def inverted_dag(): + """Returns inverted package DAG as adjacency lists.""" + dag = {} + for pkg in spack.repo.all_packages(): + dag.setdefault(pkg.name, set()) + for dep in pkg.dependencies: + deps = [dep] + + # expand virtuals if necessary + if spack.repo.is_virtual(dep): + deps = [s.name for s in spack.repo.providers_for(dep)] + + for d in deps: + dag.setdefault(d, set()).add(pkg.name) + return dag + + +def all_dependents(name, inverted_dag, dependents=None): + if dependents is None: + dependents = set() + + if name in dependents: + return set() + dependents.add(name) + + direct = inverted_dag[name] + for dname in direct: + all_dependents(dname, inverted_dag, dependents) + dependents.update(direct) + return dependents + + def dependents(parser, args): specs = spack.cmd.parse_specs(args.spec) if len(specs) != 1: tty.die("spack dependents takes only one spec.") - spec = spack.cmd.disambiguate_spec(specs[0]) - tty.msg("Dependents of %s" % spec.cformat('$_$@$%@$/')) - deps = spack.store.db.installed_dependents(spec) - if deps: - spack.cmd.display_specs(deps) + if args.all: + spec = specs[0] + idag = inverted_dag() + + dependents = all_dependents(spec.name, idag) + dependents.remove(spec.name) + if dependents: + colify(sorted(dependents)) + else: + print("No dependents") + else: - print("No dependents") + spec = spack.cmd.disambiguate_spec(specs[0]) + + tty.msg("Dependents of %s" % spec.cformat('$_$@$%@$/')) + deps = spack.store.db.installed_dependents(spec) + if deps: + spack.cmd.display_specs(deps) + else: + print("No dependents")