diff options
author | Todd Gamblin <tgamblin@llnl.gov> | 2019-12-02 01:01:11 -0800 |
---|---|---|
committer | Todd Gamblin <tgamblin@llnl.gov> | 2019-12-18 21:10:31 -0800 |
commit | 531f370e0d3256202e1eb40dce669e8ae2ebb15a (patch) | |
tree | 160cf29072d9da92792fbf3ca0499f33908f7d56 /lib | |
parent | 81b147cc0af9205061b4197b682b3058ce185c08 (diff) | |
download | spack-531f370e0d3256202e1eb40dce669e8ae2ebb15a.tar.gz spack-531f370e0d3256202e1eb40dce669e8ae2ebb15a.tar.bz2 spack-531f370e0d3256202e1eb40dce669e8ae2ebb15a.tar.xz spack-531f370e0d3256202e1eb40dce669e8ae2ebb15a.zip |
possible_dependencies() now reports missing dependencies
- Add an optional argument so that `possible_dependencies()` will report
missing dependencies.
- Add a test to ensure it works.
- Ignore missing dependencies in `possible_dependencies()` by default.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/spack/spack/package.py | 54 | ||||
-rw-r--r-- | lib/spack/spack/test/package_class.py | 9 |
2 files changed, 48 insertions, 15 deletions
diff --git a/lib/spack/spack/package.py b/lib/spack/spack/package.py index c6dc39954c..5128a1e17f 100644 --- a/lib/spack/spack/package.py +++ b/lib/spack/spack/package.py @@ -556,16 +556,19 @@ class PackageBase(with_metaclass(PackageMeta, PackageViewMixin, object)): @classmethod def possible_dependencies( cls, transitive=True, expand_virtuals=True, deptype='all', - visited=None): + visited=None, missing=None): """Return dict of possible dependencies of this package. Args: - transitive (bool): return all transitive dependencies if True, - only direct dependencies if False. - expand_virtuals (bool): expand virtual dependencies into all - possible implementations. - deptype (str or tuple): dependency types to consider - visited (set): set of names of dependencies visited so far. + transitive (bool, optional): return all transitive dependencies if + True, only direct dependencies if False (default True).. + expand_virtuals (bool, optional): expand virtual dependencies into + all possible implementations (default True) + deptype (str or tuple, optional): dependency types to consider + visited (dicct, optional): dict of names of dependencies visited so + far, mapped to their immediate dependencies' names. + missing (dict, optional): dict to populate with packages and their + *missing* dependencies. Returns: (dict): dictionary mapping dependency names to *their* @@ -576,7 +579,12 @@ class PackageBase(with_metaclass(PackageMeta, PackageViewMixin, object)): *immediate* dependencies. If ``expand_virtuals`` is ``False``, virtual package names wil be inserted as keys mapped to empty sets of dependencies. Virtuals, if not expanded, are treated as - though they have no immediate dependencies + though they have no immediate dependencies. + + Missing dependencies by default are ignored, but if a + missing dict is provided, it will be populated with package names + mapped to any dependencies they have that are in no + repositories. This is only populated if transitive is True. Note: the returned dict *includes* the package itself. @@ -586,6 +594,9 @@ class PackageBase(with_metaclass(PackageMeta, PackageViewMixin, object)): if visited is None: visited = {cls.name: set()} + if missing is None: + missing = {cls.name: set()} + for name, conditions in cls.dependencies.items(): # check whether this dependency could be of the type asked for types = [dep.type for cond, dep in conditions.items()] @@ -609,12 +620,24 @@ class PackageBase(with_metaclass(PackageMeta, PackageViewMixin, object)): # recursively traverse dependencies for dep_name in dep_names: - if dep_name not in visited: - visited.setdefault(dep_name, set()) - if transitive: - dep_cls = spack.repo.path.get_pkg_class(dep_name) - dep_cls.possible_dependencies( - transitive, expand_virtuals, deptype, visited) + if dep_name in visited: + continue + + visited.setdefault(dep_name, set()) + + # skip the rest if not transitive + if not transitive: + continue + + try: + dep_cls = spack.repo.path.get_pkg_class(dep_name) + except spack.repo.UnknownPackageError: + # log unknown packages + missing.setdefault(cls.name, set()).add(dep_name) + continue + + dep_cls.possible_dependencies( + transitive, expand_virtuals, deptype, visited, missing) return visited @@ -2671,6 +2694,7 @@ def possible_dependencies(*pkg_or_spec, **kwargs): transitive = kwargs.get('transitive', True) expand_virtuals = kwargs.get('expand_virtuals', True) deptype = kwargs.get('deptype', 'all') + missing = kwargs.get('missing') packages = [] for pos in pkg_or_spec: @@ -2686,7 +2710,7 @@ def possible_dependencies(*pkg_or_spec, **kwargs): visited = {} for pkg in packages: pkg.possible_dependencies( - transitive, expand_virtuals, deptype, visited) + transitive, expand_virtuals, deptype, visited, missing) return visited diff --git a/lib/spack/spack/test/package_class.py b/lib/spack/spack/test/package_class.py index 521bd9d54a..25c9258759 100644 --- a/lib/spack/spack/test/package_class.py +++ b/lib/spack/spack/test/package_class.py @@ -47,6 +47,15 @@ def test_possible_dependencies(mock_packages, mpileaks_possible_deps): } +def test_possible_dependencies_missing(mock_packages): + md = spack.repo.get("missing-dependency") + missing = {} + md.possible_dependencies(transitive=True, missing=missing) + assert missing["missing-dependency"] == set([ + "this-is-a-missing-dependency" + ]) + + def test_possible_dependencies_with_deptypes(mock_packages): dtbuild1 = spack.repo.get('dtbuild1') |