Specs to/from YAML are working.

This commit is contained in:
Todd Gamblin 2015-04-29 01:47:09 -07:00
parent 13132c6b97
commit 278e70e533
2 changed files with 102 additions and 2 deletions

View File

@ -28,6 +28,11 @@
So far: So far:
argparse: We include our own version to be Python 2.6 compatible. argparse: We include our own version to be Python 2.6 compatible.
pyqver2: External script to query required python version of python source code.
Used for ensuring 2.6 compatibility. pyqver2: External script to query required python version of
python source code. Used for ensuring 2.6 compatibility.
functools: Used for implementation of total_ordering.
yaml: Used for config files.
""" """

View File

@ -95,6 +95,7 @@
import hashlib import hashlib
from StringIO import StringIO from StringIO import StringIO
from operator import attrgetter from operator import attrgetter
from external import yaml
import llnl.util.tty as tty import llnl.util.tty as tty
from llnl.util.lang import * from llnl.util.lang import *
@ -578,6 +579,100 @@ def dep_hash(self, length=None):
return full_hash[:length] return full_hash[:length]
def dag_hash(self, length=None):
"""Return a hash of the entire spec DAG, including connectivity."""
sha = hashlib.sha1()
sha.update(self.to_node_yaml(canonical=True))
full_hash = sha.hexdigest()
return full_hash[:length]
def to_node_dict(self):
return {
self.name : {
'versions': [str(v) for v in self.versions],
'compiler' : None if self.compiler is None else {
'name' : self.compiler.name,
'versions': [str(v) for v in self.compiler.versions],
},
'variants' : dict(
(name,v.enabled) for name, v in self.variants.items()),
'arch' : self.architecture,
'dependencies' : dict((d, self.dependencies[d].dag_hash())
for d in sorted(self.dependencies))
}}
def to_node_yaml(self, **kwargs):
"""Return spec's DAG in minimal YAML (only immediate descendents)."""
canonical = kwargs.pop('canonical', False)
check_kwargs(kwargs, self.to_yaml)
if canonical:
return yaml.dump(self.to_node_dict(),
default_flow_style=True, width=sys.maxint)
else:
return yaml.dump(self.to_node_dict(),
default_flow_style=False)
def to_dict(self):
return {
'dag' : [s.to_node_dict() for s in self.traverse(order='pre')],
'hash' : self.dag_hash()
}
def to_yaml(self):
return yaml.dump(self.to_dict(), default_flow_style=False)
@staticmethod
def from_node_dict(node):
name = next(iter(node))
node = node[name]
spec = Spec(name)
spec.versions = VersionList(node['versions'])
compiler = node['compiler']
spec.architecture = node['arch']
if compiler is None:
spec.compiler = None
else:
spec.compiler = CompilerSpec(compiler['name'], compiler['versions'])
for name, enabled in node['variants'].items():
spec.variants[name] = Variant(name, enabled)
return spec
@staticmethod
def from_yaml(string):
"""Construct a spec from YAML.
TODO: currently discards hashes. Include hashes when they
represent more than the DAG does.
"""
deps = {}
spec = None
yfile = yaml.load(string)
for node in yfile['dag']:
name = next(iter(node))
dep = Spec.from_node_dict(node)
if not spec:
spec = dep
deps[dep.name] = dep
for node in yfile['dag']:
name = next(iter(node))
for dep_name in node[name]['dependencies']:
deps[name].dependencies[dep_name] = deps[dep_name]
return spec
def _concretize_helper(self, presets=None, visited=None): def _concretize_helper(self, presets=None, visited=None):
"""Recursive helper function for concretize(). """Recursive helper function for concretize().
This concretizes everything bottom-up. As things are This concretizes everything bottom-up. As things are