Fix bugs in spack dependencies command (#7435)

- transitive dependencies were not being handled correctly

- restructure code to do recursion and mark visited packages properly

- add `-V` option to *not* expand virtuals in spack dependencies
This commit is contained in:
Todd Gamblin 2018-03-12 17:26:58 +09:00 committed by GitHub
parent a1c8ce82f2
commit b4a9e37a98
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 35 additions and 20 deletions

View File

@ -43,7 +43,10 @@ def setup_parser(subparser):
"instead of possible dependencies of a package.")
subparser.add_argument(
'-t', '--transitive', action='store_true', default=False,
help="Show all transitive dependencies.")
help="show all transitive dependencies")
subparser.add_argument(
'-V', '--no-expand-virtuals', action='store_false', default=True,
dest="expand_virtuals", help="do not expand virtual dependencies")
subparser.add_argument(
'spec', nargs=argparse.REMAINDER, help="spec or package name")
@ -76,7 +79,8 @@ def dependencies(parser, args):
dependencies = set()
for pkg in packages:
dependencies.update(
set(pkg.possible_dependencies(args.transitive)))
set(pkg.possible_dependencies(
args.transitive, args.expand_virtuals)))
if spec.name in dependencies:
dependencies.remove(spec.name)

View File

@ -543,7 +543,9 @@ def q(string):
# Static graph includes anything a package COULD depend on.
if static:
names = set.union(*[s.package.possible_dependencies() for s in specs])
names = set.union(*[
s.package.possible_dependencies(expand_virtuals=False)
for s in specs])
specs = [Spec(name) for name in names]
labeled = set()

View File

@ -627,31 +627,40 @@ def __init__(self, spec):
super(PackageBase, self).__init__()
def possible_dependencies(self, transitive=True, visited=None):
"""Return set of possible transitive dependencies of this package.
def possible_dependencies(
self, transitive=True, expand_virtuals=True, visited=None):
"""Return set of possible dependencies of this package.
Note: the set returned *includes* the package itself.
Args:
transitive (bool): include all transitive dependencies if True,
transitive (bool): return all transitive dependencies if True,
only direct dependencies if False.
expand_virtuals (bool): expand virtual dependencies into all
possible implementations.
visited (set): set of names of dependencies visited so far.
"""
if visited is None:
visited = set()
visited = set([self.name])
visited.add(self.name)
for name in self.dependencies:
spec = spack.spec.Spec(name)
if not spec.virtual:
visited.add(name)
if transitive:
pkg = spack.repo.get(name)
pkg.possible_dependencies(transitive, visited)
for i, name in enumerate(self.dependencies):
if spack.repo.is_virtual(name):
if expand_virtuals:
providers = spack.repo.providers_for(name)
dep_names = [spec.name for spec in providers]
else:
visited.add(name)
continue
else:
for provider in spack.repo.providers_for(spec):
visited.add(provider.name)
dep_names = [name]
for dep_name in dep_names:
if dep_name not in visited:
visited.add(dep_name)
if transitive:
pkg = spack.repo.get(provider.name)
pkg.possible_dependencies(transitive, visited)
pkg = spack.repo.get(dep_name)
pkg.possible_dependencies(
transitive, expand_virtuals, visited)
return visited