More compact YAML formatting for abstract specs.

- Don't add empty/absent fields to Spec YAML when they're not there.
This commit is contained in:
Todd Gamblin 2016-05-27 20:50:48 -05:00
parent 7aaad89ba9
commit 025609c63f
2 changed files with 27 additions and 26 deletions

View file

@ -904,19 +904,25 @@ def dag_hash(self, length=None):
return b32_hash
def to_node_dict(self):
d = {}
params = dict((name, v.value) for name, v in self.variants.items())
params.update(dict((name, value)
for name, value in self.compiler_flags.items()))
deps = self.dependencies_dict(deptype=('link', 'run'))
d = {
'parameters': params,
'arch': self.architecture,
'dependencies': dict(
if params:
d['parameters'] = params
if self.architecture is not None:
d['arch'] = self.architecture
if self.dependencies:
deps = self.dependencies_dict(deptype=('link', 'run'))
d['dependencies'] = dict(
(name, {
'hash': dspec.spec.dag_hash(),
'type': [str(s) for s in dspec.deptypes]})
for name, dspec in deps.items())
}
# Older concrete specs do not have a namespace. Omit for
# consistent hashing.
@ -932,9 +938,9 @@ def to_node_dict(self):
if self.compiler:
d.update(self.compiler.to_dict())
else:
d['compiler'] = None
d.update(self.versions.to_dict())
if self.versions:
d.update(self.versions.to_dict())
return {self.name: d}
@ -954,17 +960,17 @@ def from_node_dict(node):
spec = Spec(name)
spec.namespace = node.get('namespace', None)
spec.versions = VersionList.from_dict(node)
spec._hash = node.get('hash', None)
if 'hash' in node:
spec._hash = node['hash']
if 'version' in node or 'versions' in node:
spec.versions = VersionList.from_dict(node)
spec.architecture = spack.architecture.arch_from_dict(node['arch'])
if node['compiler'] is None:
spec.compiler = None
else:
if 'compiler' in node:
spec.compiler = CompilerSpec.from_dict(node)
else:
spec.compiler = None
if 'parameters' in node:
for name, value in node['parameters'].items():
@ -972,14 +978,12 @@ def from_node_dict(node):
spec.compiler_flags[name] = value
else:
spec.variants[name] = VariantSpec(name, value)
elif 'variants' in node:
for name, value in node['variants'].items():
spec.variants[name] = VariantSpec(name, value)
for name in FlagMap.valid_compiler_flags():
spec.compiler_flags[name] = []
else:
raise SpackRecordError(
"Did not find a valid format for variants in YAML file")
# Don't read dependencies here; from_node_dict() is used by
# from_yaml() to read the root *and* each dependency spec.
@ -1037,6 +1041,10 @@ def from_yaml(stream):
for node in nodes:
# get dependency dict from the node.
name = next(iter(node))
if 'dependencies' not in node[name]:
continue
yaml_deps = node[name]['dependencies']
for dname, dhash, dtypes in Spec.read_yaml_dep_specs(yaml_deps):
# Fill in dependencies by looking them up by name in deps dict
@ -2824,12 +2832,6 @@ def __init__(self, msg, yaml_error):
super(SpackYAMLError, self).__init__(msg, str(yaml_error))
class SpackRecordError(spack.error.SpackError):
def __init__(self, msg):
super(SpackRecordError, self).__init__(msg)
class AmbiguousHashError(SpecError):
def __init__(self, msg, *specs):

View file

@ -30,7 +30,7 @@
from spack.spec import Spec
from spack.test.mock_packages_test import *
class SpecDagTest(MockPackagesTest):
class SpecYamlTest(MockPackagesTest):
def check_yaml_round_trip(self, spec):
yaml_text = spec.to_yaml()
@ -64,7 +64,6 @@ def test_concrete_spec(self):
def test_yaml_subdag(self):
spec = Spec('mpileaks^mpich+debug')
spec.concretize()
yaml_spec = Spec.from_yaml(spec.to_yaml())
for dep in ('callpath', 'mpich', 'dyninst', 'libdwarf', 'libelf'):