Specs to/from YAML are working.
This commit is contained in:
parent
13132c6b97
commit
278e70e533
9
lib/spack/external/__init__.py
vendored
9
lib/spack/external/__init__.py
vendored
@ -28,6 +28,11 @@
|
||||
|
||||
So far:
|
||||
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.
|
||||
"""
|
||||
|
@ -95,6 +95,7 @@
|
||||
import hashlib
|
||||
from StringIO import StringIO
|
||||
from operator import attrgetter
|
||||
from external import yaml
|
||||
|
||||
import llnl.util.tty as tty
|
||||
from llnl.util.lang import *
|
||||
@ -578,6 +579,100 @@ def dep_hash(self, length=None):
|
||||
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):
|
||||
"""Recursive helper function for concretize().
|
||||
This concretizes everything bottom-up. As things are
|
||||
|
Loading…
Reference in New Issue
Block a user