summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorTodd Gamblin <tgamblin@llnl.gov>2022-04-23 23:20:28 -0700
committerTodd Gamblin <tgamblin@llnl.gov>2022-05-13 10:45:12 -0700
commit7c1d566959838dec48185d1de67697225d8979d5 (patch)
treea060bde503620d5daf8909b25bdc252eb8909001 /lib
parent7ab46e26b561e40b7e1fd5bc926c5012aee3e153 (diff)
downloadspack-7c1d566959838dec48185d1de67697225d8979d5.tar.gz
spack-7c1d566959838dec48185d1de67697225d8979d5.tar.bz2
spack-7c1d566959838dec48185d1de67697225d8979d5.tar.xz
spack-7c1d566959838dec48185d1de67697225d8979d5.zip
Remove all uses of `runtime_hash`; document lockfile formats and fix tests
This removes all but one usage of runtime hash. The runtime hash was being used to write historical lockfiles for tests, but we don't need it for that; we can just save those lockfiles. - [x] add legacy lockfiles for v1, v2, v3 - [x] fix bugs with v1 lockfile tests (the dummy lockfile we were writing was not actually a v1 lockfile because it used the new spec file format). - [x] remove all but one runtime_hash usage -- that one needs a small rework of the concretizer to really fix, as it's about separate concretization of build dependencies. - [x] Document the history of the lockfile format in `environment/__init__.py`
Diffstat (limited to 'lib')
-rw-r--r--lib/spack/spack/ci.py2
-rw-r--r--lib/spack/spack/cmd/spec.py11
-rw-r--r--lib/spack/spack/database.py2
-rw-r--r--lib/spack/spack/environment/__init__.py327
-rw-r--r--lib/spack/spack/environment/environment.py7
-rw-r--r--lib/spack/spack/schema/spec.py6
-rw-r--r--lib/spack/spack/spec.py45
-rw-r--r--lib/spack/spack/test/cmd/env.py239
-rw-r--r--lib/spack/spack/test/concretize.py1
-rw-r--r--lib/spack/spack/test/data/legacy_env/spack.lock672
-rw-r--r--lib/spack/spack/test/data/legacy_env/v1.lock383
-rw-r--r--lib/spack/spack/test/data/legacy_env/v2.lock919
-rw-r--r--lib/spack/spack/test/data/legacy_env/v3.lock924
-rw-r--r--lib/spack/spack/test/spec_semantics.py22
14 files changed, 2719 insertions, 841 deletions
diff --git a/lib/spack/spack/ci.py b/lib/spack/spack/ci.py
index 98c3956780..d2eb8634ea 100644
--- a/lib/spack/spack/ci.py
+++ b/lib/spack/spack/ci.py
@@ -871,7 +871,6 @@ def generate_gitlab_ci_yaml(env, print_summary, output_file,
pkg_name = _pkg_name_from_spec_label(spec_label)
release_spec = root_spec[pkg_name]
release_spec_dag_hash = release_spec.dag_hash()
- release_spec_runtime_hash = release_spec.runtime_hash()
if prune_untouched_packages:
if release_spec not in affected_specs:
@@ -941,7 +940,6 @@ def generate_gitlab_ci_yaml(env, print_summary, output_file,
'SPACK_ROOT_SPEC': _format_root_spec(
root_spec, main_phase, strip_compilers),
'SPACK_JOB_SPEC_DAG_HASH': release_spec_dag_hash,
- 'SPACK_JOB_SPEC_RUNTIME_HASH': release_spec_runtime_hash,
'SPACK_JOB_SPEC_PKG_NAME': release_spec.name,
'SPACK_COMPILER_ACTION': compiler_action
}
diff --git a/lib/spack/spack/cmd/spec.py b/lib/spack/spack/cmd/spec.py
index 3a0398ca23..74a47d154d 100644
--- a/lib/spack/spack/cmd/spec.py
+++ b/lib/spack/spack/cmd/spec.py
@@ -52,10 +52,6 @@ for further documentation regarding the spec syntax, see:
'-N', '--namespaces', action='store_true', default=False,
help='show fully qualified package names')
subparser.add_argument(
- '--hash-type', default="dag_hash",
- choices=['runtime_hash', 'dag_hash'],
- help='generate spec with a particular hash type.')
- subparser.add_argument(
'-t', '--types', action='store_true', default=False,
help='show dependency types')
arguments.add_common_arguments(subparser, ['specs'])
@@ -96,14 +92,11 @@ def spec(parser, args):
for (input, output) in specs:
# With -y, just print YAML to output.
if args.format:
- # The user can specify the hash type to use
- hash_type = getattr(ht, args.hash_type)
-
if args.format == 'yaml':
# use write because to_yaml already has a newline.
- sys.stdout.write(output.to_yaml(hash=hash_type))
+ sys.stdout.write(output.to_yaml(hash=ht.dag_hash))
elif args.format == 'json':
- print(output.to_json(hash=hash_type))
+ print(output.to_json(hash=ht.dag_hash))
else:
print(output.format(args.format))
continue
diff --git a/lib/spack/spack/database.py b/lib/spack/spack/database.py
index 8537d345fd..95e3be6715 100644
--- a/lib/spack/spack/database.py
+++ b/lib/spack/spack/database.py
@@ -1096,7 +1096,6 @@ class Database(object):
"Specs added to DB must be concrete.")
key = spec.dag_hash()
- spec_run_hash = spec._runtime_hash
spec_pkg_hash = spec._package_hash
upstream, record = self.query_by_spec_hash(key)
if upstream:
@@ -1162,7 +1161,6 @@ class Database(object):
# the original hashes of concrete specs.
new_spec._mark_concrete()
new_spec._hash = key
- new_spec._runtime_hash = spec_run_hash
new_spec._package_hash = spec_pkg_hash
else:
diff --git a/lib/spack/spack/environment/__init__.py b/lib/spack/spack/environment/__init__.py
index b710979013..add58261e6 100644
--- a/lib/spack/spack/environment/__init__.py
+++ b/lib/spack/spack/environment/__init__.py
@@ -1,7 +1,334 @@
+# -*- coding: utf-8 -*-
# Copyright 2013-2022 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
+"""This package implements Spack environments.
+
+.. _lockfile-format:
+
+`spack.lock` format
+===================
+
+Spack environments have existed since Spack ``v0.12.0``, and there have been 4 different
+``spack.lock`` formats since then. The formats are documented here.
+
+The high-level format of a Spack lockfile hasn't changed much between versions, but the
+contents have. Lockfiles are JSON-formatted and their top-level sections are:
+
+ 1. ``_meta`` (object): this contains deatails about the file format, including:
+ * ``file-type``: always ``"spack-lockfile"``
+ * ``lockfile-version``: an integer representing the lockfile format version
+ * ``specfile-version``: an integer representing the spec format version (since
+ ``v0.17``)
+
+ 2. ``roots`` (list): an ordered list of records representing the roots of the Spack
+ environment. Each has two fields:
+ * ``hash``: a Spack spec hash uniquely identifying the concrete root spec
+ * ``spec``: a string representation of the abstract spec that was concretized
+
+3. ``concrete_specs``: a dictionary containing the specs in the environment.
+
+Compatibility
+-------------
+
+New versions of Spack can (so far) read all old lockfile formats -- they are
+backward-compatible. Old versions cannot read new lockfile formats, and you'll need to
+upgrade Spack to use them.
+
+.. list-table:: Lockfile version compatibility across Spack versions
+ :header-rows: 1
+
+ * - Spack version
+ - ``v1``
+ - ``v2``
+ - ``v3``
+ - ``v4``
+ * - ``v0.12:0.14``
+ - ✅
+ -
+ -
+ -
+ * - ``v0.15:0.16``
+ - ✅
+ - ✅
+ -
+ -
+ * - ``v0.17``
+ - ✅
+ - ✅
+ - ✅
+ -
+ * - ``v0.18:``
+ - ✅
+ - ✅
+ - ✅
+ - ✅
+
+Version 1
+---------
+
+When lockfiles were first created, there was only one hash in Spack: the DAG hash. This
+DAG hash (we'll call it the old DAG hash) did *not* include build dependencies -- it
+only included transitive link and run dependencies.
+
+The spec format at this time was keyed by name. Each spec started with a key for its
+name, whose value was a dictionary of other spec attributes. The lockfile put these
+name-keyed specs into dictionaries keyed by their DAG hash, and the spec records did not
+actually have a "hash" field in the lockfile -- you have to associate the hash from the
+key with the spec record after the fact.
+
+Dependencies in original lockfiles were keyed by ``"hash"``, i.e. the old DAG hash.
+
+.. code-block:: json
+
+ {
+ "_meta": {
+ "file-type": "spack-lockfile",
+ "lockfile-version": 1
+ },
+ "roots": [
+ {
+ "hash": "<old_dag_hash 1>",
+ "spec": "<abstract spec 1>"
+ },
+ {
+ "hash": "<old_dag_hash 2>",
+ "spec": "<abstract spec 2>"
+ }
+ ],
+ "concrete_specs": {
+ "<old_dag_hash 1>": {
+ "... <spec dict attributes> ...": { },
+ "dependencies": {
+ "depname_1": {
+ "hash": "<old_dag_hash for depname_1>",
+ "type": ["build", "link"]
+ },
+ "depname_2": {
+ "hash": "<old_dag_hash for depname_3>",
+ "type": ["build", "link"]
+ }
+ },
+ "hash": "<old_dag_hash 1>"
+ },
+ "<old_dag_hash 2>": {
+ "... <spec dict attributes> ...": { },
+ "dependencies": {
+ "depname_3": {
+ "hash": "<old_dag_hash for depname_3>",
+ "type": ["build", "link"]
+ },
+ "depname_4": {
+ "hash": "<old_dag_hash for depname_4>",
+ "type": ["build", "link"]
+ },
+ },
+ "hash": "<old_dag_hash 2>"
+ },
+ }
+ }
+
+
+Version 2
+---------
+
+Version 2 changes one thing: specs in the lockfile are now keyed by ``build_hash``
+instead of the old ``dag_hash``. Specs have a ``hash`` attribute with their real DAG
+hash, so you can't go by the dictionary key anymore to identify a spec -- you have to
+read it in and look at ``"hash"``. Dependencies are still keyed by old DAG hash.
+
+Even though we key lockfiles by ``build_hash``, specs in Spack were still deployed with
+the old, coarser DAG hash. This means that in v2 and v3 lockfiles (which are keyed by
+build hash), there may be multiple versions of the same spec with different build
+dependencies, which means they will have different build hashes but the same DAG hash.
+Spack would only have been able to actually install one of these.
+
+.. code-block:: json
+
+ {
+ "_meta": {
+ "file-type": "spack-lockfile",
+ "lockfile-version": 2
+ },
+ "roots": [
+ {
+ "hash": "<build_hash 1>",
+ "spec": "<abstract spec 1>"
+ },
+ {
+ "hash": "<build_hash 2>",
+ "spec": "<abstract spec 2>"
+ }
+ ],
+ "concrete_specs": {
+ "<build_hash 1>": {
+ "... <spec dict attributes> ...": { },
+ "dependencies": {
+ "depname_1": {
+ "hash": "<old_dag_hash for depname_1>",
+ "type": ["build", "link"]
+ },
+ "depname_2": {
+ "hash": "<old_dag_hash for depname_3>",
+ "type": ["build", "link"]
+ }
+ },
+ "hash": "<old_dag_hash 1>",
+ },
+ "<build_hash 2>": {
+ "... <spec dict attributes> ...": { },
+ "dependencies": {
+ "depname_3": {
+ "hash": "<old_dag_hash for depname_3>",
+ "type": ["build", "link"]
+ },
+ "depname_4": {
+ "hash": "<old_dag_hash for depname_4>",
+ "type": ["build", "link"]
+ }
+ },
+ "hash": "<old_dag_hash 2>"
+ }
+ }
+ }
+
+
+Version 3
+---------
+
+Version 3 doesn't change the top-level lockfile format, but this was when we changed the
+specfile format. Specs in ``concrete_specs`` are now keyed by the build hash, with no
+inner dictionary keyed by their package name. The package name is in a ``name`` field
+inside each spec dictionary. The ``dependencies`` field in the specs is a list instead
+of a dictionary, and each element of the list is a record with the name, dependency
+types, and hash of the dependency. Instead of a key called ``hash``, dependencies are
+keyed by ``build_hash``. Each spec still has a ``hash`` attribute.
+
+Version 3 adds the ``specfile_version`` field to ``_meta`` and uses the new JSON spec
+format.
+
+.. code-block:: json
+
+ {
+ "_meta": {
+ "file-type": "spack-lockfile",
+ "lockfile-version": 3,
+ "specfile-version": 2
+ },
+ "roots": [
+ {
+ "hash": "<build_hash 1>",
+ "spec": "<abstract spec 1>"
+ },
+ {
+ "hash": "<build_hash 2>",
+ "spec": "<abstract spec 2>"
+ },
+ ],
+ "concrete_specs": {
+ "<build_hash 1>": {
+ "... <spec dict attributes> ...": { },
+ "dependencies": [
+ {
+ "name": "depname_1",
+ "build_hash": "<build_hash for depname_1>",
+ "type": ["build", "link"]
+ },
+ {
+ "name": "depname_2",
+ "build_hash": "<build_hash for depname_2>",
+ "type": ["build", "link"]
+ },
+ ],
+ "hash": "<old_dag_hash 1>",
+ },
+ "<build_hash 2>": {
+ "... <spec dict attributes> ...": { },
+ "dependencies": [
+ {
+ "name": "depname_3",
+ "build_hash": "<build_hash for depname_3>",
+ "type": ["build", "link"]
+ },
+ {
+ "name": "depname_4",
+ "build_hash": "<build_hash for depname_4>",
+ "type": ["build", "link"]
+ },
+ ],
+ "hash": "<old_dag_hash 2>"
+ }
+ }
+ }
+
+
+Version 4
+---------
+
+Version 4 removes build hashes and is keyed by the new DAG hash (``hash``). The ``hash``
+now includes build dependencies and a canonical hash of the ``package.py`` file.
+Dependencies are keyed by ``hash`` (DAG hash) as well. There are no more ``build_hash``
+fields in the specs, and there are no more issues with lockfiles being able to store
+multiple specs with the same DAG hash (because the DAG hash is now finer-grained).
+
+
+.. code-block:: json
+
+ {
+ "_meta": {
+ "file-type": "spack-lockfile",
+ "lockfile-version": 3,
+ "specfile-version": 2
+ },
+ "roots": [
+ {
+ "hash": "<dag_hash 1>",
+ "spec": "<abstract spec 1>"
+ },
+ {
+ "hash": "<dag_hash 2>",
+ "spec": "<abstract spec 2>"
+ }
+ ],
+ "concrete_specs": {
+ "<dag_hash 1>": {
+ "... <spec dict attributes> ...": { },
+ "dependencies": [
+ {
+ "name": "depname_1",
+ "hash": "<dag_hash for depname_1>",
+ "type": ["build", "link"]
+ },
+ {
+ "name": "depname_2",
+ "hash": "<dag_hash for depname_2>",
+ "type": ["build", "link"]
+ }
+ ],
+ "hash": "<dag_hash 1>",
+ },
+ "<daghash 2>": {
+ "... <spec dict attributes> ...": { },
+ "dependencies": [
+ {
+ "name": "depname_3",
+ "hash": "<dag_hash for depname_3>",
+ "type": ["build", "link"]
+ },
+ {
+ "name": "depname_4",
+ "hash": "<dag_hash for depname_4>",
+ "type": ["build", "link"]
+ }
+ ],
+ "hash": "<dag_hash 2>"
+ }
+ }
+ }
+
+"""
+
from .environment import (
Environment,
SpackEnvironmentError,
diff --git a/lib/spack/spack/environment/environment.py b/lib/spack/spack/environment/environment.py
index 75c99a9c21..6ed4297fca 100644
--- a/lib/spack/spack/environment/environment.py
+++ b/lib/spack/spack/environment/environment.py
@@ -1825,7 +1825,12 @@ class Environment(object):
# First pass: Put each spec in the map ignoring dependencies
for lockfile_key, node_dict in json_specs_by_hash.items():
- specs_by_hash[lockfile_key] = Spec.from_node_dict(node_dict)
+ spec = Spec.from_node_dict(node_dict)
+ if not spec._hash:
+ # in v1 lockfiles, the hash only occurs as a key
+ print("HERE")
+ spec._hash = lockfile_key
+ specs_by_hash[lockfile_key] = spec
# Second pass: For each spec, get its dependencies from the node dict
# and add them to the spec
diff --git a/lib/spack/spack/schema/spec.py b/lib/spack/spack/schema/spec.py
index a1665092aa..3e64f08502 100644
--- a/lib/spack/spack/schema/spec.py
+++ b/lib/spack/spack/schema/spec.py
@@ -110,8 +110,12 @@ properties = {
'properties': {
'name': {'type': 'string'},
'hash': {'type': 'string'},
- 'runtime_hash': {'type': 'string'},
'package_hash': {'type': 'string'},
+
+ # these hashes were used on some specs prior to 0.18
+ 'full_hash': {'type': 'string'},
+ 'build_hash': {'type': 'string'},
+
'version': {
'oneOf': [
{'type': 'string'},
diff --git a/lib/spack/spack/spec.py b/lib/spack/spack/spec.py
index e0a417cb76..c49878cd37 100644
--- a/lib/spack/spack/spec.py
+++ b/lib/spack/spack/spec.py
@@ -1191,10 +1191,14 @@ class Spec(object):
self._dependencies = _EdgeMap(store_by=EdgeDirection.child)
self.namespace = None
- self._hash = None
- self._runtime_hash = None
- self._package_hash = None
+ # initial values for all spec hash types
+ for h in ht.hashes:
+ setattr(self, h.attr, None)
+
+ # Python __hash__ is handled separately from the cached spec hashes
self._dunder_hash = None
+
+ # cache of package for this spec
self._package = None
# Most of these are internal implementation details that can be
@@ -1810,7 +1814,6 @@ class Spec(object):
"""
return self._cached_hash(ht.process_hash, length)
-
def dag_hash_bit_prefix(self, bits):
"""Get the first <bits> bits of the DAG hash as an integer type."""
return spack.util.hash.base32_prefix_bits(self.dag_hash(), bits)
@@ -1999,7 +2002,6 @@ class Spec(object):
]
}
],
- "runtime_hash": "d2yzqp2highd7sn4nr5ndkw3ydcrlhtk",
"hash": "tve45xfqkfgmzwcyfetze2z6syrg7eaf",
},
# ... more node dicts for readline and its dependencies ...
@@ -2203,18 +2205,13 @@ class Spec(object):
dep_hash, deptypes = elt
elif isinstance(elt, dict):
# new format: elements of dependency spec are keyed.
- for key in (ht.dag_hash.name,
- ht.build_hash.name,
- ht.full_hash.name,
- ht.runtime_hash.name,
- ht.process_hash.name):
- if key in elt:
- dep_hash, deptypes = elt[key], elt['type']
- hash_type = key
+ for h in ht.hashes:
+ if h.name in elt:
+ dep_hash, deptypes = elt[h.name], elt['type']
+ hash_type = h.name
break
else: # We never determined a hash type...
- raise spack.error.SpecError(
- "Couldn't parse dependency spec.")
+ raise spack.error.SpecError("Couldn't parse dependency spec.")
else:
raise spack.error.SpecError(
"Couldn't parse dependency types in spec.")
@@ -3747,20 +3744,17 @@ class Spec(object):
self._concrete = other._concrete
if self._concrete:
- self._hash = other._hash
self._dunder_hash = other._dunder_hash
self._normal = other._normal
- self._full_hash = other._full_hash
- self._runtime_hash = other._runtime_hash
- self._package_hash = other._package_hash
+ for h in ht.hashes:
+ setattr(self, h.attr, getattr(other, h.attr, None))
else:
- self._hash = None
self._dunder_hash = None
# Note, we could use other._normal if we are copying all deps, but
# always set it False here to avoid the complexity of checking
self._normal = False
- self._runtime_hash = None
- self._package_hash = None
+ for h in ht.hashes:
+ setattr(self, h.attr, None)
return changed
@@ -5022,7 +5016,7 @@ class SpecParser(spack.parse.Parser):
# Raise an error if the previous spec is already
# concrete (assigned by hash)
- if specs[-1]._hash:
+ if specs[-1].concrete:
raise RedundantSpecError(specs[-1], 'dependency')
# command line deps get empty deptypes now.
# Real deptypes are assigned later per packages.
@@ -5032,9 +5026,8 @@ class SpecParser(spack.parse.Parser):
# If the next token can be part of a valid anonymous spec,
# create the anonymous spec
if self.next.type in (AT, ON, OFF, PCT):
- # Raise an error if the previous spec is already
- # concrete (assigned by hash)
- if specs and specs[-1]._hash:
+ # Raise an error if the previous spec is already concrete
+ if specs and specs[-1].concrete:
raise RedundantSpecError(specs[-1],
'compiler, version, '
'or variant')
diff --git a/lib/spack/spack/test/cmd/env.py b/lib/spack/spack/test/cmd/env.py
index 32c7f08f32..48f0092c09 100644
--- a/lib/spack/spack/test/cmd/env.py
+++ b/lib/spack/spack/test/cmd/env.py
@@ -2,6 +2,7 @@
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
+import filecmp
import glob
import os
import shutil
@@ -17,7 +18,6 @@ import llnl.util.link_tree
import spack.cmd.env
import spack.environment as ev
import spack.environment.shell
-import spack.hash_types as ht
import spack.modules
import spack.paths
import spack.repo
@@ -969,89 +969,6 @@ def test_uninstall_removes_from_env(mock_stage, mock_fetch, install_mockery):
assert not test.user_specs
-def create_v1_lockfile_dict(roots, all_specs):
- test_lockfile_dict = {
- "_meta": {
- "lockfile-version": 1,
- "file-type": "spack-lockfile"
- },
- "roots": list(
- {
- "hash": s.runtime_hash(),
- "spec": s.name
- } for s in roots
- ),
- # Version one lockfiles use the dag hash without build deps as keys,
- # but they write out the full node dict (including build deps)
- "concrete_specs": dict(
- # (s.dag_hash(), s.to_node_dict(hash=ht.dag_hash))
- (s.runtime_hash(), s.to_node_dict(hash=ht.build_hash))
- for s in all_specs
- )
- }
- return test_lockfile_dict
-
-
-@pytest.mark.usefixtures('config')
-def test_read_old_lock_and_write_new(tmpdir):
- build_only = ('build',)
-
- mock_repo = MockPackageMultiRepo()
- y = mock_repo.add_package('y', [], [])
- mock_repo.add_package('x', [y], [build_only])
-
- with spack.repo.use_repositories(mock_repo):
- x = Spec('x')
- x.concretize()
-
- y = x['y']
-
- test_lockfile_dict = create_v1_lockfile_dict([x], [x, y])
-
- test_lockfile_path = str(tmpdir.join('test.lock'))
- with open(test_lockfile_path, 'w') as f:
- sjson.dump(test_lockfile_dict, stream=f)
-
- _env_create('test', test_lockfile_path, with_view=False)
-
- e = ev.read('test')
- hashes = set(e._to_lockfile_dict()['concrete_specs'])
- # When the lockfile is rewritten, it should adopt the new hash scheme
- # which accounts for all dependencies, including build dependencies
- assert hashes == set([
- x.dag_hash(),
- y.dag_hash()])
-
-
-@pytest.mark.usefixtures('config')
-def test_read_old_lock_creates_backup(tmpdir):
- """When reading a version-1 lockfile, make sure that a backup of that file
- is created.
- """
-
- mock_repo = MockPackageMultiRepo()
- y = mock_repo.add_package('y', [], [])
-
- with spack.repo.use_repositories(mock_repo):
- y = Spec('y')
- y.concretize()
-
- test_lockfile_dict = create_v1_lockfile_dict([y], [y])
-
- env_root = tmpdir.mkdir('test-root')
- test_lockfile_path = str(env_root.join(ev.lockfile_name))
- with open(test_lockfile_path, 'w') as f:
- sjson.dump(test_lockfile_dict, stream=f)
-
- e = ev.Environment(str(env_root))
- assert os.path.exists(e._lock_backup_v1_path)
- with open(e._lock_backup_v1_path, 'r') as backup_v1_file:
- lockfile_dict_v1 = sjson.load(backup_v1_file)
-
- # Make sure that the backup file follows the v1 hash scheme
- assert y.runtime_hash() in lockfile_dict_v1['concrete_specs']
-
-
@pytest.mark.usefixtures('config')
def test_indirect_build_dep():
"""Simple case of X->Y->Z where Y is a build/link dep and Z is a
@@ -1118,11 +1035,11 @@ def test_store_different_build_deps():
x_spec = Spec('x ^z@2')
x_concretized = x_spec.concretized()
- # Even though x chose a different 'z', it should choose the same y
- # according to the DAG hash (since build deps are excluded from
- # comparison by default). Although the dag hashes are equal, the specs
- # are not considered equal because they compare build deps.
- assert x_concretized['y'].runtime_hash() == y_concretized.runtime_hash()
+ # Even though x chose a different 'z', the y it chooses should be identical
+ # *aside* from the dependency on 'z'. The dag_hash() will show the difference
+ # in build dependencies.
+ assert x_concretized['y'].eq_node(y_concretized)
+ assert x_concretized['y'].dag_hash() != y_concretized.dag_hash()
_env_create('test', with_view=False)
e = ev.read('test')
@@ -1137,7 +1054,13 @@ def test_store_different_build_deps():
y_read = e_read.specs_by_hash[y_env_hash]
x_read = e_read.specs_by_hash[x_env_hash]
+ # make sure the DAG hashes and build deps are preserved after
+ # a round trip to/from the lockfile
assert x_read['z'] != y_read['z']
+ assert x_read['z'].dag_hash() != y_read['z'].dag_hash()
+
+ assert x_read['y'].eq_node(y_read)
+ assert x_read['y'].dag_hash() != y_read.dag_hash()
def test_env_updates_view_install(
@@ -2603,7 +2526,6 @@ def test_does_not_rewrite_rel_dev_path_when_keep_relative_is_set(tmpdir):
_, _, _, spack_yaml = _setup_develop_packages(tmpdir)
env('create', '--keep-relative', 'named_env', str(spack_yaml))
with ev.read('named_env') as e:
- print(e.dev_specs)
assert e.dev_specs['mypkg1']['path'] == '../build_folder'
assert e.dev_specs['mypkg2']['path'] == '/some/other/path'
@@ -2865,15 +2787,108 @@ def test_environment_query_spec_by_hash(mock_stage, mock_fetch, install_mockery)
assert e.matching_spec('libelf').installed
-def test_read_legacy_lockfile_and_reconcretize(mock_stage, mock_fetch, install_mockery):
- """In legacy lockfiles there is possibly a one-to-many relationship between
- DAG hash lockfile keys. In the case of DAG hash conflicts, we always keep
- the spec associated with whichever root spec came first in "roots". After
- we force reconcretization, there should no longer be conflicts, i.e. all
- specs that originally conflicted should be present in the environment
- again."""
+@pytest.mark.parametrize("lockfile", ["v1", "v2", "v3"])
+def test_read_old_lock_and_write_new(config, tmpdir, lockfile):
+ # v1 lockfiles stored by a coarse DAG hash that did not include build deps.
+ # They could not represent multiple build deps with different build hashes.
+ #
+ # v2 and v3 lockfiles are keyed by a "build hash", so they can represent specs
+ # with different build deps but the same DAG hash. However, those two specs
+ # could never have been built together, because they cannot coexist in a
+ # Spack DB, which is keyed by DAG hash. The second one would just be a no-op
+ # no-op because its DAG hash was already in the DB.
+ #
+ # Newer Spack uses a fine-grained DAG hash that includes build deps, package hash,
+ # and more. But, we still have to identify old specs by their original DAG hash.
+ # Essentially, the name (hash) we give something in Spack at concretization time is
+ # its name forever (otherwise we'd need to relocate prefixes and disrupt existing
+ # installations). So, we just discard the second conflicting dtbuild1 version when
+ # reading v2 and v3 lockfiles. This is what old Spack would've done when installing
+ # the environment, anyway.
+ #
+ # This test ensures the behavior described above.
+ lockfile_path = os.path.join(
+ spack.paths.test_path, "data", "legacy_env", "%s.lock" % lockfile
+ )
+
+ # read in the JSON from a legacy lockfile
+ with open(lockfile_path) as f:
+ old_dict = sjson.load(f)
+
+ # read all DAG hashes from the legacy lockfile and record its shadowed DAG hash.
+ old_hashes = set()
+ shadowed_hash = None
+ for key, spec_dict in old_dict["concrete_specs"].items():
+ if "hash" not in spec_dict:
+ # v1 and v2 key specs by their name in concrete_specs
+ name, spec_dict = next(iter(spec_dict.items()))
+ else:
+ # v3 lockfiles have a `name` field and key by hash
+ name = spec_dict["name"]
+
+ # v1 lockfiles do not have a "hash" field -- they use the key.
+ dag_hash = key if lockfile == "v1" else spec_dict["hash"]
+ old_hashes.add(dag_hash)
+
+ # v1 lockfiles can't store duplicate build dependencies, so they
+ # will not have a shadowed hash.
+ if lockfile != "v1":
+ # v2 and v3 lockfiles store specs by build hash, so they can have multiple
+ # keys for the same DAG hash. We discard the second one (dtbuild@1.0).
+ if name == "dtbuild1" and spec_dict["version"] == "1.0":
+ shadowed_hash = dag_hash
+
+ # make an env out of the old lockfile -- env should be able to read v1/v2/v3
+ test_lockfile_path = str(tmpdir.join("test.lock"))
+ shutil.copy(lockfile_path, test_lockfile_path)
+ _env_create("test", test_lockfile_path, with_view=False)
+
+ # re-read the old env as a new lockfile
+ e = ev.read("test")
+ hashes = set(e._to_lockfile_dict()["concrete_specs"])
+
+ # v1 doesn't have duplicate build deps.
+ # in v2 and v3, the shadowed hash will be gone.
+ if shadowed_hash:
+ old_hashes -= set([shadowed_hash])
+
+ # make sure we see the same hashes in old and new lockfiles
+ assert old_hashes == hashes
+
+
+def test_read_v1_lock_creates_backup(config, tmpdir):
+ """When reading a version-1 lockfile, make sure that a backup of that file
+ is created.
+ """
+ # read in the JSON from a legacy v1 lockfile
+ v1_lockfile_path = os.path.join(
+ spack.paths.test_path, "data", "legacy_env", "v1.lock"
+ )
+
+ # make an env out of the old lockfile
+ test_lockfile_path = str(tmpdir.join(ev.lockfile_name))
+ shutil.copy(v1_lockfile_path, test_lockfile_path)
+
+ e = ev.Environment(str(tmpdir))
+ assert os.path.exists(e._lock_backup_v1_path)
+ assert filecmp.cmp(e._lock_backup_v1_path, v1_lockfile_path)
+
+
+@pytest.mark.parametrize("lockfile", ["v1", "v2", "v3"])
+def test_read_legacy_lockfile_and_reconcretize(
+ mock_stage, mock_fetch, install_mockery, lockfile
+):
+ # In legacy lockfiles v2 and v3 (keyed by build hash), there may be multiple
+ # versions of the same spec with different build dependencies, which means
+ # they will have different build hashes but the same DAG hash.
+ # In the case of DAG hash conflicts, we always keep the spec associated with
+ # whichever root spec came first in the "roots" list.
+ #
+ # After reconcretization with the *new*, finer-grained DAG hash, there should no
+ # longer be conflicts, and the previously conflicting specs can coexist in the
+ # same environment.
legacy_lockfile_path = os.path.join(
- spack.paths.test_path, 'data', 'legacy_env', 'spack.lock'
+ spack.paths.test_path, "data", "legacy_env", "%s.lock" % lockfile
)
# The order of the root specs in this environment is:
@@ -2881,38 +2896,32 @@ def test_read_legacy_lockfile_and_reconcretize(mock_stage, mock_fetch, install_m
# wci7a3a -> dttop ^dtbuild1@0.5,
# 5zg6wxw -> dttop ^dtbuild1@1.0
# ]
- # So in the legacy lockfile we have two versions of dttop with the same DAG
- # hash (in the past DAG hash did not take build deps into account). Make
- # sure we keep the correct instance of each spec, i.e. the one that appeared
- # first.
+ # So in v2 and v3 lockfiles we have two versions of dttop with the same DAG
+ # hash but different build hashes.
env('create', 'test', legacy_lockfile_path)
test = ev.read('test')
-
assert len(test.specs_by_hash) == 1
single_root = next(iter(test.specs_by_hash.values()))
- assert single_root['dtbuild1'].version == Version('0.5')
+ # v1 only has version 1.0, because v1 was keyed by DAG hash, and v1.0 overwrote
+ # v0.5 on lockfile creation. v2 only has v0.5, because we specifically prefer
+ # the one that would be installed when we read old lockfiles.
+ if lockfile == "v1":
+ assert single_root['dtbuild1'].version == Version('1.0')
+ else:
+ assert single_root['dtbuild1'].version == Version('0.5')
# Now forcefully reconcretize
with ev.read('test'):
concretize('-f')
+ # After reconcretizing, we should again see two roots, one depending on each
+ # of the dtbuild1 versions specified in the roots of the original lockfile.
test = ev.read('test')
-
- # After reconcretizing, we should again see two roots, one depending on
- # each of the dtbuild1 versions specified in the roots of the original
- # lockfile.
assert len(test.specs_by_hash) == 2
- expected_dtbuild1_versions = [Version('0.5'), Version('1.0')]
-
- for s in test.specs_by_hash.values():
- expected_dtbuild1_versions.remove(s['dtbuild1'].version)
-
- assert len(expected_dtbuild1_versions) == 0
-
expected_versions = set([Version('0.5'), Version('1.0')])
current_versions = set(s['dtbuild1'].version for s in test.specs_by_hash.values())
assert current_versions == expected_versions
diff --git a/lib/spack/spack/test/concretize.py b/lib/spack/spack/test/concretize.py
index f4b11056e8..698041de98 100644
--- a/lib/spack/spack/test/concretize.py
+++ b/lib/spack/spack/test/concretize.py
@@ -1080,7 +1080,6 @@ class TestConcretize(object):
s._old_concretize(), t._new_concretize()
assert s.dag_hash() == t.dag_hash()
- assert s.runtime_hash() == t.runtime_hash()
def test_external_that_would_require_a_virtual_dependency(self):
s = Spec('requires-virtual').concretized()
diff --git a/lib/spack/spack/test/data/legacy_env/spack.lock b/lib/spack/spack/test/data/legacy_env/spack.lock
deleted file mode 100644
index 794a3f263c..0000000000
--- a/lib/spack/spack/test/data/legacy_env/spack.lock
+++ /dev/null
@@ -1,672 +0,0 @@
-{
- "_meta": {
- "file-type": "spack-lockfile",
- "lockfile-version": 3,
- "specfile-version": 2
- },
- "roots": [
- {
- "hash": "wci7a3aaaa4nj6ct6rj4aeltgbfojefy",
- "spec": "dttop ^dtbuild1@0.5"
- },
- {
- "hash": "5zg6wxwir2xien62soca6xaeilfzofz7",
- "spec": "dttop ^dtbuild1@1.0"
- }
- ],
- "concrete_specs": {
- "wci7a3aaaa4nj6ct6rj4aeltgbfojefy": {
- "name": "dttop",
- "version": "1.0",
- "arch": {
- "platform": "test",
- "platform_os": "debian6",
- "target": {
- "name": "core2",
- "vendor": "GenuineIntel",
- "features": [
- "mmx",
- "sse",
- "sse2",
- "ssse3"
- ],
- "generation": 0,
- "parents": [
- "nocona"
- ]
- }
- },
- "compiler": {
- "name": "gcc",
- "version": "4.5.0"
- },
- "namespace": "builtin.mock",
- "parameters": {
- "cflags": [],
- "cppflags": [],
- "cxxflags": [],
- "fflags": [],
- "ldflags": [],
- "ldlibs": []
- },
- "dependencies": [
- {
- "name": "dtbuild1",
- "build_hash": "qgpyperfcinui6o25aoglxzkdrlakf6b",
- "type": [
- "build"
- ]
- },
- {
- "name": "dtlink1",
- "build_hash": "4skh62lxn6gra5li7sqaeunzgaxjkbns",
- "type": [
- "build",
- "link"
- ]
- },
- {
- "name": "dtrun1",
- "build_hash": "upfcexeb7zwzxdsimesyzo42yz35bw2s",
- "type": [
- "run"
- ]
- }
- ],
- "hash": "foya4e4rtwl5ep4mq463sdeslgaoc3qu"
- },
- "qgpyperfcinui6o25aoglxzkdrlakf6b": {
- "name": "dtbuild1",
- "version": "0.5",
- "arch": {
- "platform": "test",
- "platform_os": "debian6",
- "target": {
- "name": "core2",
- "vendor": "GenuineIntel",
- "features": [
- "mmx",
- "sse",
- "sse2",
- "ssse3"
- ],
- "generation": 0,
- "parents": [
- "nocona"
- ]
- }
- },
- "compiler": {
- "name": "gcc",
- "version": "4.5.0"
- },
- "namespace": "builtin.mock",
- "parameters": {
- "cflags": [],
- "cppflags": [],
- "cxxflags": [],
- "fflags": [],
- "ldflags": [],
- "ldlibs": []
- },
- "dependencies": [
- {
- "name": "dtbuild2",
- "build_hash": "pq6krl6alw7ic5ix4g5izvlzt2llbvcp",
- "type": [
- "build"
- ]
- },
- {
- "name": "dtlink2",
- "build_hash": "5isttyk6zuekua2nqp23rrjpmcpo7y6a",
- "type": [
- "build",
- "link"
- ]
- },
- {
- "name": "dtrun2",
- "build_hash": "ypkyvbgxdzvverb7ami5rb6yxmp5ylmo",
- "type": [
- "run"
- ]
- }
- ],
- "hash": "lgcxyf3mkho6hpzymcvbetrvbujacufn"
- },
- "pq6krl6alw7ic5ix4g5izvlzt2llbvcp": {
- "name": "dtbuild2",
- "version": "1.0",
- "arch": {
- "platform": "test",
- "platform_os": "debian6",
- "target": {
- "name": "core2",
- "vendor": "GenuineIntel",
- "features": [
- "mmx",
- "sse",
- "sse2",
- "ssse3"
- ],
- "generation": 0,
- "parents": [
- "nocona"
- ]
- }
- },
- "compiler": {
- "name": "gcc",
- "version": "4.5.0"
- },
- "namespace": "builtin.mock",
- "parameters": {
- "cflags": [],
- "cppflags": [],
- "cxxflags": [],
- "fflags": [],
- "ldflags": [],
- "ldlibs": []
- },
- "hash": "pq6krl6alw7ic5ix4g5izvlzt2llbvcp"
- },
- "5isttyk6zuekua2nqp23rrjpmcpo7y6a": {
- "name": "dtlink2",
- "version": "1.0",
- "arch": {
- "platform": "test",
- "platform_os": "debian6",
- "target": {
- "name": "core2",
- "vendor": "GenuineIntel",
- "features": [
- "mmx",
- "sse",
- "sse2",
- "ssse3"
- ],
- "generation": 0,
- "parents": [
- "nocona"
- ]
- }
- },
- "compiler": {
- "name": "gcc",
- "version": "4.5.0"
- },
- "namespace": "builtin.mock",
- "parameters": {
- "cflags": [],
- "cppflags": [],
- "cxxflags": [],
- "fflags": [],
- "ldflags": [],
- "ldlibs": []
- },
- "hash": "5isttyk6zuekua2nqp23rrjpmcpo7y6a"
- },
- "ypkyvbgxdzvverb7ami5rb6yxmp5ylmo": {
- "name": "dtrun2",
- "version": "1.0",
- "arch": {
- "platform": "test",
- "platform_os": "debian6",
- "target": {
- "name": "core2",
- "vendor": "GenuineIntel",
- "features": [
- "mmx",
- "sse",
- "sse2",
- "ssse3"
- ],
- "generation": 0,
- "parents": [
- "nocona"
- ]
- }
- },
- "compiler": {
- "name": "gcc",
- "version": "4.5.0"
- },
- "namespace": "builtin.mock",
- "parameters": {
- "cflags": [],
- "cppflags": [],
- "cxxflags": [],
- "fflags": [],
- "ldflags": [],
- "ldlibs": []
- },
- "hash": "ypkyvbgxdzvverb7ami5rb6yxmp5ylmo"
- },
- "4skh62lxn6gra5li7sqaeunzgaxjkbns": {
- "name": "dtlink1",
- "version": "1.0",
- "arch": {
- "platform": "test",
- "platform_os": "debian6",
- "target": {
- "name": "core2",
- "vendor": "GenuineIntel",
- "features": [
- "mmx",
- "sse",
- "sse2",
- "ssse3"
- ],
- "generation": 0,
- "parents": [
- "nocona"
- ]
- }
- },
- "compiler": {
- "name": "gcc",
- "version": "4.5.0"
- },
- "namespace": "builtin.mock",
- "parameters": {
- "cflags": [],
- "cppflags": [],
- "cxxflags": [],
- "fflags": [],
- "ldflags": [],
- "ldlibs": []
- },
- "dependencies": [
- {
- "name": "dtlink3",
- "build_hash": "iq7m6ubgajdcnukktxolh7nc2z666h7r",
- "type": [
- "build",
- "link"
- ]
- }
- ],
- "hash": "4oxug37ghalgpxyzuurftzdvlr2a7wrz"
- },
- "iq7m6ubgajdcnukktxolh7nc2z666h7r": {
- "name": "dtlink3",
- "version": "1.0",
- "arch": {
- "platform": "test",
- "platform_os": "debian6",
- "target": {
- "name": "core2",
- "vendor": "GenuineIntel",
- "features": [
- "mmx",
- "sse",
- "sse2",
- "ssse3"
- ],
- "generation": 0,
- "parents": [
- "nocona"
- ]
- }
- },
- "compiler": {
- "name": "gcc",
- "version": "4.5.0"
- },
- "namespace": "builtin.mock",
- "parameters": {
- "cflags": [],
- "cppflags": [],
- "cxxflags": [],
- "fflags": [],
- "ldflags": [],
- "ldlibs": []
- },
- "dependencies": [
- {
- "name": "dtbuild2",
- "build_hash": "pq6krl6alw7ic5ix4g5izvlzt2llbvcp",
- "type": [
- "build"
- ]
- },
- {
- "name": "dtlink4",
- "build_hash": "kdt2sgmlahmfyjt3rc3mdvuoh7wdyoe3",
- "type": [
- "build",
- "link"
- ]
- }
- ],
- "hash": "n4j5jrvzgfnrvwwjwfycnk6n3ce2xk25"
- },
- "kdt2sgmlahmfyjt3rc3mdvuoh7wdyoe3": {
- "name": "dtlink4",
- "version": "1.0",
- "arch": {
- "platform": "test",
- "platform_os": "debian6",
- "target": {
- "name": "core2",
- "vendor": "GenuineIntel",
- "features": [
- "mmx",
- "sse",
- "sse2",
- "ssse3"
- ],
- "generation": 0,
- "parents": [
- "nocona"
- ]
- }
- },
- "compiler": {
- "name": "gcc",
- "version": "4.5.0"
- },
- "namespace": "builtin.mock",
- "parameters": {
- "cflags": [],
- "cppflags": [],
- "cxxflags": [],
- "fflags": [],
- "ldflags": [],
- "ldlibs": []
- },
- "hash": "kdt2sgmlahmfyjt3rc3mdvuoh7wdyoe3"
- },
- "upfcexeb7zwzxdsimesyzo42yz35bw2s": {
- "name": "dtrun1",
- "version": "1.0",
- "arch": {
- "platform": "test",
- "platform_os": "debian6",
- "target": {
- "name": "core2",
- "vendor": "GenuineIntel",
- "features": [
- "mmx",
- "sse",
- "sse2",
- "ssse3"
- ],
- "generation": 0,
- "parents": [
- "nocona"
- ]
- }
- },
- "compiler": {
- "name": "gcc",
- "version": "4.5.0"
- },
- "namespace": "builtin.mock",
- "parameters": {
- "cflags": [],
- "cppflags": [],
- "cxxflags": [],
- "fflags": [],
- "ldflags": [],
- "ldlibs": []
- },
- "dependencies": [
- {
- "name": "dtlink5",
- "build_hash": "bxpadcbd6xljttj5s5m3awlrt4zqztsh",
- "type": [
- "build",
- "link"
- ]
- },
- {
- "name": "dtrun3",
- "build_hash": "iqth4unmdwlv7zyw7joloh2lyuyvu6gb",
- "type": [
- "run"
- ]
- }
- ],
- "hash": "byqsjfa6hl27wpqbva5isxgbwdybgplb"
- },
- "bxpadcbd6xljttj5s5m3awlrt4zqztsh": {
- "name": "dtlink5",
- "version": "1.0",
- "arch": {
- "platform": "test",
- "platform_os": "debian6",
- "target": {
- "name": "core2",
- "vendor": "GenuineIntel",
- "features": [
- "mmx",
- "sse",
- "sse2",
- "ssse3"
- ],
- "generation": 0,
- "parents": [
- "nocona"
- ]
- }
- },
- "compiler": {
- "name": "gcc",
- "version": "4.5.0"
- },
- "namespace": "builtin.mock",
- "parameters": {
- "cflags": [],
- "cppflags": [],
- "cxxflags": [],
- "fflags": [],
- "ldflags": [],
- "ldlibs": []
- },
- "hash": "bxpadcbd6xljttj5s5m3awlrt4zqztsh"
- },
- "iqth4unmdwlv7zyw7joloh2lyuyvu6gb": {
- "name": "dtrun3",
- "version": "1.0",
- "arch": {
- "platform": "test",
- "platform_os": "debian6",
- "target": {
- "name": "core2",
- "vendor": "GenuineIntel",
- "features": [
- "mmx",
- "sse",
- "sse2",
- "ssse3"
- ],
- "generation": 0,
- "parents": [
- "nocona"
- ]
- }
- },
- "compiler": {
- "name": "gcc",
- "version": "4.5.0"
- },
- "namespace": "builtin.mock",
- "parameters": {
- "cflags": [],
- "cppflags": [],
- "cxxflags": [],
- "fflags": [],
- "ldflags": [],
- "ldlibs": []
- },
- "dependencies": [
- {
- "name": "dtbuild3",
- "build_hash": "t77enxfrcdrc6mumxzcdossrq4gvdliq",
- "type": [
- "build"
- ]
- }
- ],
- "hash": "beml5jys2cfxib6evml7ufn4wy2ak5by"
- },
- "t77enxfrcdrc6mumxzcdossrq4gvdliq": {
- "name": "dtbuild3",
- "version": "1.0",
- "arch": {
- "platform": "test",
- "platform_os": "debian6",
- "target": {
- "name": "core2",
- "vendor": "GenuineIntel",
- "features": [
- "mmx",
- "sse",
- "sse2",
- "ssse3"
- ],
- "generation": 0,
- "parents": [
- "nocona"
- ]
- }
- },
- "compiler": {
- "name": "gcc",
- "version": "4.5.0"
- },
- "namespace": "builtin.mock",
- "parameters": {
- "cflags": [],
- "cppflags": [],
- "cxxflags": [],
- "fflags": [],
- "ldflags": [],
- "ldlibs": []
- },
- "hash": "t77enxfrcdrc6mumxzcdossrq4gvdliq"
- },
- "5zg6wxwir2xien62soca6xaeilfzofz7": {
- "name": "dttop",
- "version": "1.0",
- "arch": {
- "platform": "test",
- "platform_os": "debian6",
- "target": {
- "name": "core2",
- "vendor": "GenuineIntel",
- "features": [
- "mmx",
- "sse",
- "sse2",
- "ssse3"
- ],
- "generation": 0,
- "parents": [
- "nocona"
- ]
- }
- },
- "compiler": {
- "name": "gcc",
- "version": "4.5.0"
- },
- "namespace": "builtin.mock",
- "parameters": {
- "cflags": [],
- "cppflags": [],
- "cxxflags": [],
- "fflags": [],
- "ldflags": [],
- "ldlibs": []
- },
- "dependencies": [
- {
- "name": "dtbuild1",
- "build_hash": "l7ikvcp4qgxtc4queb2kawhd267pylkn",
- "type": [
- "build"
- ]
- },
- {
- "name": "dtlink1",
- "build_hash": "4skh62lxn6gra5li7sqaeunzgaxjkbns",
- "type": [
- "build",
- "link"
- ]
- },
- {
- "name": "dtrun1",
- "build_hash": "upfcexeb7zwzxdsimesyzo42yz35bw2s",
- "type": [
- "run"
- ]
- }
- ],
- "hash": "foya4e4rtwl5ep4mq463sdeslgaoc3qu"
- },
- "l7ikvcp4qgxtc4queb2kawhd267pylkn": {
- "name": "dtbuild1",
- "version": "1.0",
- "arch": {
- "platform": "test",
- "platform_os": "debian6",
- "target": {
- "name": "core2",
- "vendor": "GenuineIntel",
- "features": [
- "mmx",
- "sse",
- "sse2",
- "ssse3"
- ],
- "generation": 0,
- "parents": [
- "nocona"
- ]
- }
- },
- "compiler": {
- "name": "gcc",
- "version": "4.5.0"
- },
- "namespace": "builtin.mock",
- "parameters": {
- "cflags": [],
- "cppflags": [],
- "cxxflags": [],
- "fflags": [],
- "ldflags": [],
- "ldlibs": []
- },
- "dependencies": [
- {
- "name": "dtbuild2",
- "build_hash": "pq6krl6alw7ic5ix4g5izvlzt2llbvcp",
- "type": [
- "build"
- ]
- },
- {
- "name": "dtlink2",
- "build_hash": "5isttyk6zuekua2nqp23rrjpmcpo7y6a",
- "type": [
- "build",
- "link"
- ]
- },
- {
- "name": "dtrun2",
- "build_hash": "ypkyvbgxdzvverb7ami5rb6yxmp5ylmo",
- "type": [
- "run"
- ]
- }
- ],
- "hash": "4tldi4u3p35juizd5y5pqushwiddwmbm"
- }
- }
-} \ No newline at end of file
diff --git a/lib/spack/spack/test/data/legacy_env/v1.lock b/lib/spack/spack/test/data/legacy_env/v1.lock
new file mode 100644
index 0000000000..20c1a21949
--- /dev/null
+++ b/lib/spack/spack/test/data/legacy_env/v1.lock
@@ -0,0 +1,383 @@
+{
+ "_meta": {
+ "file-type": "spack-lockfile",
+ "lockfile-version": 1
+ },
+ "roots": [
+ {
+ "hash": "rtc6yg6kszj6shpc4wfnnattyxcqdwbk",
+ "spec": "dttop ^dtbuild1@0.5"
+ },
+ {
+ "hash": "rtc6yg6kszj6shpc4wfnnattyxcqdwbk",
+ "spec": "dttop ^dtbuild1@1.0"
+ }
+ ],
+ "concrete_specs": {
+ "rtc6yg6kszj6shpc4wfnnattyxcqdwbk": {
+ "dttop": {
+ "version": "1.0",
+ "arch": {
+ "platform": "darwin",
+ "platform_os": "macos",
+ "target": "x86_64"
+ },
+ "compiler": {
+ "name": "clang",
+ "version": "13.0.0"
+ },
+ "namespace": "builtin.mock",
+ "parameters": {
+ "cflags": [],
+ "cppflags": [],
+ "cxxflags": [],
+ "fflags": [],
+ "ldflags": [],
+ "ldlibs": []
+ },
+ "dependencies": {
+ "dtbuild1": {
+ "hash": "dbfu5piza5tmsxd47ccdenbpnrt4cwxp",
+ "type": [
+ "build"
+ ]
+ },
+ "dtlink1": {
+ "hash": "zlgayt66nyopbltittef4ve7w75teyyw",
+ "type": [
+ "build",
+ "link"
+ ]
+ },
+ "dtrun1": {
+ "hash": "r23pvzyjxs2citoucn2atswjdlagqs3b",
+ "type": [
+ "run"
+ ]
+ }
+ }
+ }
+ },
+ "dbfu5piza5tmsxd47ccdenbpnrt4cwxp": {
+ "dtbuild1": {
+ "version": "1.0",
+ "arch": {
+ "platform": "darwin",
+ "platform_os": "macos",
+ "target": "x86_64"
+ },
+ "compiler": {
+ "name": "clang",
+ "version": "13.0.0"
+ },
+ "namespace": "builtin.mock",
+ "parameters": {
+ "cflags": [],
+ "cppflags": [],
+ "cxxflags": [],
+ "fflags": [],
+ "ldflags": [],
+ "ldlibs": []
+ },
+ "dependencies": {
+ "dtbuild2": {
+ "hash": "rzegrliakybnu33aafpezeohibhjfbey",
+ "type": [
+ "build"
+ ]
+ },
+ "dtlink2": {
+ "hash": "z4z2hz675fiulykkquhfsidnctvna2cv",
+ "type": [
+ "build",
+ "link"
+ ]
+ },
+ "dtrun2": {
+ "hash": "powghwfbyefncy7n3rohsaa7eurksm6m",
+ "type": [
+ "run"
+ ]
+ }
+ }
+ }
+ },
+ "rzegrliakybnu33aafpezeohibhjfbey": {
+ "dtbuild2": {
+ "version": "1.0",
+ "arch": {
+ "platform": "darwin",
+ "platform_os": "macos",
+ "target": "x86_64"
+ },
+ "compiler": {
+ "name": "clang",
+ "version": "13.0.0"
+ },
+ "namespace": "builtin.mock",
+ "parameters": {
+ "cflags": [],
+ "cppflags": [],
+ "cxxflags": [],
+ "fflags": [],
+ "ldflags": [],
+ "ldlibs": []
+ }
+ }
+ },
+ "z4z2hz675fiulykkquhfsidnctvna2cv": {
+ "dtlink2": {
+ "version": "1.0",
+ "arch": {
+ "platform": "darwin",
+ "platform_os": "macos",
+ "target": "x86_64"
+ },
+ "compiler": {
+ "name": "clang",
+ "version": "13.0.0"
+ },
+ "namespace": "builtin.mock",
+ "parameters": {
+ "cflags": [],
+ "cppflags": [],
+ "cxxflags": [],
+ "fflags": [],
+ "ldflags": [],
+ "ldlibs": []
+ }
+ }
+ },
+ "powghwfbyefncy7n3rohsaa7eurksm6m": {
+ "dtrun2": {
+ "version": "1.0",
+ "arch": {
+ "platform": "darwin",
+ "platform_os": "macos",
+ "target": "x86_64"
+ },
+ "compiler": {
+ "name": "clang",
+ "version": "13.0.0"
+ },
+ "namespace": "builtin.mock",
+ "parameters": {
+ "cflags": [],
+ "cppflags": [],
+ "cxxflags": [],
+ "fflags": [],
+ "ldflags": [],
+ "ldlibs": []
+ }
+ }
+ },
+ "zlgayt66nyopbltittef4ve7w75teyyw": {
+ "dtlink1": {
+ "version": "1.0",
+ "arch": {
+ "platform": "darwin",
+ "platform_os": "macos",
+ "target": "x86_64"
+ },
+ "compiler": {
+ "name": "clang",
+ "version": "13.0.0"
+ },
+ "namespace": "builtin.mock",
+ "parameters": {
+ "cflags": [],
+ "cppflags": [],
+ "cxxflags": [],
+ "fflags": [],
+ "ldflags": [],
+ "ldlibs": []
+ },
+ "dependencies": {
+ "dtlink3": {
+ "hash": "bjgkddw2inn42okhdzhdy4xcuqmdjlzv",
+ "type": [
+ "build",
+ "link"
+ ]
+ }
+ }
+ }
+ },
+ "bjgkddw2inn42okhdzhdy4xcuqmdjlzv": {
+ "dtlink3": {
+ "version": "1.0",
+ "arch": {
+ "platform": "darwin",
+ "platform_os": "macos",
+ "target": "x86_64"
+ },
+ "compiler": {
+ "name": "clang",
+ "version": "13.0.0"
+ },
+ "namespace": "builtin.mock",
+ "parameters": {
+ "cflags": [],
+ "cppflags": [],
+ "cxxflags": [],
+ "fflags": [],
+ "ldflags": [],
+ "ldlibs": []
+ },
+ "dependencies": {
+ "dtbuild2": {
+ "hash": "rzegrliakybnu33aafpezeohibhjfbey",
+ "type": [
+ "build"
+ ]
+ },
+ "dtlink4": {
+ "hash": "tvjtpacvyky4jlplt22krwshcwgyqcxd",
+ "type": [
+ "build",
+ "link"
+ ]
+ }
+ }
+ }
+ },
+ "tvjtpacvyky4jlplt22krwshcwgyqcxd": {
+ "dtlink4": {
+ "version": "1.0",
+ "arch": {
+ "platform": "darwin",
+ "platform_os": "macos",
+ "target": "x86_64"
+ },
+ "compiler": {
+ "name": "clang",
+ "version": "13.0.0"
+ },
+ "namespace": "builtin.mock",
+ "parameters": {
+ "cflags": [],
+ "cppflags": [],
+ "cxxflags": [],
+ "fflags": [],
+ "ldflags": [],
+ "ldlibs": []
+ }
+ }
+ },
+ "r23pvzyjxs2citoucn2atswjdlagqs3b": {
+ "dtrun1": {
+ "version": "1.0",
+ "arch": {
+ "platform": "darwin",
+ "platform_os": "macos",
+ "target": "x86_64"
+ },
+ "compiler": {
+ "name": "clang",
+ "version": "13.0.0"
+ },
+ "namespace": "builtin.mock",
+ "parameters": {
+ "cflags": [],
+ "cppflags": [],
+ "cxxflags": [],
+ "fflags": [],
+ "ldflags": [],
+ "ldlibs": []
+ },
+ "dependencies": {
+ "dtlink5": {
+ "hash": "e5gnrubxp2rl4l6gfit2qb65vrmudbny",
+ "type": [
+ "build",
+ "link"
+ ]
+ },
+ "dtrun3": {
+ "hash": "4qhelrleofze5wzr7freg2zesngxxusd",
+ "type": [
+ "run"
+ ]
+ }
+ }
+ }
+ },
+ "e5gnrubxp2rl4l6gfit2qb65vrmudbny": {
+ "dtlink5": {
+ "version": "1.0",
+ "arch": {
+ "platform": "darwin",
+ "platform_os": "macos",
+ "target": "x86_64"
+ },
+ "compiler": {
+ "name": "clang",
+ "version": "13.0.0"
+ },
+ "namespace": "builtin.mock",
+ "parameters": {
+ "cflags": [],
+ "cppflags": [],
+ "cxxflags": [],
+ "fflags": [],
+ "ldflags": [],
+ "ldlibs": []
+ }
+ }
+ },
+ "4qhelrleofze5wzr7freg2zesngxxusd": {
+ "dtrun3": {
+ "version": "1.0",
+ "arch": {
+ "platform": "darwin",
+ "platform_os": "macos",
+ "target": "x86_64"
+ },
+ "compiler": {
+ "name": "clang",
+ "version": "13.0.0"
+ },
+ "namespace": "builtin.mock",
+ "parameters": {
+ "cflags": [],
+ "cppflags": [],
+ "cxxflags": [],
+ "fflags": [],
+ "ldflags": [],
+ "ldlibs": []
+ },
+ "dependencies": {
+ "dtbuild3": {
+ "hash": "7qx3epm7xmhv7myz27pmik4je6berknr",
+ "type": [
+ "build"
+ ]
+ }
+ }
+ }
+ },
+ "7qx3epm7xmhv7myz27pmik4je6berknr": {
+ "dtbuild3": {
+ "version": "1.0",
+ "arch": {
+ "platform": "darwin",
+ "platform_os": "macos",
+ "target": "x86_64"
+ },
+ "compiler": {
+ "name": "clang",
+ "version": "13.0.0"
+ },
+ "namespace": "builtin.mock",
+ "parameters": {
+ "cflags": [],
+ "cppflags": [],
+ "cxxflags": [],
+ "fflags": [],
+ "ldflags": [],
+ "ldlibs": []
+ }
+ }
+ }
+ }
+}
diff --git a/lib/spack/spack/test/data/legacy_env/v2.lock b/lib/spack/spack/test/data/legacy_env/v2.lock
new file mode 100644
index 0000000000..f77451e939
--- /dev/null
+++ b/lib/spack/spack/test/data/legacy_env/v2.lock
@@ -0,0 +1,919 @@
+{
+ "_meta": {
+ "file-type": "spack-lockfile",
+ "lockfile-version": 2
+ },
+ "roots": [
+ {
+ "hash": "fvsxmvcsdvwx6uz44bytxu3jit4wxbxx",
+ "spec": "dttop ^dtbuild1@0.5"
+ },
+ {
+ "hash": "eymyqmyzk62nkbztpg7dmjnntznuaoy3",
+ "spec": "dttop ^dtbuild1@1.0"
+ }
+ ],
+ "concrete_specs": {
+ "fvsxmvcsdvwx6uz44bytxu3jit4wxbxx": {
+ "dttop": {
+ "version": "1.0",
+ "arch": {
+ "platform": "darwin",
+ "platform_os": "macos",
+ "target": {
+ "name": "skylake",
+ "vendor": "GenuineIntel",
+ "features": [
+ "adx",
+ "aes",
+ "avx",
+ "avx2",
+ "bmi1",
+ "bmi2",
+ "clflushopt",
+ "f16c",
+ "fma",
+ "mmx",
+ "movbe",
+ "pclmulqdq",
+ "popcnt",
+ "rdrand",
+ "rdseed",
+ "sse",
+ "sse2",
+ "sse4_1",
+ "sse4_2",
+ "ssse3",
+ "xsavec",
+ "xsaveopt"
+ ],
+ "generation": 0,
+ "parents": [
+ "broadwell"
+ ]
+ }
+ },
+ "compiler": {
+ "name": "apple-clang",
+ "version": "13.0.0"
+ },
+ "namespace": "builtin.mock",
+ "parameters": {
+ "cflags": [],
+ "cppflags": [],
+ "cxxflags": [],
+ "fflags": [],
+ "ldflags": [],
+ "ldlibs": []
+ },
+ "dependencies": {
+ "dtbuild1": {
+ "hash": "zw4o7pprzvvlmsofxj544jt7bdop7vyl",
+ "type": [
+ "build"
+ ]
+ },
+ "dtlink1": {
+ "hash": "fmsqm7vbwvxcibfzlcgo5ac5zly3bgox",
+ "type": [
+ "build",
+ "link"
+ ]
+ },
+ "dtrun1": {
+ "hash": "skcjwhzqovl2vumdbyjijmsn3dyhqbbb",
+ "type": [
+ "run"
+ ]
+ }
+ },
+ "hash": "bvzqjnqrl7abwal5azcbut2adbxjltxw"
+ }
+ },
+ "zw4o7pprzvvlmsofxj544jt7bdop7vyl": {
+ "dtbuild1": {
+ "version": "0.5",
+ "arch": {
+ "platform": "darwin",
+ "platform_os": "macos",
+ "target": {
+ "name": "skylake",
+ "vendor": "GenuineIntel",
+ "features": [
+ "adx",
+ "aes",
+ "avx",
+ "avx2",
+ "bmi1",
+ "bmi2",
+ "clflushopt",
+ "f16c",
+ "fma",
+ "mmx",
+ "movbe",
+ "pclmulqdq",
+ "popcnt",
+ "rdrand",
+ "rdseed",
+ "sse",
+ "sse2",
+ "sse4_1",
+ "sse4_2",
+ "ssse3",
+ "xsavec",
+ "xsaveopt"
+ ],
+ "generation": 0,
+ "parents": [
+ "broadwell"
+ ]
+ }
+ },
+ "compiler": {
+ "name": "apple-clang",
+ "version": "13.0.0"
+ },
+ "namespace": "builtin.mock",
+ "parameters": {
+ "cflags": [],
+ "cppflags": [],
+ "cxxflags": [],
+ "fflags": [],
+ "ldflags": [],
+ "ldlibs": []
+ },
+ "dependencies": {
+ "dtbuild2": {
+ "hash": "ojbqgzn53vd7do3ehbrwueyz4nk6xqin",
+ "type": [
+ "build"
+ ]
+ },
+ "dtlink2": {
+ "hash": "kpckvggymdnvjndepbqjz236upav5ymm",
+ "type": [
+ "build",
+ "link"
+ ]
+ },
+ "dtrun2": {
+ "hash": "4hj7adm23qwhtx5lxhy543jtkztvbcfe",
+ "type": [
+ "run"
+ ]
+ }
+ },
+ "hash": "nz7d6bnl2anbiwckijzbgpdukow2mlb4"
+ }
+ },
+ "ojbqgzn53vd7do3ehbrwueyz4nk6xqin": {
+ "dtbuild2": {
+ "version": "1.0",
+ "arch": {
+ "platform": "darwin",
+ "platform_os": "macos",
+ "target": {
+ "name": "skylake",
+ "vendor": "GenuineIntel",
+ "features": [
+ "adx",
+ "aes",
+ "avx",
+ "avx2",
+ "bmi1",
+ "bmi2",
+ "clflushopt",
+ "f16c",
+ "fma",
+ "mmx",
+ "movbe",
+ "pclmulqdq",
+ "popcnt",
+ "rdrand",
+ "rdseed",
+ "sse",
+ "sse2",
+ "sse4_1",
+ "sse4_2",
+ "ssse3",
+ "xsavec",
+ "xsaveopt"
+ ],
+ "generation": 0,
+ "parents": [
+ "broadwell"
+ ]
+ }
+ },
+ "compiler": {
+ "name": "apple-clang",
+ "version": "13.0.0"
+ },
+ "namespace": "builtin.mock",
+ "parameters": {
+ "cflags": [],
+ "cppflags": [],
+ "cxxflags": [],
+ "fflags": [],
+ "ldflags": [],
+ "ldlibs": []
+ },
+ "hash": "ojbqgzn53vd7do3ehbrwueyz4nk6xqin"
+ }
+ },
+ "kpckvggymdnvjndepbqjz236upav5ymm": {
+ "dtlink2": {
+ "version": "1.0",
+ "arch": {
+ "platform": "darwin",
+ "platform_os": "macos",
+ "target": {
+ "name": "skylake",
+ "vendor": "GenuineIntel",
+ "features": [
+ "adx",
+ "aes",
+ "avx",
+ "avx2",
+ "bmi1",
+ "bmi2",
+ "clflushopt",
+ "f16c",
+ "fma",
+ "mmx",
+ "movbe",
+ "pclmulqdq",
+ "popcnt",
+ "rdrand",
+ "rdseed",
+ "sse",
+ "sse2",
+ "sse4_1",
+ "sse4_2",
+ "ssse3",
+ "xsavec",
+ "xsaveopt"
+ ],
+ "generation": 0,
+ "parents": [
+ "broadwell"
+ ]
+ }
+ },
+ "compiler": {
+ "name": "apple-clang",
+ "version": "13.0.0"
+ },
+ "namespace": "builtin.mock",
+ "parameters": {
+ "cflags": [],
+ "cppflags": [],
+ "cxxflags": [],
+ "fflags": [],
+ "ldflags": [],
+ "ldlibs": []
+ },
+ "hash": "kpckvggymdnvjndepbqjz236upav5ymm"
+ }
+ },
+ "4hj7adm23qwhtx5lxhy543jtkztvbcfe": {
+ "dtrun2": {
+ "version": "1.0",
+ "arch": {
+ "platform": "darwin",
+ "platform_os": "macos",
+ "target": {
+ "name": "skylake",
+ "vendor": "GenuineIntel",
+ "features": [
+ "adx",
+ "aes",
+ "avx",
+ "avx2",
+ "bmi1",
+ "bmi2",
+ "clflushopt",
+ "f16c",
+ "fma",
+ "mmx",
+ "movbe",
+ "pclmulqdq",
+ "popcnt",
+ "rdrand",
+ "rdseed",
+ "sse",
+ "sse2",
+ "sse4_1",
+ "sse4_2",
+ "ssse3",
+ "xsavec",
+ "xsaveopt"
+ ],
+ "generation": 0,
+ "parents": [
+ "broadwell"
+ ]
+ }
+ },
+ "compiler": {
+ "name": "apple-clang",
+ "version": "13.0.0"
+ },
+ "namespace": "builtin.mock",
+ "parameters": {
+ "cflags": [],
+ "cppflags": [],
+ "cxxflags": [],
+ "fflags": [],
+ "ldflags": [],
+ "ldlibs": []
+ },
+ "hash": "4hj7adm23qwhtx5lxhy543jtkztvbcfe"
+ }
+ },
+ "fmsqm7vbwvxcibfzlcgo5ac5zly3bgox": {
+ "dtlink1": {
+ "version": "1.0",
+ "arch": {
+ "platform": "darwin",
+ "platform_os": "macos",
+ "target": {
+ "name": "skylake",
+ "vendor": "GenuineIntel",
+ "features": [
+ "adx",
+ "aes",
+ "avx",
+ "avx2",
+ "bmi1",
+ "bmi2",
+ "clflushopt",
+ "f16c",
+ "fma",
+ "mmx",
+ "movbe",
+ "pclmulqdq",
+ "popcnt",
+ "rdrand",
+ "rdseed",
+ "sse",
+ "sse2",
+ "sse4_1",
+ "sse4_2",
+ "ssse3",
+ "xsavec",
+ "xsaveopt"
+ ],
+ "generation": 0,
+ "parents": [
+ "broadwell"
+ ]
+ }
+ },
+ "compiler": {
+ "name": "apple-clang",
+ "version": "13.0.0"
+ },
+ "namespace": "builtin.mock",
+ "parameters": {
+ "cflags": [],
+ "cppflags": [],
+ "cxxflags": [],
+ "fflags": [],
+ "ldflags": [],
+ "ldlibs": []
+ },
+ "dependencies": {
+ "dtlink3": {
+ "hash": "clkcipbhtglfceg6j5b7qklri33msmy3",
+ "type": [
+ "build",
+ "link"
+ ]
+ }
+ },
+ "hash": "bwi2mxyehnjoxp7kpkhoxbloh2tvmz2l"
+ }
+ },
+ "clkcipbhtglfceg6j5b7qklri33msmy3": {
+ "dtlink3": {
+ "version": "1.0",
+ "arch": {
+ "platform": "darwin",
+ "platform_os": "macos",
+ "target": {
+ "name": "skylake",
+ "vendor": "GenuineIntel",
+ "features": [
+ "adx",
+ "aes",
+ "avx",
+ "avx2",
+ "bmi1",
+ "bmi2",
+ "clflushopt",
+ "f16c",
+ "fma",
+ "mmx",
+ "movbe",
+ "pclmulqdq",
+ "popcnt",
+ "rdrand",
+ "rdseed",
+ "sse",
+ "sse2",
+ "sse4_1",
+ "sse4_2",
+ "ssse3",
+ "xsavec",
+ "xsaveopt"
+ ],
+ "generation": 0,
+ "parents": [
+ "broadwell"
+ ]
+ }
+ },
+ "compiler": {
+ "name": "apple-clang",
+ "version": "13.0.0"
+ },
+ "namespace": "builtin.mock",
+ "parameters": {
+ "cflags": [],
+ "cppflags": [],
+ "cxxflags": [],
+ "fflags": [],
+ "ldflags": [],
+ "ldlibs": []
+ },
+ "dependencies": {
+ "dtbuild2": {
+ "hash": "ojbqgzn53vd7do3ehbrwueyz4nk6xqin",
+ "type": [
+ "build"
+ ]
+ },
+ "dtlink4": {
+ "hash": "gznxlq6w5f274fngfrwsotcrg2gnkigp",
+ "type": [
+ "build",
+ "link"
+ ]
+ }
+ },
+ "hash": "3ty6ao54qcoejcnckim6aygo64bxajqm"
+ }
+ },
+ "gznxlq6w5f274fngfrwsotcrg2gnkigp": {
+ "dtlink4": {
+ "version": "1.0",
+ "arch": {
+ "platform": "darwin",
+ "platform_os": "macos",
+ "target": {
+ "name": "skylake",
+ "vendor": "GenuineIntel",
+ "features": [
+ "adx",
+ "aes",
+ "avx",
+ "avx2",
+ "bmi1",
+ "bmi2",
+ "clflushopt",
+ "f16c",
+ "fma",
+ "mmx",
+ "movbe",
+ "pclmulqdq",
+ "popcnt",
+ "rdrand",
+ "rdseed",
+ "sse",
+ "sse2",
+ "sse4_1",
+ "sse4_2",
+ "ssse3",
+ "xsavec",
+ "xsaveopt"
+ ],
+ "generation": 0,
+ "parents": [
+ "broadwell"
+ ]
+ }
+ },
+ "compiler": {
+ "name": "apple-clang",
+ "version": "13.0.0"
+ },
+ "namespace": "builtin.mock",
+ "parameters": {
+ "cflags": [],
+ "cppflags": [],
+ "cxxflags": [],
+ "fflags": [],
+ "ldflags": [],
+ "ldlibs": []
+ },
+ "hash": "gznxlq6w5f274fngfrwsotcrg2gnkigp"
+ }
+ },
+ "skcjwhzqovl2vumdbyjijmsn3dyhqbbb": {
+ "dtrun1": {
+ "version": "1.0",
+ "arch": {
+ "platform": "darwin",
+ "platform_os": "macos",
+ "target": {
+ "name": "skylake",
+ "vendor": "GenuineIntel",
+ "features": [
+ "adx",
+ "aes",
+ "avx",
+ "avx2",
+ "bmi1",
+ "bmi2",
+ "clflushopt",
+ "f16c",
+ "fma",
+ "mmx",
+ "movbe",
+ "pclmulqdq",
+ "popcnt",
+ "rdrand",
+ "rdseed",
+ "sse",
+ "sse2",
+ "sse4_1",
+ "sse4_2",
+ "ssse3",
+ "xsavec",
+ "xsaveopt"
+ ],
+ "generation": 0,
+ "parents": [
+ "broadwell"
+ ]
+ }
+ },
+ "compiler": {
+ "name": "apple-clang",
+ "version": "13.0.0"
+ },
+ "namespace": "builtin.mock",
+ "parameters": {
+ "cflags": [],
+ "cppflags": [],
+ "cxxflags": [],
+ "fflags": [],
+ "ldflags": [],
+ "ldlibs": []
+ },
+ "dependencies": {
+ "dtlink5": {
+ "hash": "y557umbvt4y57wxc4ktwkixzguai3dio",
+ "type": [
+ "build",
+ "link"
+ ]
+ },
+ "dtrun3": {
+ "hash": "kmcnoznhtf4qgkxrfcsitzthiqswci3t",
+ "type": [
+ "run"
+ ]
+ }
+ },
+ "hash": "5eh47vivjja4zgrvkconqt47ptsnggpj"
+ }
+ },
+ "y557umbvt4y57wxc4ktwkixzguai3dio": {
+ "dtlink5": {
+ "version": "1.0",
+ "arch": {
+ "platform": "darwin",
+ "platform_os": "macos",
+ "target": {
+ "name": "skylake",
+ "vendor": "GenuineIntel",
+ "features": [
+ "adx",
+ "aes",
+ "avx",
+ "avx2",
+ "bmi1",
+ "bmi2",
+ "clflushopt",
+ "f16c",
+ "fma",
+ "mmx",
+ "movbe",
+ "pclmulqdq",
+ "popcnt",
+ "rdrand",
+ "rdseed",
+ "sse",
+ "sse2",
+ "sse4_1",
+ "sse4_2",
+ "ssse3",
+ "xsavec",
+ "xsaveopt"
+ ],
+ "generation": 0,
+ "parents": [
+ "broadwell"
+ ]
+ }
+ },
+ "compiler": {
+ "name": "apple-clang",
+ "version": "13.0.0"
+ },
+ "namespace": "builtin.mock",
+ "parameters": {
+ "cflags": [],
+ "cppflags": [],
+ "cxxflags": [],
+ "fflags": [],
+ "ldflags": [],
+ "ldlibs": []
+ },
+ "hash": "y557umbvt4y57wxc4ktwkixzguai3dio"
+ }
+ },
+ "kmcnoznhtf4qgkxrfcsitzthiqswci3t": {
+ "dtrun3": {
+ "version": "1.0",
+ "arch": {
+ "platform": "darwin",
+ "platform_os": "macos",
+ "target": {
+ "name": "skylake",
+ "vendor": "GenuineIntel",
+ "features": [
+ "adx",
+ "aes",
+ "avx",
+ "avx2",
+ "bmi1",
+ "bmi2",
+ "clflushopt",
+ "f16c",
+ "fma",
+ "mmx",
+ "movbe",
+ "pclmulqdq",
+ "popcnt",
+ "rdrand",
+ "rdseed",
+ "sse",
+ "sse2",
+ "sse4_1",
+ "sse4_2",
+ "ssse3",
+ "xsavec",
+ "xsaveopt"
+ ],
+ "generation": 0,
+ "parents": [
+ "broadwell"
+ ]
+ }
+ },
+ "compiler": {
+ "name": "apple-clang",
+ "version": "13.0.0"
+ },
+ "namespace": "builtin.mock",
+ "parameters": {
+ "cflags": [],
+ "cppflags": [],
+ "cxxflags": [],
+ "fflags": [],
+ "ldflags": [],
+ "ldlibs": []
+ },
+ "dependencies": {
+ "dtbuild3": {
+ "hash": "ms6xv6czf2dw7gal3cx5gzmgp3zw25z7",
+ "type": [
+ "build"
+ ]
+ }
+ },
+ "hash": "at5j7haicypoprvn37rclbv7wtfotdm4"
+ }
+ },
+ "ms6xv6czf2dw7gal3cx5gzmgp3zw25z7": {
+ "dtbuild3": {
+ "version": "1.0",
+ "arch": {
+ "platform": "darwin",
+ "platform_os": "macos",
+ "target": {
+ "name": "skylake",
+ "vendor": "GenuineIntel",
+ "features": [
+ "adx",
+ "aes",
+ "avx",
+ "avx2",
+ "bmi1",
+ "bmi2",
+ "clflushopt",
+ "f16c",
+ "fma",
+ "mmx",
+ "movbe",
+ "pclmulqdq",
+ "popcnt",
+ "rdrand",
+ "rdseed",
+ "sse",
+ "sse2",
+ "sse4_1",
+ "sse4_2",
+ "ssse3",
+ "xsavec",
+ "xsaveopt"
+ ],
+ "generation": 0,
+ "parents": [
+ "broadwell"
+ ]
+ }
+ },
+ "compiler": {
+ "name": "apple-clang",
+ "version": "13.0.0"
+ },
+ "namespace": "builtin.mock",
+ "parameters": {
+ "cflags": [],
+ "cppflags": [],
+ "cxxflags": [],
+ "fflags": [],
+ "ldflags": [],
+ "ldlibs": []
+ },
+ "hash": "ms6xv6czf2dw7gal3cx5gzmgp3zw25z7"
+ }
+ },
+ "eymyqmyzk62nkbztpg7dmjnntznuaoy3": {
+ "dttop": {
+ "version": "1.0",
+ "arch": {
+ "platform": "darwin",
+ "platform_os": "macos",
+ "target": {
+ "name": "skylake",
+ "vendor": "GenuineIntel",
+ "features": [
+ "adx",
+ "aes",
+ "avx",
+ "avx2",
+ "bmi1",
+ "bmi2",
+ "clflushopt",
+ "f16c",
+ "fma",
+ "mmx",
+ "movbe",
+ "pclmulqdq",
+ "popcnt",
+ "rdrand",
+ "rdseed",
+ "sse",
+ "sse2",
+ "sse4_1",
+ "sse4_2",
+ "ssse3",
+ "xsavec",
+ "xsaveopt"
+ ],
+ "generation": 0,
+ "parents": [
+ "broadwell"
+ ]
+ }
+ },
+ "compiler": {
+ "name": "apple-clang",
+ "version": "13.0.0"
+ },
+ "namespace": "builtin.mock",
+ "parameters": {
+ "cflags": [],
+ "cppflags": [],
+ "cxxflags": [],
+ "fflags": [],
+ "ldflags": [],
+ "ldlibs": []
+ },
+ "dependencies": {
+ "dtbuild1": {
+ "hash": "jdcbg7gynk3xybuwurmqnpu7f3f4lyru",
+ "type": [
+ "build"
+ ]
+ },
+ "dtlink1": {
+ "hash": "fmsqm7vbwvxcibfzlcgo5ac5zly3bgox",
+ "type": [
+ "build",
+ "link"
+ ]
+ },
+ "dtrun1": {
+ "hash": "skcjwhzqovl2vumdbyjijmsn3dyhqbbb",
+ "type": [
+ "run"
+ ]
+ }
+ },
+ "hash": "bvzqjnqrl7abwal5azcbut2adbxjltxw"
+ }
+ },
+ "jdcbg7gynk3xybuwurmqnpu7f3f4lyru": {
+ "dtbuild1": {
+ "version": "1.0",
+ "arch": {
+ "platform": "darwin",
+ "platform_os": "macos",
+ "target": {
+ "name": "skylake",
+ "vendor": "GenuineIntel",
+ "features": [
+ "adx",
+ "aes",
+ "avx",
+ "avx2",
+ "bmi1",
+ "bmi2",
+ "clflushopt",
+ "f16c",
+ "fma",
+ "mmx",
+ "movbe",
+ "pclmulqdq",
+ "popcnt",
+ "rdrand",
+ "rdseed",
+ "sse",
+ "sse2",
+ "sse4_1",
+ "sse4_2",
+ "ssse3",
+ "xsavec",
+ "xsaveopt"
+ ],
+ "generation": 0,
+ "parents": [
+ "broadwell"
+ ]
+ }
+ },
+ "compiler": {
+ "name": "apple-clang",
+ "version": "13.0.0"
+ },
+ "namespace": "builtin.mock",
+ "parameters": {
+ "cflags": [],
+ "cppflags": [],
+ "cxxflags": [],
+ "fflags": [],
+ "ldflags": [],
+ "ldlibs": []
+ },
+ "dependencies": {
+ "dtbuild2": {
+ "hash": "ojbqgzn53vd7do3ehbrwueyz4nk6xqin",
+ "type": [
+ "build"
+ ]
+ },
+ "dtlink2": {
+ "hash": "kpckvggymdnvjndepbqjz236upav5ymm",
+ "type": [
+ "build",
+ "link"
+ ]
+ },
+ "dtrun2": {
+ "hash": "4hj7adm23qwhtx5lxhy543jtkztvbcfe",
+ "type": [
+ "run"
+ ]
+ }
+ },
+ "hash": "4a6yogpekskoz6kznhgwv6vdbyhoh4yy"
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/lib/spack/spack/test/data/legacy_env/v3.lock b/lib/spack/spack/test/data/legacy_env/v3.lock
new file mode 100644
index 0000000000..97f0eb926c
--- /dev/null
+++ b/lib/spack/spack/test/data/legacy_env/v3.lock
@@ -0,0 +1,924 @@
+{
+ "_meta": {
+ "file-type": "spack-lockfile",
+ "lockfile-version": 3,
+ "specfile-version": 2
+ },
+ "roots": [
+ {
+ "hash": "bzapmjnw5faayjwdemyipyky4wdksh5t",
+ "spec": "dttop ^dtbuild1@0.5"
+ },
+ {
+ "hash": "2n4kyt2vzexalndoo46aa63vclquruuk",
+ "spec": "dttop ^dtbuild1@1.0"
+ }
+ ],
+ "concrete_specs": {
+ "bzapmjnw5faayjwdemyipyky4wdksh5t": {
+ "name": "dttop",
+ "version": "1.0",
+ "arch": {
+ "platform": "darwin",
+ "platform_os": "bigsur",
+ "target": {
+ "name": "skylake",
+ "vendor": "GenuineIntel",
+ "features": [
+ "adx",
+ "aes",
+ "avx",
+ "avx2",
+ "bmi1",
+ "bmi2",
+ "clflushopt",
+ "f16c",
+ "fma",
+ "mmx",
+ "movbe",
+ "pclmulqdq",
+ "popcnt",
+ "rdrand",
+ "rdseed",
+ "sse",
+ "sse2",
+ "sse4_1",
+ "sse4_2",
+ "ssse3",
+ "xsavec",
+ "xsaveopt"
+ ],
+ "generation": 0,
+ "parents": [
+ "broadwell"
+ ]
+ }
+ },
+ "compiler": {
+ "name": "apple-clang",
+ "version": "13.0.0"
+ },
+ "namespace": "builtin.mock",
+ "parameters": {
+ "cflags": [],
+ "cppflags": [],
+ "cxxflags": [],
+ "fflags": [],
+ "ldflags": [],
+ "ldlibs": []
+ },
+ "dependencies": [
+ {
+ "name": "dtbuild1",
+ "build_hash": "hu3l6iyiyhfhgpljz6mm2arkzatex5kl",
+ "type": [
+ "build"
+ ]
+ },
+ {
+ "name": "dtlink1",
+ "build_hash": "seallhwetilvtxoxaun3zvauga6erllj",
+ "type": [
+ "build",
+ "link"
+ ]
+ },
+ {
+ "name": "dtrun1",
+ "build_hash": "s7wjy5kbni43lswlhsdywh7fsz3kruax",
+ "type": [
+ "run"
+ ]
+ }
+ ],
+ "hash": "m5m2tbnyh2xnjd4nzwiuobvpk2wn4wix"
+ },
+ "hu3l6iyiyhfhgpljz6mm2arkzatex5kl": {
+ "name": "dtbuild1",
+ "version": "0.5",
+ "arch": {
+ "platform": "darwin",
+ "platform_os": "bigsur",
+ "target": {
+ "name": "skylake",
+ "vendor": "GenuineIntel",
+ "features": [
+ "adx",
+ "aes",
+ "avx",
+ "avx2",
+ "bmi1",
+ "bmi2",
+ "clflushopt",
+ "f16c",
+ "fma",
+ "mmx",
+ "movbe",
+ "pclmulqdq",
+ "popcnt",
+ "rdrand",
+ "rdseed",
+ "sse",
+ "sse2",
+ "sse4_1",
+ "sse4_2",
+ "ssse3",
+ "xsavec",
+ "xsaveopt"
+ ],
+ "generation": 0,
+ "parents": [
+ "broadwell"
+ ]
+ }
+ },
+ "compiler": {
+ "name": "apple-clang",
+ "version": "13.0.0"
+ },
+ "namespace": "builtin.mock",
+ "parameters": {
+ "cflags": [],
+ "cppflags": [],
+ "cxxflags": [],
+ "fflags": [],
+ "ldflags": [],
+ "ldlibs": []
+ },
+ "dependencies": [
+ {
+ "name": "dtbuild2",
+ "build_hash": "pk3aetkbsbsktaslbuthagh746f2nj72",
+ "type": [
+ "build"
+ ]
+ },
+ {
+ "name": "dtlink2",
+ "build_hash": "rmgjkspuni3egfwusig4xlotnd74hgik",
+ "type": [
+ "build",
+ "link"
+ ]
+ },
+ {
+ "name": "dtrun2",
+ "build_hash": "ehpgq3io4lcrlfucjwxt2t64q7ibxqy4",
+ "type": [
+ "run"
+ ]
+ }
+ ],
+ "hash": "pyxv3jfcry5my4ebahaktbk6vral4gcg"
+ },
+ "pk3aetkbsbsktaslbuthagh746f2nj72": {
+ "name": "dtbuild2",
+ "version": "1.0",
+ "arch": {
+ "platform": "darwin",
+ "platform_os": "bigsur",
+ "target": {
+ "name": "skylake",
+ "vendor": "GenuineIntel",
+ "features": [
+ "adx",
+ "aes",
+ "avx",
+ "avx2",
+ "bmi1",
+ "bmi2",
+ "clflushopt",
+ "f16c",
+ "fma",
+ "mmx",
+ "movbe",
+ "pclmulqdq",
+ "popcnt",
+ "rdrand",
+ "rdseed",
+ "sse",
+ "sse2",
+ "sse4_1",
+ "sse4_2",
+ "ssse3",
+ "xsavec",
+ "xsaveopt"
+ ],
+ "generation": 0,
+ "parents": [
+ "broadwell"
+ ]
+ }
+ },
+ "compiler": {
+ "name": "apple-clang",
+ "version": "13.0.0"
+ },
+ "namespace": "builtin.mock",
+ "parameters": {
+ "cflags": [],
+ "cppflags": [],
+ "cxxflags": [],
+ "fflags": [],
+ "ldflags": [],
+ "ldlibs": []
+ },
+ "hash": "pk3aetkbsbsktaslbuthagh746f2nj72"
+ },
+ "rmgjkspuni3egfwusig4xlotnd74hgik": {
+ "name": "dtlink2",
+ "version": "1.0",
+ "arch": {
+ "platform": "darwin",
+ "platform_os": "bigsur",
+ "target": {
+ "name": "skylake",
+ "vendor": "GenuineIntel",
+ "features": [
+ "adx",
+ "aes",
+ "avx",
+ "avx2",
+ "bmi1",
+ "bmi2",
+ "clflushopt",
+ "f16c",
+ "fma",
+ "mmx",
+ "movbe",
+ "pclmulqdq",
+ "popcnt",
+ "rdrand",
+ "rdseed",
+ "sse",
+ "sse2",
+ "sse4_1",
+ "sse4_2",
+ "ssse3",
+ "xsavec",
+ "xsaveopt"
+ ],
+ "generation": 0,
+ "parents": [
+ "broadwell"
+ ]
+ }
+ },
+ "compiler": {
+ "name": "apple-clang",
+ "version": "13.0.0"
+ },
+ "namespace": "builtin.mock",
+ "parameters": {
+ "cflags": [],
+ "cppflags": [],
+ "cxxflags": [],
+ "fflags": [],
+ "ldflags": [],
+ "ldlibs": []
+ },
+ "hash": "rmgjkspuni3egfwusig4xlotnd74hgik"
+ },
+ "ehpgq3io4lcrlfucjwxt2t64q7ibxqy4": {
+ "name": "dtrun2",
+ "version": "1.0",
+ "arch": {
+ "platform": "darwin",
+ "platform_os": "bigsur",
+ "target": {
+ "name": "skylake",
+ "vendor": "GenuineIntel",
+ "features": [
+ "adx",
+ "aes",
+ "avx",
+ "avx2",
+ "bmi1",
+ "bmi2",
+ "clflushopt",
+ "f16c",
+ "fma",
+ "mmx",
+ "movbe",
+ "pclmulqdq",
+ "popcnt",
+ "rdrand",
+ "rdseed",
+ "sse",
+ "sse2",
+ "sse4_1",
+ "sse4_2",
+ "ssse3",
+ "xsavec",
+ "xsaveopt"
+ ],
+ "generation": 0,
+ "parents": [
+ "broadwell"
+ ]
+ }
+ },
+ "compiler": {
+ "name": "apple-clang",
+ "version": "13.0.0"
+ },
+ "namespace": "builtin.mock",
+ "parameters": {
+ "cflags": [],
+ "cppflags": [],
+ "cxxflags": [],
+ "fflags": [],
+ "ldflags": [],
+ "ldlibs": []
+ },
+ "hash": "ehpgq3io4lcrlfucjwxt2t64q7ibxqy4"
+ },
+ "seallhwetilvtxoxaun3zvauga6erllj": {
+ "name": "dtlink1",
+ "version": "1.0",
+ "arch": {
+ "platform": "darwin",
+ "platform_os": "bigsur",
+ "target": {
+ "name": "skylake",
+ "vendor": "GenuineIntel",
+ "features": [
+ "adx",
+ "aes",
+ "avx",
+ "avx2",
+ "bmi1",
+ "bmi2",
+ "clflushopt",
+ "f16c",
+ "fma",
+ "mmx",
+ "movbe",
+ "pclmulqdq",
+ "popcnt",
+ "rdrand",
+ "rdseed",
+ "sse",
+ "sse2",
+ "sse4_1",
+ "sse4_2",
+ "ssse3",
+ "xsavec",
+ "xsaveopt"
+ ],
+ "generation": 0,
+ "parents": [
+ "broadwell"
+ ]
+ }
+ },
+ "compiler": {
+ "name": "apple-clang",
+ "version": "13.0.0"
+ },
+ "namespace": "builtin.mock",
+ "parameters": {
+ "cflags": [],
+ "cppflags": [],
+ "cxxflags": [],
+ "fflags": [],
+ "ldflags": [],
+ "ldlibs": []
+ },
+ "dependencies": [
+ {
+ "name": "dtlink3",
+ "build_hash": "xe6nm3jplyqo6pi3yag6h23oekcy45ie",
+ "type": [
+ "build",
+ "link"
+ ]
+ }
+ ],
+ "hash": "gm4epmarycggqb3bsergwfiusz3hcqdn"
+ },
+ "xe6nm3jplyqo6pi3yag6h23oekcy45ie": {
+ "name": "dtlink3",
+ "version": "1.0",
+ "arch": {
+ "platform": "darwin",
+ "platform_os": "bigsur",
+ "target": {
+ "name": "skylake",
+ "vendor": "GenuineIntel",
+ "features": [
+ "adx",
+ "aes",
+ "avx",
+ "avx2",
+ "bmi1",
+ "bmi2",
+ "clflushopt",
+ "f16c",
+ "fma",
+ "mmx",
+ "movbe",
+ "pclmulqdq",
+ "popcnt",
+ "rdrand",
+ "rdseed",
+ "sse",
+ "sse2",
+ "sse4_1",
+ "sse4_2",
+ "ssse3",
+ "xsavec",
+ "xsaveopt"
+ ],
+ "generation": 0,
+ "parents": [
+ "broadwell"
+ ]
+ }
+ },
+ "compiler": {
+ "name": "apple-clang",
+ "version": "13.0.0"
+ },
+ "namespace": "builtin.mock",
+ "parameters": {
+ "cflags": [],
+ "cppflags": [],
+ "cxxflags": [],
+ "fflags": [],
+ "ldflags": [],
+ "ldlibs": []
+ },
+ "dependencies": [
+ {
+ "name": "dtbuild2",
+ "build_hash": "pk3aetkbsbsktaslbuthagh746f2nj72",
+ "type": [
+ "build"
+ ]
+ },
+ {
+ "name": "dtlink4",
+ "build_hash": "6c5wagoxq3jeo6uuvyql56yqna4rm2cx",
+ "type": [
+ "build",
+ "link"
+ ]
+ }
+ ],
+ "hash": "iuj6oe423ocaabhlrhhyf45o54r3u4ny"
+ },
+ "6c5wagoxq3jeo6uuvyql56yqna4rm2cx": {
+ "name": "dtlink4",
+ "version": "1.0",
+ "arch": {
+ "platform": "darwin",
+ "platform_os": "bigsur",
+ "target": {
+ "name": "skylake",
+ "vendor": "GenuineIntel",
+ "features": [
+ "adx",
+ "aes",
+ "avx",
+ "avx2",
+ "bmi1",
+ "bmi2",
+ "clflushopt",
+ "f16c",
+ "fma",
+ "mmx",
+ "movbe",
+ "pclmulqdq",
+ "popcnt",
+ "rdrand",
+ "rdseed",
+ "sse",
+ "sse2",
+ "sse4_1",
+ "sse4_2",
+ "ssse3",
+ "xsavec",
+ "xsaveopt"
+ ],
+ "generation": 0,
+ "parents": [
+ "broadwell"
+ ]
+ }
+ },
+ "compiler": {
+ "name": "apple-clang",
+ "version": "13.0.0"
+ },
+ "namespace": "builtin.mock",
+ "parameters": {
+ "cflags": [],
+ "cppflags": [],
+ "cxxflags": [],
+ "fflags": [],
+ "ldflags": [],
+ "ldlibs": []
+ },
+ "hash": "6c5wagoxq3jeo6uuvyql56yqna4rm2cx"
+ },
+ "s7wjy5kbni43lswlhsdywh7fsz3kruax": {
+ "name": "dtrun1",
+ "version": "1.0",
+ "arch": {
+ "platform": "darwin",
+ "platform_os": "bigsur",
+ "target": {
+ "name": "skylake",
+ "vendor": "GenuineIntel",
+ "features": [
+ "adx",
+ "aes",
+ "avx",
+ "avx2",
+ "bmi1",
+ "bmi2",
+ "clflushopt",
+ "f16c",
+ "fma",
+ "mmx",
+ "movbe",
+ "pclmulqdq",
+ "popcnt",
+ "rdrand",
+ "rdseed",
+ "sse",
+ "sse2",
+ "sse4_1",
+ "sse4_2",
+ "ssse3",
+ "xsavec",
+ "xsaveopt"
+ ],
+ "generation": 0,
+ "parents": [
+ "broadwell"
+ ]
+ }
+ },
+ "compiler": {
+ "name": "apple-clang",
+ "version": "13.0.0"
+ },
+ "namespace": "builtin.mock",
+ "parameters": {
+ "cflags": [],
+ "cppflags": [],
+ "cxxflags": [],
+ "fflags": [],
+ "ldflags": [],
+ "ldlibs": []
+ },
+ "dependencies": [
+ {
+ "name": "dtlink5",
+ "build_hash": "qphelcbihtf4umgz6h66ppikwn3ernif",
+ "type": [
+ "build",
+ "link"
+ ]
+ },
+ {
+ "name": "dtrun3",
+ "build_hash": "kierl2q24kzqcl35r5o6rj3ecg2463yn",
+ "type": [
+ "run"
+ ]
+ }
+ ],
+ "hash": "axoyavsuklr3jdzx3lljffqfmiqmq5xj"
+ },
+ "qphelcbihtf4umgz6h66ppikwn3ernif": {
+ "name": "dtlink5",
+ "version": "1.0",
+ "arch": {
+ "platform": "darwin",
+ "platform_os": "bigsur",
+ "target": {
+ "name": "skylake",
+ "vendor": "GenuineIntel",
+ "features": [
+ "adx",
+ "aes",
+ "avx",
+ "avx2",
+ "bmi1",
+ "bmi2",
+ "clflushopt",
+ "f16c",
+ "fma",
+ "mmx",
+ "movbe",
+ "pclmulqdq",
+ "popcnt",
+ "rdrand",
+ "rdseed",
+ "sse",
+ "sse2",
+ "sse4_1",
+ "sse4_2",
+ "ssse3",
+ "xsavec",
+ "xsaveopt"
+ ],
+ "generation": 0,
+ "parents": [
+ "broadwell"
+ ]
+ }
+ },
+ "compiler": {
+ "name": "apple-clang",
+ "version": "13.0.0"
+ },
+ "namespace": "builtin.mock",
+ "parameters": {
+ "cflags": [],
+ "cppflags": [],
+ "cxxflags": [],
+ "fflags": [],
+ "ldflags": [],
+ "ldlibs": []
+ },
+ "hash": "qphelcbihtf4umgz6h66ppikwn3ernif"
+ },
+ "kierl2q24kzqcl35r5o6rj3ecg2463yn": {
+ "name": "dtrun3",
+ "version": "1.0",
+ "arch": {
+ "platform": "darwin",
+ "platform_os": "bigsur",
+ "target": {
+ "name": "skylake",
+ "vendor": "GenuineIntel",
+ "features": [
+ "adx",
+ "aes",
+ "avx",
+ "avx2",
+ "bmi1",
+ "bmi2",
+ "clflushopt",
+ "f16c",
+ "fma",
+ "mmx",
+ "movbe",
+ "pclmulqdq",
+ "popcnt",
+ "rdrand",
+ "rdseed",
+ "sse",
+ "sse2",
+ "sse4_1",
+ "sse4_2",
+ "ssse3",
+ "xsavec",
+ "xsaveopt"
+ ],
+ "generation": 0,
+ "parents": [
+ "broadwell"
+ ]
+ }
+ },
+ "compiler": {
+ "name": "apple-clang",
+ "version": "13.0.0"
+ },
+ "namespace": "builtin.mock",
+ "parameters": {
+ "cflags": [],
+ "cppflags": [],
+ "cxxflags": [],
+ "fflags": [],
+ "ldflags": [],
+ "ldlibs": []
+ },
+ "dependencies": [
+ {
+ "name": "dtbuild3",
+ "build_hash": "e4ue4tdy3yscgshzqpzsh7yjf7bear4k",
+ "type": [
+ "build"
+ ]
+ }
+ ],
+ "hash": "4bzkvvvuex7vybtto7rej6sg7uzqdqs2"
+ },
+ "e4ue4tdy3yscgshzqpzsh7yjf7bear4k": {
+ "name": "dtbuild3",
+ "version": "1.0",
+ "arch": {
+ "platform": "darwin",
+ "platform_os": "bigsur",
+ "target": {
+ "name": "skylake",
+ "vendor": "GenuineIntel",
+ "features": [
+ "adx",
+ "aes",
+ "avx",
+ "avx2",
+ "bmi1",
+ "bmi2",
+ "clflushopt",
+ "f16c",
+ "fma",
+ "mmx",
+ "movbe",
+ "pclmulqdq",
+ "popcnt",
+ "rdrand",
+ "rdseed",
+ "sse",
+ "sse2",
+ "sse4_1",
+ "sse4_2",
+ "ssse3",
+ "xsavec",
+ "xsaveopt"
+ ],
+ "generation": 0,
+ "parents": [
+ "broadwell"
+ ]
+ }
+ },
+ "compiler": {
+ "name": "apple-clang",
+ "version": "13.0.0"
+ },
+ "namespace": "builtin.mock",
+ "parameters": {
+ "cflags": [],
+ "cppflags": [],
+ "cxxflags": [],
+ "fflags": [],
+ "ldflags": [],
+ "ldlibs": []
+ },
+ "hash": "e4ue4tdy3yscgshzqpzsh7yjf7bear4k"
+ },
+ "2n4kyt2vzexalndoo46aa63vclquruuk": {
+ "name": "dttop",
+ "version": "1.0",
+ "arch": {
+ "platform": "darwin",
+ "platform_os": "bigsur",
+ "target": {
+ "name": "skylake",
+ "vendor": "GenuineIntel",
+ "features": [
+ "adx",
+ "aes",
+ "avx",
+ "avx2",
+ "bmi1",
+ "bmi2",
+ "clflushopt",
+ "f16c",
+ "fma",
+ "mmx",
+ "movbe",
+ "pclmulqdq",
+ "popcnt",
+ "rdrand",
+ "rdseed",
+ "sse",
+ "sse2",
+ "sse4_1",
+ "sse4_2",
+ "ssse3",
+ "xsavec",
+ "xsaveopt"
+ ],
+ "generation": 0,
+ "parents": [
+ "broadwell"
+ ]
+ }
+ },
+ "compiler": {
+ "name": "apple-clang",
+ "version": "13.0.0"
+ },
+ "namespace": "builtin.mock",
+ "parameters": {
+ "cflags": [],
+ "cppflags": [],
+ "cxxflags": [],
+ "fflags": [],
+ "ldflags": [],
+ "ldlibs": []
+ },
+ "dependencies": [
+ {
+ "name": "dtbuild1",
+ "build_hash": "habtzkoojlaipvyw3an6tjncw6dhmevz",
+ "type": [
+ "build"
+ ]
+ },
+ {
+ "name": "dtlink1",
+ "build_hash": "seallhwetilvtxoxaun3zvauga6erllj",
+ "type": [
+ "build",
+ "link"
+ ]
+ },
+ {
+ "name": "dtrun1",
+ "build_hash": "s7wjy5kbni43lswlhsdywh7fsz3kruax",
+ "type": [
+ "run"
+ ]
+ }
+ ],
+ "hash": "m5m2tbnyh2xnjd4nzwiuobvpk2wn4wix"
+ },
+ "habtzkoojlaipvyw3an6tjncw6dhmevz": {
+ "name": "dtbuild1",
+ "version": "1.0",
+ "arch": {
+ "platform": "darwin",
+ "platform_os": "bigsur",
+ "target": {
+ "name": "skylake",
+ "vendor": "GenuineIntel",
+ "features": [
+ "adx",
+ "aes",
+ "avx",
+ "avx2",
+ "bmi1",
+ "bmi2",
+ "clflushopt",
+ "f16c",
+ "fma",
+ "mmx",
+ "movbe",
+ "pclmulqdq",
+ "popcnt",
+ "rdrand",
+ "rdseed",
+ "sse",
+ "sse2",
+ "sse4_1",
+ "sse4_2",
+ "ssse3",
+ "xsavec",
+ "xsaveopt"
+ ],
+ "generation": 0,
+ "parents": [
+ "broadwell"
+ ]
+ }
+ },
+ "compiler": {
+ "name": "apple-clang",
+ "version": "13.0.0"
+ },
+ "namespace": "builtin.mock",
+ "parameters": {
+ "cflags": [],
+ "cppflags": [],
+ "cxxflags": [],
+ "fflags": [],
+ "ldflags": [],
+ "ldlibs": []
+ },
+ "dependencies": [
+ {
+ "name": "dtbuild2",
+ "build_hash": "pk3aetkbsbsktaslbuthagh746f2nj72",
+ "type": [
+ "build"
+ ]
+ },
+ {
+ "name": "dtlink2",
+ "build_hash": "rmgjkspuni3egfwusig4xlotnd74hgik",
+ "type": [
+ "build",
+ "link"
+ ]
+ },
+ {
+ "name": "dtrun2",
+ "build_hash": "ehpgq3io4lcrlfucjwxt2t64q7ibxqy4",
+ "type": [
+ "run"
+ ]
+ }
+ ],
+ "hash": "o4q27mbuz2zalxa36gdsykhystn6giin"
+ }
+ }
+} \ No newline at end of file
diff --git a/lib/spack/spack/test/spec_semantics.py b/lib/spack/spack/test/spec_semantics.py
index df73f989c9..58db63d0d1 100644
--- a/lib/spack/spack/test/spec_semantics.py
+++ b/lib/spack/spack/test/spec_semantics.py
@@ -999,28 +999,35 @@ class TestSpecSematics(object):
dep = Spec('splice-h+foo')
spec.concretize()
dep.concretize()
+
# Sanity checking that these are not the same thing.
assert dep.dag_hash() != spec['splice-h'].dag_hash()
- assert dep.runtime_hash() != spec['splice-h'].runtime_hash()
+
# Do the splice.
out = spec.splice(dep, transitive)
+
# Returned spec should still be concrete.
assert out.concrete
+
# Traverse the spec and assert that all dependencies are accounted for.
for node in spec.traverse():
assert node.name in out
+
# If the splice worked, then the dag hash of the spliced dep should
# now match the dag hash of the build spec of the dependency from the
# returned spec.
out_h_build = out['splice-h'].build_spec
assert out_h_build.dag_hash() == dep.dag_hash()
+
# Transitivity should determine whether the transitive dependency was
# changed.
expected_z = dep['splice-z'] if transitive else spec['splice-z']
assert out['splice-z'].dag_hash() == expected_z.dag_hash()
+
# Sanity check build spec of out should be the original spec.
assert (out['splice-t'].build_spec.dag_hash() ==
spec['splice-t'].dag_hash())
+
# Finally, the spec should know it's been spliced:
assert out.spliced
@@ -1033,15 +1040,10 @@ class TestSpecSematics(object):
# monkeypatch hashes so we can test that they are cached
spec._hash = 'aaaaaa'
- spec._runtime_hash = 'aaaaaa'
dep._hash = 'bbbbbb'
- dep._runtime_hash = 'bbbbbb'
spec['splice-h']._hash = 'cccccc'
- spec['splice-h']._runtime_hash = 'cccccc'
spec['splice-z']._hash = 'dddddd'
- spec['splice-z']._runtime_hash = 'dddddd'
dep['splice-z']._hash = 'eeeeee'
- dep['splice-z']._runtime_hash = 'eeeeee'
out = spec.splice(dep, transitive=transitive)
out_z_expected = (dep if transitive else spec)['splice-z']
@@ -1050,10 +1052,6 @@ class TestSpecSematics(object):
assert (out['splice-h'].dag_hash() == dep.dag_hash()) == transitive
assert out['splice-z'].dag_hash() == out_z_expected.dag_hash()
- assert out.runtime_hash() != spec.runtime_hash()
- assert (out['splice-h'].runtime_hash() == dep.runtime_hash()) == transitive
- assert out['splice-z'].runtime_hash() == out_z_expected.runtime_hash()
-
@pytest.mark.parametrize('transitive', [True, False])
def test_splice_input_unchanged(self, transitive):
spec = Spec('splice-t').concretized()
@@ -1073,14 +1071,14 @@ class TestSpecSematics(object):
spec.concretize()
dep.concretize()
out = spec.splice(dep, transitive)
+
# Now we attempt a second splice.
dep = Spec('splice-z+bar')
dep.concretize()
+
# Transitivity shouldn't matter since Splice Z has no dependencies.
out2 = out.splice(dep, transitive)
assert out2.concrete
- assert out2['splice-z'].runtime_hash() != spec['splice-z'].runtime_hash()
- assert out2['splice-z'].runtime_hash() != out['splice-z'].runtime_hash()
assert out2['splice-z'].dag_hash() != spec['splice-z'].dag_hash()
assert out2['splice-z'].dag_hash() != out['splice-z'].dag_hash()
assert (out2['splice-t'].build_spec.dag_hash() ==