diff options
-rw-r--r-- | lib/spack/spack/ci.py | 2 | ||||
-rw-r--r-- | lib/spack/spack/cmd/spec.py | 11 | ||||
-rw-r--r-- | lib/spack/spack/database.py | 2 | ||||
-rw-r--r-- | lib/spack/spack/environment/__init__.py | 327 | ||||
-rw-r--r-- | lib/spack/spack/environment/environment.py | 7 | ||||
-rw-r--r-- | lib/spack/spack/schema/spec.py | 6 | ||||
-rw-r--r-- | lib/spack/spack/spec.py | 45 | ||||
-rw-r--r-- | lib/spack/spack/test/cmd/env.py | 239 | ||||
-rw-r--r-- | lib/spack/spack/test/concretize.py | 1 | ||||
-rw-r--r-- | lib/spack/spack/test/data/legacy_env/spack.lock | 672 | ||||
-rw-r--r-- | lib/spack/spack/test/data/legacy_env/v1.lock | 383 | ||||
-rw-r--r-- | lib/spack/spack/test/data/legacy_env/v2.lock | 919 | ||||
-rw-r--r-- | lib/spack/spack/test/data/legacy_env/v3.lock | 924 | ||||
-rw-r--r-- | lib/spack/spack/test/spec_semantics.py | 22 | ||||
-rwxr-xr-x | share/spack/spack-completion.bash | 2 |
15 files changed, 2720 insertions, 842 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() == diff --git a/share/spack/spack-completion.bash b/share/spack/spack-completion.bash index 5e40746276..cd875080e0 100755 --- a/share/spack/spack-completion.bash +++ b/share/spack/spack-completion.bash @@ -1678,7 +1678,7 @@ _spack_solve() { _spack_spec() { if $list_options then - SPACK_COMPREPLY="-h --help -l --long -L --very-long -I --install-status -y --yaml -j --json --format -c --cover -N --namespaces --hash-type -t --types -U --fresh --reuse" + SPACK_COMPREPLY="-h --help -l --long -L --very-long -I --install-status -y --yaml -j --json --format -c --cover -N --namespaces -t --types -U --fresh --reuse" else _all_packages fi |