diff options
Diffstat (limited to 'lib/spack/spack/spec.py')
-rw-r--r-- | lib/spack/spack/spec.py | 60 |
1 files changed, 39 insertions, 21 deletions
diff --git a/lib/spack/spack/spec.py b/lib/spack/spack/spec.py index 86eaa3bb91..2ef3757689 100644 --- a/lib/spack/spack/spec.py +++ b/lib/spack/spack/spec.py @@ -117,6 +117,7 @@ from spack.build_environment import get_path_from_module, load_module from spack.util.prefix import Prefix from spack.util.string import * import spack.util.spack_yaml as syaml +import spack.util.spack_json as sjson from spack.util.spack_yaml import syaml_dict from spack.util.crypto import prefix_bits from spack.version import * @@ -153,7 +154,6 @@ __all__ = [ 'UnsatisfiableArchitectureSpecError', 'UnsatisfiableProviderSpecError', 'UnsatisfiableDependencySpecError', - 'SpackYAMLError', 'AmbiguousHashError'] # Valid pattern for an identifier in Spack @@ -1174,15 +1174,21 @@ class Spec(object): return syaml_dict([(self.name, d)]) - def to_yaml(self, stream=None): + def to_dict(self): node_list = [] for s in self.traverse(order='pre', deptype=('link', 'run')): node = s.to_node_dict() node[s.name]['hash'] = s.dag_hash() node_list.append(node) + + return syaml_dict([('spec', node_list)]) + + def to_yaml(self, stream=None): return syaml.dump( - syaml_dict([('spec', node_list)]), - stream=stream, default_flow_style=False) + self.to_dict(), stream=stream, default_flow_style=False) + + def to_json(self, stream=None): + return sjson.dump(self.to_dict(), stream) @staticmethod def from_node_dict(node): @@ -1245,22 +1251,13 @@ class Spec(object): yield dep_name, dag_hash, list(deptypes) @staticmethod - def from_yaml(stream): + def from_dict(data): """Construct a spec from YAML. Parameters: - stream -- string or file object to read from. - - TODO: currently discards hashes. Include hashes when they - represent more than the DAG does. - + data -- a nested dict/list data structure read from YAML or JSON. """ - try: - yfile = syaml.load(stream) - except MarkedYAMLError as e: - raise SpackYAMLError("error parsing YAML spec:", str(e)) - - nodes = yfile['spec'] + nodes = data['spec'] # Read nodes out of list. Root spec is the first element; # dependencies are the following elements. @@ -1285,6 +1282,32 @@ class Spec(object): return spec + @staticmethod + def from_yaml(stream): + """Construct a spec from YAML. + + Parameters: + stream -- string or file object to read from. + """ + try: + data = syaml.load(stream) + return Spec.from_dict(data) + except MarkedYAMLError as e: + raise syaml.SpackYAMLError("error parsing YAML spec:", str(e)) + + @staticmethod + def from_json(stream): + """Construct a spec from JSON. + + Parameters: + stream -- string or file object to read from. + """ + try: + data = sjson.load(stream) + return Spec.from_dict(data) + except Exception as e: + raise sjson.SpackJSONError("error parsing JSON spec:", str(e)) + def _concretize_helper(self, presets=None, visited=None): """Recursive helper function for concretize(). This concretizes everything bottom-up. As things are @@ -3064,11 +3087,6 @@ class UnsatisfiableDependencySpecError(UnsatisfiableSpecError): provided, required, "dependency") -class SpackYAMLError(spack.error.SpackError): - def __init__(self, msg, yaml_error): - super(SpackYAMLError, self).__init__(msg, str(yaml_error)) - - class AmbiguousHashError(SpecError): def __init__(self, msg, *specs): super(AmbiguousHashError, self).__init__(msg) |