summaryrefslogtreecommitdiff
path: root/lib/spack/spack/spec.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/spack/spack/spec.py')
-rw-r--r--lib/spack/spack/spec.py78
1 files changed, 38 insertions, 40 deletions
diff --git a/lib/spack/spack/spec.py b/lib/spack/spack/spec.py
index 8e44075f42..a37b39be67 100644
--- a/lib/spack/spack/spec.py
+++ b/lib/spack/spack/spec.py
@@ -102,23 +102,26 @@ import sys
from StringIO import StringIO
from operator import attrgetter
+import yaml
+from yaml.error import MarkedYAMLError
+
import llnl.util.tty as tty
+from llnl.util.filesystem import join_path
+from llnl.util.lang import *
+from llnl.util.tty.color import *
+
import spack
import spack.architecture
import spack.compilers as compilers
import spack.error
import spack.parse
-import yaml
-from llnl.util.filesystem import join_path
-from llnl.util.lang import *
-from llnl.util.tty.color import *
from spack.build_environment import get_path_from_module, load_module
from spack.util.naming import mod_to_class
from spack.util.prefix import Prefix
from spack.util.string import *
from spack.version import *
-from spack.virtual import ProviderIndex
-from yaml.error import MarkedYAMLError
+from spack.provider_index import ProviderIndex
+
# Valid pattern for an identifier in Spack
identifier_re = r'\w[\w-]*'
@@ -438,8 +441,7 @@ class FlagMap(HashableMap):
return clone
def _cmp_key(self):
- return ''.join(str(key) + ' '.join(str(v) for v in value)
- for key, value in sorted(self.items()))
+ return tuple((k, tuple(v)) for k, v in sorted(self.iteritems()))
def __str__(self):
sorted_keys = filter(
@@ -715,7 +717,7 @@ class Spec(object):
"""Internal package call gets only the class object for a package.
Use this to just get package metadata.
"""
- return spack.repo.get_pkg_class(self.name)
+ return spack.repo.get_pkg_class(self.fullname)
@property
def virtual(self):
@@ -904,37 +906,36 @@ class Spec(object):
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.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.
- if not self.concrete or self.namespace:
+ if self.namespace:
d['namespace'] = self.namespace
if self.architecture:
# TODO: Fix the target.to_dict to account for the tuple
# Want it to be a dict of dicts
d['arch'] = self.architecture.to_dict()
- else:
- d['arch'] = None
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 +955,18 @@ class Spec(object):
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 'arch' in 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 +974,12 @@ class Spec(object):
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 +1037,10 @@ class Spec(object):
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
@@ -1567,7 +1571,7 @@ class Spec(object):
UnsupportedCompilerError.
"""
for spec in self.traverse():
- # Don't get a package for a virtual name.
+ # raise an UnknownPackageError if the spec's package isn't real.
if (not spec.virtual) and spec.name:
spack.repo.get(spec.fullname)
@@ -2824,12 +2828,6 @@ class SpackYAMLError(spack.error.SpackError):
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):