package: add spack.package.possible_dependencies method
- this version allows getting possible dependencies of multiple packages or specs at once. - New method handles calling `PackageBase.possible_dependencies` multiple times and passing `visited` dict around.
This commit is contained in:
		@@ -2663,6 +2663,34 @@ def dump_packages(spec, path):
 | 
				
			|||||||
            spack.repo.path.dump_provenance(node, dest_pkg_dir)
 | 
					            spack.repo.path.dump_provenance(node, dest_pkg_dir)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def possible_dependencies(*pkg_or_spec, **kwargs):
 | 
				
			||||||
 | 
					    """Get the possible dependencies of a number of packages.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    See ``PackageBase.possible_dependencies`` for details.
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    transitive = kwargs.get('transitive', True)
 | 
				
			||||||
 | 
					    expand_virtuals = kwargs.get('expand_virtuals', True)
 | 
				
			||||||
 | 
					    deptype = kwargs.get('deptype', 'all')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    packages = []
 | 
				
			||||||
 | 
					    for pos in pkg_or_spec:
 | 
				
			||||||
 | 
					        if isinstance(pos, PackageMeta):
 | 
				
			||||||
 | 
					            pkg = pos
 | 
				
			||||||
 | 
					        elif isinstance(pos, spack.spec.Spec):
 | 
				
			||||||
 | 
					            pkg = pos.package
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            pkg = spack.spec.Spec(pos).package
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        packages.append(pkg)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    visited = {}
 | 
				
			||||||
 | 
					    for pkg in packages:
 | 
				
			||||||
 | 
					        pkg.possible_dependencies(
 | 
				
			||||||
 | 
					            transitive, expand_virtuals, deptype, visited)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return visited
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def print_pkg(message):
 | 
					def print_pkg(message):
 | 
				
			||||||
    """Outputs a message with a package icon."""
 | 
					    """Outputs a message with a package icon."""
 | 
				
			||||||
    from llnl.util.tty.color import cwrite
 | 
					    from llnl.util.tty.color import cwrite
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,14 +10,14 @@
 | 
				
			|||||||
static DSL metadata for packages.
 | 
					static DSL metadata for packages.
 | 
				
			||||||
"""
 | 
					"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import pytest
 | 
				
			||||||
import spack.repo
 | 
					import spack.repo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_possible_dependencies(mock_packages):
 | 
					@pytest.fixture
 | 
				
			||||||
    mpileaks = spack.repo.get('mpileaks')
 | 
					def mpileaks_possible_deps(mock_packages):
 | 
				
			||||||
    mpi_names = [spec.name for spec in spack.repo.path.providers_for('mpi')]
 | 
					    mpi_names = [spec.name for spec in spack.repo.path.providers_for('mpi')]
 | 
				
			||||||
 | 
					    possible = {
 | 
				
			||||||
    assert mpileaks.possible_dependencies(expand_virtuals=True) == {
 | 
					 | 
				
			||||||
        'callpath': set(['dyninst'] + mpi_names),
 | 
					        'callpath': set(['dyninst'] + mpi_names),
 | 
				
			||||||
        'dyninst': set(['libdwarf', 'libelf']),
 | 
					        'dyninst': set(['libdwarf', 'libelf']),
 | 
				
			||||||
        'fake': set(),
 | 
					        'fake': set(),
 | 
				
			||||||
@@ -29,6 +29,13 @@ def test_possible_dependencies(mock_packages):
 | 
				
			|||||||
        'multi-provider-mpi': set(),
 | 
					        'multi-provider-mpi': set(),
 | 
				
			||||||
        'zmpi': set(['fake']),
 | 
					        'zmpi': set(['fake']),
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    return possible
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_possible_dependencies(mock_packages, mpileaks_possible_deps):
 | 
				
			||||||
 | 
					    mpileaks = spack.repo.get('mpileaks')
 | 
				
			||||||
 | 
					    assert (mpileaks.possible_dependencies(expand_virtuals=True) ==
 | 
				
			||||||
 | 
					            mpileaks_possible_deps)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    assert mpileaks.possible_dependencies(expand_virtuals=False) == {
 | 
					    assert mpileaks.possible_dependencies(expand_virtuals=False) == {
 | 
				
			||||||
        'callpath': set(['dyninst']),
 | 
					        'callpath': set(['dyninst']),
 | 
				
			||||||
@@ -59,3 +66,17 @@ def test_possible_dependencies_with_deptypes(mock_packages):
 | 
				
			|||||||
        'dtbuild1': set(['dtlink2']),
 | 
					        'dtbuild1': set(['dtlink2']),
 | 
				
			||||||
        'dtlink2': set(),
 | 
					        'dtlink2': set(),
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_possible_dependencies_with_multiple_classes(
 | 
				
			||||||
 | 
					        mock_packages, mpileaks_possible_deps):
 | 
				
			||||||
 | 
					    pkgs = ['dt-diamond', 'mpileaks']
 | 
				
			||||||
 | 
					    expected = mpileaks_possible_deps.copy()
 | 
				
			||||||
 | 
					    expected.update({
 | 
				
			||||||
 | 
					        'dt-diamond': set(['dt-diamond-left', 'dt-diamond-right']),
 | 
				
			||||||
 | 
					        'dt-diamond-left': set(['dt-diamond-bottom']),
 | 
				
			||||||
 | 
					        'dt-diamond-right': set(['dt-diamond-bottom']),
 | 
				
			||||||
 | 
					        'dt-diamond-bottom': set(),
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assert spack.package.possible_dependencies(*pkgs) == expected
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user