spec: Spec.tree() merges deptypes when only covering nodes (#8821)

- previously, output could be confusing when deptypes were only shown for
  one dependent when a node had *multiple* dependents

- also fix default coverage of `Spec.tree()`: it previously defaulted to
  cover only build and link dependencies, but this is a holdover from
  when those were the only types.
This commit is contained in:
Todd Gamblin 2018-07-29 11:54:20 -07:00 committed by GitHub
parent dba7f715cf
commit 2c45c3c5b3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 56 additions and 8 deletions

View File

@ -3198,7 +3198,7 @@ def tree(self, **kwargs):
fmt = kwargs.pop('format', '$_$@$%@+$+$=')
prefix = kwargs.pop('prefix', None)
show_types = kwargs.pop('show_types', False)
deptypes = kwargs.pop('deptypes', ('build', 'link'))
deptypes = kwargs.pop('deptypes', 'all')
check_kwargs(kwargs, self.tree)
out = ""
@ -3226,12 +3226,21 @@ def tree(self, **kwargs):
out += colorize('@K{%s} ', color=color) % node.dag_hash(hlen)
if show_types:
types = set()
if cover == 'nodes':
# when only covering nodes, we merge dependency types
# from all dependents before showing them.
for name, ds in node.dependents_dict().items():
if ds.deptypes:
types.update(set(ds.deptypes))
elif dep_spec.deptypes:
# when covering edges or paths, we show dependency
# types only for the edge through which we visited
types = set(dep_spec.deptypes)
out += '['
if dep_spec.deptypes:
for t in all_deptypes:
out += ''.join(t[0] if t in dep_spec.deptypes else ' ')
else:
out += ' ' * len(all_deptypes)
for t in all_deptypes:
out += ''.join(t[0] if t in types else ' ')
out += '] '
out += (" " * d)

View File

@ -22,13 +22,18 @@
# License along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
import re
import pytest
import spack.spec
from spack.main import SpackCommand
pytestmark = pytest.mark.usefixtures('config', 'mutable_mock_packages')
spec = SpackCommand('spec')
def test_spec(mock_packages, config):
def test_spec():
output = spec('mpileaks')
assert 'mpileaks@2.3' in output
@ -39,7 +44,7 @@ def test_spec(mock_packages, config):
assert 'mpich@3.0.4' in output
def test_spec_yaml(mock_packages, config):
def test_spec_yaml():
output = spec('--yaml', 'mpileaks')
mpileaks = spack.spec.Spec.from_yaml(output)
@ -49,3 +54,37 @@ def test_spec_yaml(mock_packages, config):
assert 'libdwarf' in mpileaks
assert 'libelf' in mpileaks
assert 'mpich' in mpileaks
def _parse_types(string):
"""Parse deptypes for specs from `spack spec -t` output."""
lines = string.strip().split('\n')
result = {}
for line in lines:
match = re.match(r'\[([^]]*)\]\s*\^?([^@]*)@', line)
if match:
types, name = match.groups()
result.setdefault(name, []).append(types)
result[name] = sorted(result[name])
return result
def test_spec_deptypes_nodes():
output = spec('--types', '--cover', 'nodes', 'dt-diamond')
types = _parse_types(output)
assert types['dt-diamond'] == [' ']
assert types['dt-diamond-left'] == ['bl ']
assert types['dt-diamond-right'] == ['bl ']
assert types['dt-diamond-bottom'] == ['blr ']
def test_spec_deptypes_edges():
output = spec('--types', '--cover', 'edges', 'dt-diamond')
types = _parse_types(output)
assert types['dt-diamond'] == [' ']
assert types['dt-diamond-left'] == ['bl ']
assert types['dt-diamond-right'] == ['bl ']
assert types['dt-diamond-bottom'] == ['b ', 'blr ']