directory_layout: types and remove kwargs (#48459)

This commit is contained in:
Harmen Stoppels 2025-01-08 14:09:36 +01:00 committed by GitHub
parent 7328c64fc7
commit 434a8d54d4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 30 additions and 43 deletions

View File

@ -8,7 +8,7 @@
import shutil import shutil
import sys import sys
from pathlib import Path from pathlib import Path
from typing import List, Optional, Tuple from typing import Dict, List, Optional, Tuple
import llnl.util.filesystem as fs import llnl.util.filesystem as fs
from llnl.util.symlink import readlink from llnl.util.symlink import readlink
@ -69,10 +69,9 @@ def specs_from_metadata_dirs(root: str) -> List["spack.spec.Spec"]:
class DirectoryLayout: class DirectoryLayout:
"""A directory layout is used to associate unique paths with specs. """A directory layout is used to associate unique paths with specs. Different installations are
Different installations are going to want different layouts for their going to want different layouts for their install, and they can use this to customize the
install, and they can use this to customize the nesting structure of nesting structure of spack installs. The default layout is:
spack installs. The default layout is:
* <install root>/ * <install root>/
@ -82,35 +81,31 @@ class DirectoryLayout:
* <name>-<version>-<hash> * <name>-<version>-<hash>
The hash here is a SHA-1 hash for the full DAG plus the build The installation directory projections can be modified with the projections argument."""
spec.
The installation directory projections can be modified with the def __init__(
projections argument. self,
""" root,
*,
def __init__(self, root, **kwargs): projections: Optional[Dict[str, str]] = None,
hash_length: Optional[int] = None,
) -> None:
self.root = root self.root = root
self.check_upstream = True self.check_upstream = True
projections = kwargs.get("projections") or default_projections projections = projections or default_projections
self.projections = dict( self.projections = {key: projection.lower() for key, projection in projections.items()}
(key, projection.lower()) for key, projection in projections.items()
)
# apply hash length as appropriate # apply hash length as appropriate
self.hash_length = kwargs.get("hash_length", None) self.hash_length = hash_length
if self.hash_length is not None: if self.hash_length is not None:
for when_spec, projection in self.projections.items(): for when_spec, projection in self.projections.items():
if "{hash}" not in projection: if "{hash}" not in projection:
if "{hash" in projection: raise InvalidDirectoryLayoutParametersError(
raise InvalidDirectoryLayoutParametersError( "Conflicting options for installation layout hash length"
"Conflicting options for installation layout hash" " length" if "{hash" in projection
) else "Cannot specify hash length when the hash is not part of all "
else: "install_tree projections"
raise InvalidDirectoryLayoutParametersError( )
"Cannot specify hash length when the hash is not"
" part of all install_tree projections"
)
self.projections[when_spec] = projection.replace( self.projections[when_spec] = projection.replace(
"{hash}", "{hash:%d}" % self.hash_length "{hash}", "{hash:%d}" % self.hash_length
) )

View File

@ -43,7 +43,6 @@
import spack.util.url as url_util import spack.util.url as url_util
import spack.util.web as web_util import spack.util.web as web_util
from spack.binary_distribution import CannotListKeys, GenerateIndexError from spack.binary_distribution import CannotListKeys, GenerateIndexError
from spack.directory_layout import DirectoryLayout
from spack.paths import test_path from spack.paths import test_path
from spack.spec import Spec from spack.spec import Spec
@ -136,35 +135,28 @@ def default_config(tmp_path, config_directory, monkeypatch, install_mockery):
@pytest.fixture(scope="function") @pytest.fixture(scope="function")
def install_dir_default_layout(tmpdir): def install_dir_default_layout(tmpdir):
"""Hooks a fake install directory with a default layout""" """Hooks a fake install directory with a default layout"""
scheme = os.path.join(
"${architecture}", "${compiler.name}-${compiler.version}", "${name}-${version}-${hash}"
)
real_store, real_layout = spack.store.STORE, spack.store.STORE.layout
opt_dir = tmpdir.join("opt") opt_dir = tmpdir.join("opt")
spack.store.STORE = spack.store.Store(str(opt_dir)) original_store, spack.store.STORE = spack.store.STORE, spack.store.Store(str(opt_dir))
spack.store.STORE.layout = DirectoryLayout(str(opt_dir), path_scheme=scheme)
try: try:
yield spack.store yield spack.store
finally: finally:
spack.store.STORE = real_store spack.store.STORE = original_store
spack.store.STORE.layout = real_layout
@pytest.fixture(scope="function") @pytest.fixture(scope="function")
def install_dir_non_default_layout(tmpdir): def install_dir_non_default_layout(tmpdir):
"""Hooks a fake install directory with a non-default layout""" """Hooks a fake install directory with a non-default layout"""
scheme = os.path.join(
"${name}", "${version}", "${architecture}-${compiler.name}-${compiler.version}-${hash}"
)
real_store, real_layout = spack.store.STORE, spack.store.STORE.layout
opt_dir = tmpdir.join("opt") opt_dir = tmpdir.join("opt")
spack.store.STORE = spack.store.Store(str(opt_dir)) original_store, spack.store.STORE = spack.store.STORE, spack.store.Store(
spack.store.STORE.layout = DirectoryLayout(str(opt_dir), path_scheme=scheme) str(opt_dir),
projections={
"all": "{name}/{version}/{architecture}-{compiler.name}-{compiler.version}-{hash}"
},
)
try: try:
yield spack.store yield spack.store
finally: finally:
spack.store.STORE = real_store spack.store.STORE = original_store
spack.store.STORE.layout = real_layout
@pytest.fixture(scope="function") @pytest.fixture(scope="function")