summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd Gamblin <tgamblin@llnl.gov>2018-03-12 17:26:58 +0900
committerGitHub <noreply@github.com>2018-03-12 17:26:58 +0900
commitb4a9e37a98c1adbb0cf757523b267213aa6fce95 (patch)
tree79fa8b2da657d06c0d78344136396bc458beacb8
parenta1c8ce82f2ac46278a5716fa92d4d06df6f49caf (diff)
downloadspack-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.py8
-rw-r--r--lib/spack/spack/graph.py4
-rw-r--r--lib/spack/spack/package.py43
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