summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/spack/spack/__init__.py52
-rw-r--r--lib/spack/spack/binary_distribution.py5
-rw-r--r--lib/spack/spack/caches.py1
-rw-r--r--lib/spack/spack/ci.py4
-rw-r--r--lib/spack/spack/cmd/debug.py4
-rw-r--r--lib/spack/spack/container/writers.py (renamed from lib/spack/spack/container/writers/__init__.py)58
-rw-r--r--lib/spack/spack/container/writers/docker.py34
-rw-r--r--lib/spack/spack/container/writers/singularity.py35
-rw-r--r--lib/spack/spack/environment/environment.py10
-rw-r--r--lib/spack/spack/error.py12
-rw-r--r--lib/spack/spack/main.py50
-rw-r--r--lib/spack/spack/oci/oci.py6
-rw-r--r--lib/spack/spack/package_base.py2
-rw-r--r--lib/spack/spack/patch.py22
-rw-r--r--lib/spack/spack/platforms/__init__.py8
-rw-r--r--lib/spack/spack/reporters/cdash.py4
-rw-r--r--lib/spack/spack/solver/asp.py15
-rw-r--r--lib/spack/spack/solver/version_order.py21
-rw-r--r--lib/spack/spack/spec.py13
-rw-r--r--lib/spack/spack/test/cmd/ci.py8
-rw-r--r--lib/spack/spack/test/cmd/debug.py5
-rw-r--r--lib/spack/spack/test/concretize.py3
-rw-r--r--lib/spack/spack/test/main.py15
-rw-r--r--lib/spack/spack/test/patch.py7
-rw-r--r--lib/spack/spack/util/environment.py26
-rw-r--r--lib/spack/spack/util/executable.py2
26 files changed, 196 insertions, 226 deletions
diff --git a/lib/spack/spack/__init__.py b/lib/spack/spack/__init__.py
index b37c63b5bd..cf7d62c7fd 100644
--- a/lib/spack/spack/__init__.py
+++ b/lib/spack/spack/__init__.py
@@ -3,6 +3,13 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
+import os
+import re
+from typing import Optional
+
+import spack.paths
+import spack.util.git
+
#: PEP440 canonical <major>.<minor>.<micro>.<devN> string
__version__ = "0.23.0.dev0"
spack_version = __version__
@@ -19,4 +26,47 @@ def __try_int(v):
spack_version_info = tuple([__try_int(v) for v in __version__.split(".")])
-__all__ = ["spack_version_info", "spack_version"]
+def get_spack_commit() -> Optional[str]:
+ """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() -> str:
+ """Get a descriptive version of this instance of Spack.
+
+ Outputs '<PEP440 version> (<git commit sha>)'.
+
+ The commit sha is only added when available.
+ """
+ commit = get_spack_commit()
+ if commit:
+ return f"{spack_version} ({commit})"
+ return spack_version
+
+
+__all__ = ["spack_version_info", "spack_version", "get_version", "get_spack_commit"]
diff --git a/lib/spack/spack/binary_distribution.py b/lib/spack/spack/binary_distribution.py
index 15189f9d43..61db2bebe1 100644
--- a/lib/spack/spack/binary_distribution.py
+++ b/lib/spack/spack/binary_distribution.py
@@ -44,6 +44,7 @@ import spack.mirror
import spack.oci.image
import spack.oci.oci
import spack.oci.opener
+import spack.paths
import spack.platforms
import spack.relocate as relocate
import spack.repo
@@ -1447,7 +1448,9 @@ def _oci_push_pkg_blob(
filename = os.path.join(tmpdir, f"{spec.dag_hash()}.tar.gz")
# Create an oci.image.layer aka tarball of the package
- compressed_tarfile_checksum, tarfile_checksum = spack.oci.oci.create_tarball(spec, filename)
+ compressed_tarfile_checksum, tarfile_checksum = _do_create_tarball(
+ filename, spec.prefix, get_buildinfo_dict(spec)
+ )
blob = spack.oci.oci.Blob(
Digest.from_sha256(compressed_tarfile_checksum),
diff --git a/lib/spack/spack/caches.py b/lib/spack/spack/caches.py
index eda141ed15..1ffef9343b 100644
--- a/lib/spack/spack/caches.py
+++ b/lib/spack/spack/caches.py
@@ -13,7 +13,6 @@ from llnl.util.filesystem import mkdirp
import spack.config
import spack.error
import spack.fetch_strategy
-import spack.mirror
import spack.paths
import spack.util.file_cache
import spack.util.path
diff --git a/lib/spack/spack/ci.py b/lib/spack/spack/ci.py
index bc661e0970..c40b88d9e2 100644
--- a/lib/spack/spack/ci.py
+++ b/lib/spack/spack/ci.py
@@ -1219,8 +1219,8 @@ def generate_gitlab_ci_yaml(
# Capture the version of Spack used to generate the pipeline, that can be
# passed to `git checkout` for version consistency. If we aren't in a Git
# repository, presume we are a Spack release and use the Git tag instead.
- spack_version = spack.main.get_version()
- version_to_clone = spack.main.get_spack_commit() or f"v{spack.spack_version}"
+ spack_version = spack.get_version()
+ version_to_clone = spack.get_spack_commit() or f"v{spack.spack_version}"
output_object["variables"] = {
"SPACK_ARTIFACTS_ROOT": rel_artifacts_root,
diff --git a/lib/spack/spack/cmd/debug.py b/lib/spack/spack/cmd/debug.py
index b1d33eb67d..9a93cc0a14 100644
--- a/lib/spack/spack/cmd/debug.py
+++ b/lib/spack/spack/cmd/debug.py
@@ -13,11 +13,11 @@ from glob import glob
import llnl.util.tty as tty
from llnl.util.filesystem import working_dir
+import spack
import spack.config
import spack.paths
import spack.platforms
import spack.util.git
-from spack.main import get_version
from spack.util.executable import which
description = "debugging commands for troubleshooting Spack"
@@ -89,7 +89,7 @@ def report(args):
host_os = host_platform.operating_system("frontend")
host_target = host_platform.target("frontend")
architecture = spack.spec.ArchSpec((str(host_platform), str(host_os), str(host_target)))
- print("* **Spack:**", get_version())
+ print("* **Spack:**", spack.get_version())
print("* **Python:**", platform.python_version())
print("* **Platform:**", architecture)
diff --git a/lib/spack/spack/container/writers/__init__.py b/lib/spack/spack/container/writers.py
index eabc25d218..0b5d14157c 100644
--- a/lib/spack/spack/container/writers/__init__.py
+++ b/lib/spack/spack/container/writers.py
@@ -6,6 +6,7 @@
convenience functions.
"""
import copy
+import shlex
from collections import namedtuple
from typing import Optional
@@ -15,7 +16,7 @@ import spack.schema.env
import spack.tengine as tengine
import spack.util.spack_yaml as syaml
-from ..images import (
+from .images import (
bootstrap_template_for,
build_info,
checkout_command,
@@ -308,7 +309,54 @@ class PathContext(tengine.Context):
return t.render(**self.to_dict())
-# Import after function definition all the modules in this package,
-# so that registration of writers will happen automatically
-from . import docker # noqa: F401 E402
-from . import singularity # noqa: F401 E402
+@writer("docker")
+class DockerContext(PathContext):
+ """Context used to instantiate a Dockerfile"""
+
+ #: Name of the template used for Dockerfiles
+ template_name = "container/Dockerfile"
+
+ @tengine.context_property
+ def manifest(self):
+ manifest_str = super().manifest
+ # Docker doesn't support HEREDOC, so we need to resort to
+ # a horrible echo trick to have the manifest in the Dockerfile
+ echoed_lines = []
+ for idx, line in enumerate(manifest_str.split("\n")):
+ quoted_line = shlex.quote(line)
+ if idx == 0:
+ echoed_lines.append("&& (echo " + quoted_line + " \\")
+ continue
+ echoed_lines.append("&& echo " + quoted_line + " \\")
+
+ echoed_lines[-1] = echoed_lines[-1].replace(" \\", ")")
+
+ return "\n".join(echoed_lines)
+
+
+@writer("singularity")
+class SingularityContext(PathContext):
+ """Context used to instantiate a Singularity definition file"""
+
+ #: Name of the template used for Singularity definition files
+ template_name = "container/singularity.def"
+
+ @property
+ def singularity_config(self):
+ return self.container_config.get("singularity", {})
+
+ @tengine.context_property
+ def runscript(self):
+ return self.singularity_config.get("runscript", "")
+
+ @tengine.context_property
+ def startscript(self):
+ return self.singularity_config.get("startscript", "")
+
+ @tengine.context_property
+ def test(self):
+ return self.singularity_config.get("test", "")
+
+ @tengine.context_property
+ def help(self):
+ return self.singularity_config.get("help", "")
diff --git a/lib/spack/spack/container/writers/docker.py b/lib/spack/spack/container/writers/docker.py
deleted file mode 100644
index 287ef9d1ac..0000000000
--- a/lib/spack/spack/container/writers/docker.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright 2013-2024 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)
-import shlex
-
-import spack.tengine as tengine
-
-from . import PathContext, writer
-
-
-@writer("docker")
-class DockerContext(PathContext):
- """Context used to instantiate a Dockerfile"""
-
- #: Name of the template used for Dockerfiles
- template_name = "container/Dockerfile"
-
- @tengine.context_property
- def manifest(self):
- manifest_str = super().manifest
- # Docker doesn't support HEREDOC, so we need to resort to
- # a horrible echo trick to have the manifest in the Dockerfile
- echoed_lines = []
- for idx, line in enumerate(manifest_str.split("\n")):
- quoted_line = shlex.quote(line)
- if idx == 0:
- echoed_lines.append("&& (echo " + quoted_line + " \\")
- continue
- echoed_lines.append("&& echo " + quoted_line + " \\")
-
- echoed_lines[-1] = echoed_lines[-1].replace(" \\", ")")
-
- return "\n".join(echoed_lines)
diff --git a/lib/spack/spack/container/writers/singularity.py b/lib/spack/spack/container/writers/singularity.py
deleted file mode 100644
index 5cbb055fd3..0000000000
--- a/lib/spack/spack/container/writers/singularity.py
+++ /dev/null
@@ -1,35 +0,0 @@
-# Copyright 2013-2024 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)
-import spack.tengine as tengine
-
-from . import PathContext, writer
-
-
-@writer("singularity")
-class SingularityContext(PathContext):
- """Context used to instantiate a Singularity definition file"""
-
- #: Name of the template used for Singularity definition files
- template_name = "container/singularity.def"
-
- @property
- def singularity_config(self):
- return self.container_config.get("singularity", {})
-
- @tengine.context_property
- def runscript(self):
- return self.singularity_config.get("runscript", "")
-
- @tengine.context_property
- def startscript(self):
- return self.singularity_config.get("startscript", "")
-
- @tengine.context_property
- def test(self):
- return self.singularity_config.get("test", "")
-
- @tengine.context_property
- def help(self):
- return self.singularity_config.get("help", "")
diff --git a/lib/spack/spack/environment/environment.py b/lib/spack/spack/environment/environment.py
index f6f4ffa0ad..727fd7f234 100644
--- a/lib/spack/spack/environment/environment.py
+++ b/lib/spack/spack/environment/environment.py
@@ -24,25 +24,20 @@ import llnl.util.tty.color as clr
from llnl.util.link_tree import ConflictingSpecsError
from llnl.util.symlink import readlink, symlink
+import spack
import spack.caches
-import spack.cmd
import spack.compilers
import spack.concretize
import spack.config
import spack.deptypes as dt
import spack.error
-import spack.fetch_strategy
import spack.filesystem_view as fsv
import spack.hash_types as ht
-import spack.hooks
-import spack.main
import spack.paths
import spack.repo
import spack.schema.env
import spack.spec
-import spack.stage
import spack.store
-import spack.subprocess_context
import spack.user_environment as uenv
import spack.util.cpus
import spack.util.environment
@@ -53,7 +48,6 @@ import spack.util.path
import spack.util.spack_json as sjson
import spack.util.spack_yaml as syaml
import spack.util.url
-import spack.version
from spack import traverse
from spack.installer import PackageInstaller
from spack.schema.env import TOP_LEVEL_KEY
@@ -2179,7 +2173,7 @@ class Environment:
root_specs = self._concrete_roots_dict()
spack_dict = {"version": spack.spack_version}
- spack_commit = spack.main.get_spack_commit()
+ spack_commit = spack.get_spack_commit()
if spack_commit:
spack_dict["type"] = "git"
spack_dict["commit"] = spack_commit
diff --git a/lib/spack/spack/error.py b/lib/spack/spack/error.py
index 804dc6867b..ea37d5787b 100644
--- a/lib/spack/spack/error.py
+++ b/lib/spack/spack/error.py
@@ -132,3 +132,15 @@ class UnsatisfiableSpecError(SpecError):
class FetchError(SpackError):
"""Superclass for fetch-related errors."""
+
+
+class NoSuchPatchError(SpackError):
+ """Raised when a patch file doesn't exist."""
+
+
+class PatchDirectiveError(SpackError):
+ """Raised when the wrong arguments are suppled to the patch directive."""
+
+
+class PatchLookupError(NoSuchPatchError):
+ """Raised when a patch file cannot be located from sha256."""
diff --git a/lib/spack/spack/main.py b/lib/spack/spack/main.py
index 78fda27c46..9ca5453f23 100644
--- a/lib/spack/spack/main.py
+++ b/lib/spack/spack/main.py
@@ -32,6 +32,7 @@ import llnl.util.tty.colify
import llnl.util.tty.color as color
from llnl.util.tty.log import log_output
+import spack
import spack.cmd
import spack.config
import spack.environment as ev
@@ -44,8 +45,6 @@ import spack.spec
import spack.store
import spack.util.debug
import spack.util.environment
-import spack.util.git
-import spack.util.path
from spack.error import SpackError
#: names of profile statistics
@@ -122,51 +121,6 @@ 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.
-
- Outputs '<PEP440 version> (<git commit sha>)'.
-
- The commit sha is only added when available.
- """
- version = spack.spack_version
- commit = get_spack_commit()
- if commit:
- version += " ({0})".format(commit)
-
- return version
-
-
def index_commands():
"""create an index of commands by section for this help level"""
index = {}
@@ -954,7 +908,7 @@ def _main(argv=None):
# version is special as it does not require a command or loading and additional infrastructure
if args.version:
- print(get_version())
+ print(spack.get_version())
return 0
# ------------------------------------------------------------------------
diff --git a/lib/spack/spack/oci/oci.py b/lib/spack/spack/oci/oci.py
index cacb53e08c..ae70e287a6 100644
--- a/lib/spack/spack/oci/oci.py
+++ b/lib/spack/spack/oci/oci.py
@@ -15,7 +15,6 @@ from urllib.request import Request
import llnl.util.tty as tty
-import spack.binary_distribution
import spack.config
import spack.error
import spack.fetch_strategy
@@ -37,11 +36,6 @@ class Blob(NamedTuple):
size: int
-def create_tarball(spec: spack.spec.Spec, tarfile_path):
- buildinfo = spack.binary_distribution.get_buildinfo_dict(spec)
- return spack.binary_distribution._do_create_tarball(tarfile_path, spec.prefix, buildinfo)
-
-
def with_query_param(url: str, param: str, value: str) -> str:
"""Add a query parameter to a URL
diff --git a/lib/spack/spack/package_base.py b/lib/spack/spack/package_base.py
index f3cbcbe4a6..d157ab4a66 100644
--- a/lib/spack/spack/package_base.py
+++ b/lib/spack/spack/package_base.py
@@ -65,6 +65,7 @@ from spack.install_test import (
install_test_root,
)
from spack.installer import InstallError, PackageInstaller
+from spack.solver.version_order import concretization_version_order
from spack.stage import DevelopStage, ResourceStage, Stage, StageComposite, compute_stage_name
from spack.util.executable import ProcessError, which
from spack.util.package_hash import package_hash
@@ -116,7 +117,6 @@ def preferred_version(pkg: "PackageBase"):
Arguments:
pkg: The package whose versions are to be assessed.
"""
- from spack.solver.asp import concretization_version_order
version, _ = max(pkg.versions.items(), key=concretization_version_order)
return version
diff --git a/lib/spack/spack/patch.py b/lib/spack/spack/patch.py
index 6a57f49bb0..50393ecfad 100644
--- a/lib/spack/spack/patch.py
+++ b/lib/spack/spack/patch.py
@@ -113,7 +113,7 @@ class Patch:
stage: stage where source code lives
"""
if not self.path or not os.path.isfile(self.path):
- raise NoSuchPatchError(f"No such patch: {self.path}")
+ raise spack.error.NoSuchPatchError(f"No such patch: {self.path}")
apply_patch(stage, self.path, self.level, self.working_dir, self.reverse)
@@ -275,14 +275,14 @@ class UrlPatch(Patch):
self.ordering_key = ordering_key
if allowed_archive(self.url) and not archive_sha256:
- raise PatchDirectiveError(
+ raise spack.error.PatchDirectiveError(
"Compressed patches require 'archive_sha256' "
"and patch 'sha256' attributes: %s" % self.url
)
self.archive_sha256 = archive_sha256
if not sha256:
- raise PatchDirectiveError("URL patches require a sha256 checksum")
+ raise spack.error.PatchDirectiveError("URL patches require a sha256 checksum")
self.sha256 = sha256
def apply(self, stage: "spack.stage.Stage") -> None:
@@ -480,7 +480,7 @@ class PatchCache:
"""
sha_index = self.index.get(sha256)
if not sha_index:
- raise PatchLookupError(
+ raise spack.error.PatchLookupError(
f"Couldn't find patch for package {pkg.fullname} with sha256: {sha256}"
)
@@ -490,7 +490,7 @@ class PatchCache:
if patch_dict:
break
else:
- raise PatchLookupError(
+ raise spack.error.PatchLookupError(
f"Couldn't find patch for package {pkg.fullname} with sha256: {sha256}"
)
@@ -573,15 +573,3 @@ class PatchCache:
index[patch.sha256] = {dspec_cls.fullname: patch_dict}
return index
-
-
-class NoSuchPatchError(spack.error.SpackError):
- """Raised when a patch file doesn't exist."""
-
-
-class PatchLookupError(NoSuchPatchError):
- """Raised when a patch file cannot be located from sha256."""
-
-
-class PatchDirectiveError(spack.error.SpackError):
- """Raised when the wrong arguments are suppled to the patch directive."""
diff --git a/lib/spack/spack/platforms/__init__.py b/lib/spack/spack/platforms/__init__.py
index e49f87b2a7..7b7a668fb1 100644
--- a/lib/spack/spack/platforms/__init__.py
+++ b/lib/spack/spack/platforms/__init__.py
@@ -51,7 +51,6 @@ class _PickleableCallable:
def use_platform(new_platform):
global host
- import spack.compilers
import spack.config
msg = '"{0}" must be an instance of Platform'
@@ -61,16 +60,9 @@ def use_platform(new_platform):
try:
host = _PickleableCallable(new_platform)
-
- # Clear configuration and compiler caches
spack.config.CONFIG.clear_caches()
- spack.compilers._cache_config_files = []
-
yield new_platform
finally:
host = original_host_fn
-
- # Clear configuration and compiler caches
spack.config.CONFIG.clear_caches()
- spack.compilers._cache_config_files = []
diff --git a/lib/spack/spack/reporters/cdash.py b/lib/spack/spack/reporters/cdash.py
index 0c140a488d..5d50f05c60 100644
--- a/lib/spack/spack/reporters/cdash.py
+++ b/lib/spack/spack/reporters/cdash.py
@@ -19,9 +19,11 @@ from urllib.request import HTTPSHandler, Request, build_opener
import llnl.util.tty as tty
from llnl.util.filesystem import working_dir
+import spack
import spack.build_environment
import spack.fetch_strategy
import spack.package_base
+import spack.paths
import spack.platforms
import spack.util.git
from spack.error import SpackError
@@ -119,7 +121,7 @@ class CDash(Reporter):
git = spack.util.git.git()
with working_dir(spack.paths.spack_root):
self.revision = git("rev-parse", "HEAD", output=str).strip()
- self.generator = "spack-{0}".format(spack.main.get_version())
+ self.generator = "spack-{0}".format(spack.get_version())
self.multiple_packages = False
def report_build_name(self, pkg_name):
diff --git a/lib/spack/spack/solver/asp.py b/lib/spack/spack/solver/asp.py
index ba04e7cb33..af6d3c94f7 100644
--- a/lib/spack/spack/solver/asp.py
+++ b/lib/spack/spack/solver/asp.py
@@ -64,6 +64,7 @@ from .core import (
parse_term,
)
from .counter import FullDuplicatesCounter, MinimalDuplicatesCounter, NoDuplicatesCounter
+from .version_order import concretization_version_order
GitOrStandardVersion = Union[spack.version.GitVersion, spack.version.StandardVersion]
@@ -579,20 +580,6 @@ def _is_checksummed_version(version_info: Tuple[GitOrStandardVersion, dict]):
return _is_checksummed_git_version(version)
-def concretization_version_order(version_info: Tuple[GitOrStandardVersion, dict]):
- """Version order key for concretization, where preferred > not preferred,
- not deprecated > deprecated, finite > any infinite component; only if all are
- the same, do we use default version ordering."""
- version, info = version_info
- return (
- info.get("preferred", False),
- not info.get("deprecated", False),
- not version.isdevelop(),
- not version.is_prerelease(),
- version,
- )
-
-
def _spec_with_default_name(spec_str, name):
"""Return a spec with a default name if none is provided, used for requirement specs"""
spec = spack.spec.Spec(spec_str)
diff --git a/lib/spack/spack/solver/version_order.py b/lib/spack/spack/solver/version_order.py
new file mode 100644
index 0000000000..23d3e390ce
--- /dev/null
+++ b/lib/spack/spack/solver/version_order.py
@@ -0,0 +1,21 @@
+# Copyright 2013-2024 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)
+from typing import Tuple, Union
+
+from spack.version import GitVersion, StandardVersion
+
+
+def concretization_version_order(version_info: Tuple[Union[GitVersion, StandardVersion], dict]):
+ """Version order key for concretization, where preferred > not preferred,
+ not deprecated > deprecated, finite > any infinite component; only if all are
+ the same, do we use default version ordering."""
+ version, info = version_info
+ return (
+ info.get("preferred", False),
+ not info.get("deprecated", False),
+ not version.isdevelop(),
+ not version.is_prerelease(),
+ version,
+ )
diff --git a/lib/spack/spack/spec.py b/lib/spack/spack/spec.py
index 3d5a1ce320..be1d08399e 100644
--- a/lib/spack/spack/spec.py
+++ b/lib/spack/spack/spec.py
@@ -68,6 +68,7 @@ import llnl.util.lang as lang
import llnl.util.tty as tty
import llnl.util.tty.color as clr
+import spack
import spack.compiler
import spack.compilers
import spack.config
@@ -75,7 +76,6 @@ import spack.deptypes as dt
import spack.error
import spack.hash_types as ht
import spack.parser
-import spack.patch
import spack.paths
import spack.platforms
import spack.provider_index
@@ -1307,7 +1307,7 @@ class SpecBuildInterface(lang.ObjectWrapper):
def tree(
- specs: List["spack.spec.Spec"],
+ specs: List["Spec"],
*,
color: Optional[bool] = None,
depth: bool = False,
@@ -2032,7 +2032,7 @@ class Spec:
raise InvalidHashError(self, self.abstract_hash)
if len(matches) != 1:
- raise spack.spec.AmbiguousHashError(
+ raise AmbiguousHashError(
f"Multiple packages specify hash beginning '{self.abstract_hash}'.", *matches
)
@@ -3464,7 +3464,7 @@ class Spec:
pkg_cls = spack.repo.PATH.get_pkg_class(self.name)
try:
patch = index.patch_for_package(sha256, pkg_cls)
- except spack.patch.PatchLookupError as e:
+ except spack.error.PatchLookupError as e:
raise spack.error.SpecError(
f"{e}. This usually means the patch was modified or removed. "
"To fix this, either reconcretize or use the original package "
@@ -4535,7 +4535,7 @@ def merge_abstract_anonymous_specs(*abstract_specs: Spec):
Args:
*abstract_specs: abstract specs to be merged
"""
- merged_spec = spack.spec.Spec()
+ merged_spec = Spec()
for current_spec_constraint in abstract_specs:
merged_spec.constrain(current_spec_constraint, deps=False)
@@ -4890,7 +4890,6 @@ def get_host_environment_metadata() -> Dict[str, str]:
"""Get the host environment, reduce to a subset that we can store in
the install directory, and add the spack version.
"""
- import spack.main
environ = get_host_environment()
return {
@@ -4898,7 +4897,7 @@ def get_host_environment_metadata() -> Dict[str, str]:
"platform": environ["platform"],
"host_target": environ["target"],
"hostname": environ["hostname"],
- "spack_version": spack.main.get_version(),
+ "spack_version": spack.get_version(),
"kernel_version": platform.version(),
}
diff --git a/lib/spack/spack/test/cmd/ci.py b/lib/spack/spack/test/cmd/ci.py
index 0eaabfd5a7..e2d87d5bb0 100644
--- a/lib/spack/spack/test/cmd/ci.py
+++ b/lib/spack/spack/test/cmd/ci.py
@@ -305,8 +305,8 @@ def test_ci_generate_with_custom_settings(
ci_generate_test, tmp_path, mock_binary_index, monkeypatch
):
"""Test use of user-provided scripts and attributes"""
- monkeypatch.setattr(spack.main, "get_version", lambda: "0.15.3")
- monkeypatch.setattr(spack.main, "get_spack_commit", lambda: "big ol commit sha")
+ monkeypatch.setattr(spack, "get_version", lambda: "0.15.3")
+ monkeypatch.setattr(spack, "get_spack_commit", lambda: "big ol commit sha")
spack_yaml, outputfile, _ = ci_generate_test(
f"""\
spack:
@@ -1040,8 +1040,8 @@ def test_ci_generate_override_runner_attrs(
inherit them from the top level, as well as when we override one or
more at the runner level"""
monkeypatch.setattr(spack, "spack_version", "0.20.0.test0")
- monkeypatch.setattr(spack.main, "get_version", lambda: "0.20.0.test0 (blah)")
- monkeypatch.setattr(spack.main, "get_spack_commit", lambda: git_version)
+ monkeypatch.setattr(spack, "get_version", lambda: "0.20.0.test0 (blah)")
+ monkeypatch.setattr(spack, "get_spack_commit", lambda: git_version)
spack_yaml, outputfile, _ = ci_generate_test(
f"""\
spack:
diff --git a/lib/spack/spack/test/cmd/debug.py b/lib/spack/spack/test/cmd/debug.py
index 55d0928fbd..4e16cc92c9 100644
--- a/lib/spack/spack/test/cmd/debug.py
+++ b/lib/spack/spack/test/cmd/debug.py
@@ -9,9 +9,10 @@ import platform
import pytest
+import spack
import spack.config
import spack.platforms
-from spack.main import SpackCommand, get_version
+from spack.main import SpackCommand
from spack.util.executable import which
debug = SpackCommand("debug")
@@ -55,6 +56,6 @@ def test_report():
host_target = host_platform.target("frontend")
architecture = spack.spec.ArchSpec((str(host_platform), str(host_os), str(host_target)))
- assert get_version() in out
+ assert spack.get_version() in out
assert platform.python_version() in out
assert str(architecture) in out
diff --git a/lib/spack/spack/test/concretize.py b/lib/spack/spack/test/concretize.py
index 4843861730..7349e4227d 100644
--- a/lib/spack/spack/test/concretize.py
+++ b/lib/spack/spack/test/concretize.py
@@ -25,6 +25,7 @@ import spack.hash_types as ht
import spack.platforms
import spack.repo
import spack.solver.asp
+import spack.solver.version_order
import spack.store
import spack.util.file_cache
import spack.util.libc
@@ -2928,7 +2929,7 @@ def test_concretization_version_order():
result = [
v
for v, _ in sorted(
- versions, key=spack.solver.asp.concretization_version_order, reverse=True
+ versions, key=spack.solver.version_order.concretization_version_order, reverse=True
)
]
assert result == [
diff --git a/lib/spack/spack/test/main.py b/lib/spack/spack/test/main.py
index ed66df4c88..5c64865e56 100644
--- a/lib/spack/spack/test/main.py
+++ b/lib/spack/spack/test/main.py
@@ -8,10 +8,11 @@ import pytest
import llnl.util.filesystem as fs
+import spack
import spack.paths
import spack.util.executable as exe
import spack.util.git
-from spack.main import get_version, main
+from spack.main import main
pytestmark = pytest.mark.not_on_windows(
"Test functionality supported but tests are failing on Win"
@@ -29,7 +30,7 @@ echo --|not a hash|----
fs.set_executable(git)
monkeypatch.setattr(spack.util.git, "git", lambda: exe.which(git))
- assert spack.spack_version == get_version()
+ assert spack.spack_version == spack.get_version()
def test_version_git_fails(tmpdir, working_env, monkeypatch):
@@ -44,7 +45,7 @@ exit 1
fs.set_executable(git)
monkeypatch.setattr(spack.util.git, "git", lambda: exe.which(git))
- assert spack.spack_version == get_version()
+ assert spack.spack_version == spack.get_version()
def test_git_sha_output(tmpdir, working_env, monkeypatch):
@@ -62,17 +63,17 @@ echo {0}
monkeypatch.setattr(spack.util.git, "git", lambda: exe.which(git))
expected = "{0} ({1})".format(spack.spack_version, sha)
- assert expected == get_version()
+ assert expected == spack.get_version()
def test_get_version_no_repo(tmpdir, monkeypatch):
monkeypatch.setattr(spack.paths, "prefix", str(tmpdir))
- assert spack.spack_version == get_version()
+ assert spack.spack_version == spack.get_version()
def test_get_version_no_git(tmpdir, working_env, monkeypatch):
monkeypatch.setattr(spack.util.git, "git", lambda: None)
- assert spack.spack_version == get_version()
+ assert spack.spack_version == spack.get_version()
def test_main_calls_get_version(tmpdir, capsys, working_env, monkeypatch):
@@ -96,4 +97,4 @@ exit 1
fs.set_executable(bad_git)
monkeypatch.setattr(spack.util.git, "git", lambda: exe.which(bad_git))
- assert spack.spack_version == get_version()
+ assert spack.spack_version == spack.get_version()
diff --git a/lib/spack/spack/test/patch.py b/lib/spack/spack/test/patch.py
index 4ec4cec7e7..04bce857c5 100644
--- a/lib/spack/spack/test/patch.py
+++ b/lib/spack/spack/test/patch.py
@@ -13,6 +13,7 @@ import pytest
from llnl.util.filesystem import mkdirp, touch, working_dir
+import spack.error
import spack.patch
import spack.paths
import spack.repo
@@ -434,7 +435,7 @@ def test_patch_no_file():
patch = spack.patch.Patch(fp, "nonexistent_file", 0, "")
patch.path = "test"
- with pytest.raises(spack.patch.NoSuchPatchError, match="No such patch:"):
+ with pytest.raises(spack.error.NoSuchPatchError, match="No such patch:"):
patch.apply("")
@@ -444,10 +445,10 @@ def test_patch_no_sha256():
fp = FakePackage("fake-package", "test", "fake-package")
url = url_util.path_to_file_url("foo.tgz")
match = "Compressed patches require 'archive_sha256' and patch 'sha256' attributes: file://"
- with pytest.raises(spack.patch.PatchDirectiveError, match=match):
+ with pytest.raises(spack.error.PatchDirectiveError, match=match):
spack.patch.UrlPatch(fp, url, sha256="", archive_sha256="")
match = "URL patches require a sha256 checksum"
- with pytest.raises(spack.patch.PatchDirectiveError, match=match):
+ with pytest.raises(spack.error.PatchDirectiveError, match=match):
spack.patch.UrlPatch(fp, url, sha256="", archive_sha256="abc")
diff --git a/lib/spack/spack/util/environment.py b/lib/spack/spack/util/environment.py
index 12b2bbb1d0..2e0ef7c9b9 100644
--- a/lib/spack/spack/util/environment.py
+++ b/lib/spack/spack/util/environment.py
@@ -12,6 +12,7 @@ import os.path
import pickle
import re
import shlex
+import subprocess
import sys
from functools import wraps
from typing import Any, Callable, Dict, List, MutableMapping, Optional, Tuple, Union
@@ -20,8 +21,6 @@ from llnl.path import path_to_os_path, system_path_filter
from llnl.util import tty
from llnl.util.lang import dedupe
-from .executable import Executable, which
-
if sys.platform == "win32":
SYSTEM_PATHS = [
"C:\\",
@@ -1034,8 +1033,6 @@ def environment_after_sourcing_files(
source_command = kwargs.get("source_command", "source")
concatenate_on_success = kwargs.get("concatenate_on_success", "&&")
- shell = Executable(shell_cmd)
-
def _source_single_file(file_and_args, environment):
shell_options_list = shell_options.split()
@@ -1043,26 +1040,21 @@ def environment_after_sourcing_files(
source_file.extend(x for x in file_and_args)
source_file = " ".join(source_file)
- # If the environment contains 'python' use it, if not
- # go with sys.executable. Below we just need a working
- # Python interpreter, not necessarily sys.executable.
- python_cmd = which("python3", "python", "python2")
- python_cmd = python_cmd.path if python_cmd else sys.executable
-
dump_cmd = "import os, json; print(json.dumps(dict(os.environ)))"
- dump_environment_cmd = python_cmd + f' -E -c "{dump_cmd}"'
+ dump_environment_cmd = sys.executable + f' -E -c "{dump_cmd}"'
# Try to source the file
source_file_arguments = " ".join(
[source_file, suppress_output, concatenate_on_success, dump_environment_cmd]
)
- output = shell(
- *shell_options_list,
- source_file_arguments,
- output=str,
+
+ with subprocess.Popen(
+ [shell_cmd, *shell_options_list, source_file_arguments],
env=environment,
- ignore_quotes=True,
- )
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ ) as shell:
+ output, _ = shell.communicate()
return json.loads(output)
diff --git a/lib/spack/spack/util/executable.py b/lib/spack/spack/util/executable.py
index 92933221ca..0c1901cb1a 100644
--- a/lib/spack/spack/util/executable.py
+++ b/lib/spack/spack/util/executable.py
@@ -12,6 +12,7 @@ from pathlib import Path, PurePath
import llnl.util.tty as tty
import spack.error
+from spack.util.environment import EnvironmentModifications
__all__ = ["Executable", "which", "ProcessError"]
@@ -27,7 +28,6 @@ class Executable:
self.exe = [file_path]
self.default_env = {}
- from spack.util.environment import EnvironmentModifications # no cycle
self.default_envmod = EnvironmentModifications()
self.returncode = None