diff options
author | Todd Gamblin <tgamblin@llnl.gov> | 2018-03-12 17:26:58 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-03-12 17:26:58 +0900 |
commit | b4a9e37a98c1adbb0cf757523b267213aa6fce95 (patch) | |
tree | 79fa8b2da657d06c0d78344136396bc458beacb8 | |
parent | a1c8ce82f2ac46278a5716fa92d4d06df6f49caf (diff) | |
download | spack-b4a9e37a98c1adbb0cf757523b267213aa6fce95.tar.gz spack-b4a9e37a98c1adbb0cf757523b267213aa6fce95.tar.bz2 spack-b4a9e37a98c1adbb0cf757523b267213aa6fce95.tar.xz spack-b4a9e37a98c1adbb0cf757523b267213aa6fce95.zip |
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
-rw-r--r-- | lib/spack/spack/cmd/dependencies.py | 8 | ||||
-rw-r--r-- | lib/spack/spack/graph.py | 4 | ||||
-rw-r--r-- | lib/spack/spack/package.py | 43 |
3 files changed, 35 insertions, 20 deletions
diff --git a/lib/spack/spack/cmd/dependencies.py b/lib/spack/spack/cmd/dependencies.py index 95183fa318..e0b62c3a53 100644 --- a/lib/spack/spack/cmd/dependencies.py +++ b/lib/spack/spack/cmd/dependencies.py @@ -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) diff --git a/lib/spack/spack/graph.py b/lib/spack/spack/graph.py index 896bf15e36..bfc0ab1591 100644 --- a/lib/spack/spack/graph.py +++ b/lib/spack/spack/graph.py @@ -543,7 +543,9 @@ def graph_dot(specs, deptype='all', static=False, out=None): # 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() diff --git a/lib/spack/spack/package.py b/lib/spack/spack/package.py index 846ecac448..e2877ac72a 100644 --- a/lib/spack/spack/package.py +++ b/lib/spack/spack/package.py @@ -627,31 +627,40 @@ class PackageBase(with_metaclass(PackageMeta, object)): 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.add(self.name) - for name in self.dependencies: - spec = spack.spec.Spec(name) + visited = set([self.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 |