spack dependencies: support --deptype argument
- `spack dependencies` can now take a --deptype argument to only traverse particular deptypes - add a new "common" argument for deptype in spack.cmd.common.arguments - Database.installed_relatives() can now also take a deptype argument - this is used by `spack dependencies --installed`
This commit is contained in:
parent
3dac78fc19
commit
2e22fc1090
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
import spack.cmd
|
import spack.cmd
|
||||||
import spack.config
|
import spack.config
|
||||||
|
import spack.dependency as dep
|
||||||
import spack.environment as ev
|
import spack.environment as ev
|
||||||
import spack.modules
|
import spack.modules
|
||||||
import spack.spec
|
import spack.spec
|
||||||
@ -104,6 +105,19 @@ def default(self, value):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class DeptypeAction(argparse.Action):
|
||||||
|
"""Creates a tuple of valid dependency tpyes from a deptype argument."""
|
||||||
|
def __call__(self, parser, namespace, values, option_string=None):
|
||||||
|
deptype = dep.all_deptypes
|
||||||
|
if values:
|
||||||
|
deptype = tuple(x.strip() for x in values.split(','))
|
||||||
|
if deptype == ('all',):
|
||||||
|
deptype = 'all'
|
||||||
|
deptype = dep.canonical_deptype(deptype)
|
||||||
|
|
||||||
|
setattr(namespace, self.dest, deptype)
|
||||||
|
|
||||||
|
|
||||||
_arguments['constraint'] = Args(
|
_arguments['constraint'] = Args(
|
||||||
'constraint', nargs=argparse.REMAINDER, action=ConstraintAction,
|
'constraint', nargs=argparse.REMAINDER, action=ConstraintAction,
|
||||||
help='constraint to select a subset of installed packages')
|
help='constraint to select a subset of installed packages')
|
||||||
@ -128,6 +142,11 @@ def default(self, value):
|
|||||||
dest='dirty',
|
dest='dirty',
|
||||||
help='unset harmful variables in the build environment (default)')
|
help='unset harmful variables in the build environment (default)')
|
||||||
|
|
||||||
|
_arguments['deptype'] = Args(
|
||||||
|
'--deptype', action=DeptypeAction, default=dep.all_deptypes,
|
||||||
|
help="comma-separated list of deptypes to traverse\ndefault=%s"
|
||||||
|
% ','.join(dep.all_deptypes))
|
||||||
|
|
||||||
_arguments['dirty'] = Args(
|
_arguments['dirty'] = Args(
|
||||||
'--dirty',
|
'--dirty',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
|
@ -8,10 +8,11 @@
|
|||||||
import llnl.util.tty as tty
|
import llnl.util.tty as tty
|
||||||
from llnl.util.tty.colify import colify
|
from llnl.util.tty.colify import colify
|
||||||
|
|
||||||
import spack.environment as ev
|
|
||||||
import spack.store
|
|
||||||
import spack.repo
|
|
||||||
import spack.cmd
|
import spack.cmd
|
||||||
|
import spack.cmd.common.arguments as arguments
|
||||||
|
import spack.environment as ev
|
||||||
|
import spack.repo
|
||||||
|
import spack.store
|
||||||
|
|
||||||
description = "show dependencies of a package"
|
description = "show dependencies of a package"
|
||||||
section = "basic"
|
section = "basic"
|
||||||
@ -26,6 +27,7 @@ def setup_parser(subparser):
|
|||||||
subparser.add_argument(
|
subparser.add_argument(
|
||||||
'-t', '--transitive', action='store_true', default=False,
|
'-t', '--transitive', action='store_true', default=False,
|
||||||
help="show all transitive dependencies")
|
help="show all transitive dependencies")
|
||||||
|
arguments.add_common_arguments(subparser, ['deptype'])
|
||||||
subparser.add_argument(
|
subparser.add_argument(
|
||||||
'-V', '--no-expand-virtuals', action='store_false', default=True,
|
'-V', '--no-expand-virtuals', action='store_false', default=True,
|
||||||
dest="expand_virtuals", help="do not expand virtual dependencies")
|
dest="expand_virtuals", help="do not expand virtual dependencies")
|
||||||
@ -45,7 +47,7 @@ def dependencies(parser, args):
|
|||||||
format_string = '{name}{@version}{%compiler}{/hash:7}'
|
format_string = '{name}{@version}{%compiler}{/hash:7}'
|
||||||
tty.msg("Dependencies of %s" % spec.format(format_string, color=True))
|
tty.msg("Dependencies of %s" % spec.format(format_string, color=True))
|
||||||
deps = spack.store.db.installed_relatives(
|
deps = spack.store.db.installed_relatives(
|
||||||
spec, 'children', args.transitive)
|
spec, 'children', args.transitive, deptype=args.deptype)
|
||||||
if deps:
|
if deps:
|
||||||
spack.cmd.display_specs(deps, long=True)
|
spack.cmd.display_specs(deps, long=True)
|
||||||
else:
|
else:
|
||||||
@ -63,9 +65,9 @@ def dependencies(parser, args):
|
|||||||
|
|
||||||
dependencies = set()
|
dependencies = set()
|
||||||
for pkg in packages:
|
for pkg in packages:
|
||||||
dependencies.update(
|
possible = pkg.possible_dependencies(
|
||||||
set(pkg.possible_dependencies(
|
args.transitive, args.expand_virtuals, deptype=args.deptype)
|
||||||
args.transitive, args.expand_virtuals)))
|
dependencies.update(possible)
|
||||||
|
|
||||||
if spec.name in dependencies:
|
if spec.name in dependencies:
|
||||||
dependencies.remove(spec.name)
|
dependencies.remove(spec.name)
|
||||||
|
@ -875,7 +875,8 @@ def remove(self, spec):
|
|||||||
return self._remove(spec)
|
return self._remove(spec)
|
||||||
|
|
||||||
@_autospec
|
@_autospec
|
||||||
def installed_relatives(self, spec, direction='children', transitive=True):
|
def installed_relatives(self, spec, direction='children', transitive=True,
|
||||||
|
deptype='all'):
|
||||||
"""Return installed specs related to this one."""
|
"""Return installed specs related to this one."""
|
||||||
if direction not in ('parents', 'children'):
|
if direction not in ('parents', 'children'):
|
||||||
raise ValueError("Invalid direction: %s" % direction)
|
raise ValueError("Invalid direction: %s" % direction)
|
||||||
@ -883,11 +884,12 @@ def installed_relatives(self, spec, direction='children', transitive=True):
|
|||||||
relatives = set()
|
relatives = set()
|
||||||
for spec in self.query(spec):
|
for spec in self.query(spec):
|
||||||
if transitive:
|
if transitive:
|
||||||
to_add = spec.traverse(direction=direction, root=False)
|
to_add = spec.traverse(
|
||||||
|
direction=direction, root=False, deptype=deptype)
|
||||||
elif direction == 'parents':
|
elif direction == 'parents':
|
||||||
to_add = spec.dependents()
|
to_add = spec.dependents(deptype=deptype)
|
||||||
else: # direction == 'children'
|
else: # direction == 'children'
|
||||||
to_add = spec.dependencies()
|
to_add = spec.dependencies(deptype=deptype)
|
||||||
|
|
||||||
for relative in to_add:
|
for relative in to_add:
|
||||||
hash_key = relative.dag_hash()
|
hash_key = relative.dag_hash()
|
||||||
|
@ -32,6 +32,20 @@ def test_transitive_dependencies(mock_packages):
|
|||||||
assert expected == actual
|
assert expected == actual
|
||||||
|
|
||||||
|
|
||||||
|
def test_transitive_dependencies_with_deptypes(mock_packages):
|
||||||
|
out = dependencies('--transitive', '--deptype=link,run', 'dtbuild1')
|
||||||
|
deps = set(re.split(r'\s+', out.strip()))
|
||||||
|
assert set(['dtlink2', 'dtrun2']) == deps
|
||||||
|
|
||||||
|
out = dependencies('--transitive', '--deptype=build', 'dtbuild1')
|
||||||
|
deps = set(re.split(r'\s+', out.strip()))
|
||||||
|
assert set(['dtbuild2', 'dtlink2']) == deps
|
||||||
|
|
||||||
|
out = dependencies('--transitive', '--deptype=link', 'dtbuild1')
|
||||||
|
deps = set(re.split(r'\s+', out.strip()))
|
||||||
|
assert set(['dtlink2']) == deps
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.db
|
@pytest.mark.db
|
||||||
def test_immediate_installed_dependencies(mock_packages, database):
|
def test_immediate_installed_dependencies(mock_packages, database):
|
||||||
with color_when(False):
|
with color_when(False):
|
||||||
|
Loading…
Reference in New Issue
Block a user