Environments: store spack version/commit in spack.lock (#32801)
Add a section to the lock file to track the Spack version/commit that produced an environment. This should (eventually) enhance reproducibility, though we do not currently do anything with the information. It just adds to provenance at the moment. Changes include: - [x] adding the version/commit to `spack.lock` - [x] refactor `spack.main.get_version() - [x] fix a couple of environment lock file-related typos
This commit is contained in:
parent
b06d20be19
commit
8e18297cf2
@ -16,18 +16,24 @@
|
||||
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:
|
||||
1. ``_meta`` (object): this contains details 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
|
||||
2. ``spack`` (object): optional, this identifies information about Spack
|
||||
used to concretize the environment:
|
||||
* ``type``: required, identifies form Spack version took (e.g., ``git``, ``release``)
|
||||
* ``commit``: the commit if the version is from git
|
||||
* ``version``: the Spack version
|
||||
|
||||
3. ``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.
|
||||
4. ``concrete_specs``: a dictionary containing the specs in the environment.
|
||||
|
||||
Compatibility
|
||||
-------------
|
||||
@ -271,6 +277,8 @@
|
||||
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).
|
||||
An optional ``spack`` property may be included to track version information, such as
|
||||
the commit or version.
|
||||
|
||||
|
||||
.. code-block:: json
|
||||
@ -278,8 +286,8 @@
|
||||
{
|
||||
"_meta": {
|
||||
"file-type": "spack-lockfile",
|
||||
"lockfile-version": 3,
|
||||
"specfile-version": 2
|
||||
"lockfile-version": 4,
|
||||
"specfile-version": 3
|
||||
},
|
||||
"roots": [
|
||||
{
|
||||
@ -326,7 +334,6 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"""
|
||||
|
||||
from .environment import (
|
||||
|
@ -31,6 +31,7 @@
|
||||
import spack.error
|
||||
import spack.hash_types as ht
|
||||
import spack.hooks
|
||||
import spack.main
|
||||
import spack.paths
|
||||
import spack.repo
|
||||
import spack.schema.env
|
||||
@ -2072,6 +2073,14 @@ def _to_lockfile_dict(self):
|
||||
|
||||
hash_spec_list = zip(self.concretized_order, self.concretized_user_specs)
|
||||
|
||||
spack_dict = {"version": spack.spack_version}
|
||||
spack_commit = spack.main.get_spack_commit()
|
||||
if spack_commit:
|
||||
spack_dict["type"] = "git"
|
||||
spack_dict["commit"] = spack_commit
|
||||
else:
|
||||
spack_dict["type"] = "release"
|
||||
|
||||
# this is the lockfile we'll write out
|
||||
data = {
|
||||
# metadata about the format
|
||||
@ -2080,6 +2089,8 @@ def _to_lockfile_dict(self):
|
||||
"lockfile-version": lockfile_format_version,
|
||||
"specfile-version": spack.spec.SPECFILE_FORMAT_VERSION,
|
||||
},
|
||||
# spack version information
|
||||
"spack": spack_dict,
|
||||
# users specs + hashes are the 'roots' of the environment
|
||||
"roots": [{"hash": h, "spec": str(s)} for h, s in hash_spec_list],
|
||||
# Concrete specs by hash, including dependencies
|
||||
|
@ -126,6 +126,36 @@ def add_all_commands(parser):
|
||||
parser.add_command(cmd)
|
||||
|
||||
|
||||
def get_spack_commit():
|
||||
"""Get the Spack git commit sha.
|
||||
|
||||
Returns:
|
||||
(str or None) the commit sha if available, otherwise None
|
||||
"""
|
||||
git_path = os.path.join(spack.paths.prefix, ".git")
|
||||
if not os.path.exists(git_path):
|
||||
return None
|
||||
|
||||
git = spack.util.git.git()
|
||||
if not git:
|
||||
return None
|
||||
|
||||
rev = git(
|
||||
"-C",
|
||||
spack.paths.prefix,
|
||||
"rev-parse",
|
||||
"HEAD",
|
||||
output=str,
|
||||
error=os.devnull,
|
||||
fail_on_error=False,
|
||||
)
|
||||
if git.returncode != 0:
|
||||
return None
|
||||
|
||||
match = re.match(r"[a-f\d]{7,}$", rev)
|
||||
return match.group(0) if match else None
|
||||
|
||||
|
||||
def get_version():
|
||||
"""Get a descriptive version of this instance of Spack.
|
||||
|
||||
@ -134,25 +164,9 @@ def get_version():
|
||||
The commit sha is only added when available.
|
||||
"""
|
||||
version = spack.spack_version
|
||||
git_path = os.path.join(spack.paths.prefix, ".git")
|
||||
if os.path.exists(git_path):
|
||||
git = spack.util.git.git()
|
||||
if not git:
|
||||
return version
|
||||
rev = git(
|
||||
"-C",
|
||||
spack.paths.prefix,
|
||||
"rev-parse",
|
||||
"HEAD",
|
||||
output=str,
|
||||
error=os.devnull,
|
||||
fail_on_error=False,
|
||||
)
|
||||
if git.returncode != 0:
|
||||
return version
|
||||
match = re.match(r"[a-f\d]{7,}$", rev)
|
||||
if match:
|
||||
version += " ({0})".format(match.group(0))
|
||||
commit = get_spack_commit()
|
||||
if commit:
|
||||
version += " ({0})".format(commit)
|
||||
|
||||
return version
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
import pytest
|
||||
|
||||
import spack.environment as ev
|
||||
from spack import spack_version
|
||||
from spack.main import SpackCommand
|
||||
|
||||
pytestmark = pytest.mark.usefixtures("config", "mutable_mock_repo")
|
||||
@ -54,3 +55,6 @@ def test_concretize_root_test_dependencies_are_concretized(unify, mutable_mock_e
|
||||
add("b")
|
||||
concretize("--test", "root")
|
||||
assert e.matching_spec("test-dependency")
|
||||
|
||||
data = e._to_lockfile_dict()
|
||||
assert data["spack"]["version"] == spack_version
|
||||
|
Loading…
Reference in New Issue
Block a user