config: make path replacements lazy (#34758)
Currently, all of the replacements in `spack.util.path.replacements()` get evaluated for each replacement. This makes it easy to get bootstrap issues, because config is used very early on in Spack. Right now, if I run `test_autotools_gnuconfig_replacement_no_gnuconfig` on my M1 mac, I get the circular reference error below. This fixes the issue by making all of the path replacements lazy lambdas. As a bonus, this cleans up the way we do substitution for `$env` -- it's consistent with other substitutions now. - [x] make all path `replacements()` lazy - [x] clean up handling of `$env` ```console > spack unit-test -k test_autotools_gnuconfig_replacement_no_gnuconfig ... ==> [2022-12-31-15:44:21.771459] Error: AttributeError: The 'autotools-config-replacement' package cannot find an attribute while trying to build from sources. This might be due to a change in Spack's package format to support multiple build-systems for a single package. You can fix this by updating the build recipe, and you can also report the issue as a bug. More information at https://spack.readthedocs.io/en/latest/packaging_guide.html#installation-procedure /Users/gamblin2/src/spack/lib/spack/spack/package_base.py:1332, in prefix: 1330 @property 1331 def prefix(self): >> 1332 """Get the prefix into which this package should be installed.""" 1333 return self.spec.prefix Traceback (most recent call last): File "/Users/gamblin2/src/spack/lib/spack/spack/build_environment.py", line 1030, in _setup_pkg_and_run kwargs["env_modifications"] = setup_package( ^^^^^^^^^^^^^^ File "/Users/gamblin2/src/spack/lib/spack/spack/build_environment.py", line 757, in setup_package set_module_variables_for_package(pkg) File "/Users/gamblin2/src/spack/lib/spack/spack/build_environment.py", line 596, in set_module_variables_for_package m.std_cmake_args = spack.build_systems.cmake.CMakeBuilder.std_args(pkg) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/gamblin2/src/spack/lib/spack/spack/build_systems/cmake.py", line 241, in std_args define("CMAKE_INSTALL_PREFIX", pkg.prefix), ^^^^^^^^^^ File "/Users/gamblin2/src/spack/lib/spack/spack/package_base.py", line 1333, in prefix return self.spec.prefix ^^^^^^^^^^^^^^^^ File "/Users/gamblin2/src/spack/lib/spack/spack/spec.py", line 1710, in prefix self.prefix = spack.store.layout.path_for_spec(self) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/gamblin2/src/spack/lib/spack/spack/directory_layout.py", line 336, in path_for_spec path = self.relative_path_for_spec(spec) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/gamblin2/src/spack/lib/spack/spack/directory_layout.py", line 106, in relative_path_for_spec projection = spack.projections.get_projection(self.projections, spec) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/gamblin2/src/spack/lib/spack/spack/projections.py", line 13, in get_projection if spec.satisfies(spec_like, strict=True): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/gamblin2/src/spack/lib/spack/spack/spec.py", line 3642, in satisfies if not self.virtual and other.virtual: ^^^^^^^^^^^^ File "/Users/gamblin2/src/spack/lib/spack/spack/spec.py", line 1622, in virtual return spack.repo.path.is_virtual(self.name) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/gamblin2/src/spack/lib/spack/spack/repo.py", line 890, in is_virtual return have_name and pkg_name in self.provider_index ^^^^^^^^^^^^^^^^^^^ File "/Users/gamblin2/src/spack/lib/spack/spack/repo.py", line 770, in provider_index self._provider_index.merge(repo.provider_index) ^^^^^^^^^^^^^^^^^^^ File "/Users/gamblin2/src/spack/lib/spack/spack/repo.py", line 1096, in provider_index return self.index["providers"] ~~~~~~~~~~^^^^^^^^^^^^^ File "/Users/gamblin2/src/spack/lib/spack/spack/repo.py", line 592, in __getitem__ self._build_all_indexes() File "/Users/gamblin2/src/spack/lib/spack/spack/repo.py", line 607, in _build_all_indexes self.indexes[name] = self._build_index(name, indexer) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/gamblin2/src/spack/lib/spack/spack/repo.py", line 616, in _build_index index_mtime = self.cache.mtime(cache_filename) ^^^^^^^^^^^^^^^^ File "/Users/gamblin2/src/spack/lib/spack/llnl/util/lang.py", line 826, in __getattr__ return getattr(self.instance, name) ^^^^^^^^^^^^^ File "/Users/gamblin2/src/spack/lib/spack/llnl/util/lang.py", line 825, in __getattr__ raise AttributeError() AttributeError ```
This commit is contained in:
parent
33859d3d5f
commit
88a604e7f4
1 changed files with 23 additions and 23 deletions
|
@ -51,26 +51,32 @@ def get_user():
|
|||
return getpass.getuser()
|
||||
|
||||
|
||||
# return value for replacements with no match
|
||||
NOMATCH = object()
|
||||
|
||||
|
||||
# Substitutions to perform
|
||||
def replacements():
|
||||
# break circular import from spack.util.executable
|
||||
# break circular imports
|
||||
import spack.environment as ev
|
||||
import spack.paths
|
||||
|
||||
arch = architecture()
|
||||
|
||||
return {
|
||||
"spack": spack.paths.prefix,
|
||||
"user": get_user(),
|
||||
"tempdir": tempfile.gettempdir(),
|
||||
"user_cache_path": spack.paths.user_cache_path,
|
||||
"architecture": str(arch),
|
||||
"arch": str(arch),
|
||||
"platform": str(arch.platform),
|
||||
"operating_system": str(arch.os),
|
||||
"os": str(arch.os),
|
||||
"target": str(arch.target),
|
||||
"target_family": str(arch.target.microarchitecture.family),
|
||||
"date": date.today().strftime("%Y-%m-%d"),
|
||||
"spack": lambda: spack.paths.prefix,
|
||||
"user": lambda: get_user(),
|
||||
"tempdir": lambda: tempfile.gettempdir(),
|
||||
"user_cache_path": lambda: spack.paths.user_cache_path,
|
||||
"architecture": lambda: arch,
|
||||
"arch": lambda: arch,
|
||||
"platform": lambda: arch.platform,
|
||||
"operating_system": lambda: arch.os,
|
||||
"os": lambda: arch.os,
|
||||
"target": lambda: arch.target,
|
||||
"target_family": lambda: arch.target.microarchitecture.family,
|
||||
"date": lambda: date.today().strftime("%Y-%m-%d"),
|
||||
"env": lambda: ev.active_environment().path if ev.active_environment() else NOMATCH,
|
||||
}
|
||||
|
||||
|
||||
|
@ -293,20 +299,14 @@ def substitute_config_variables(path):
|
|||
replaced if there is an active environment, and should only be used in
|
||||
environment yaml files.
|
||||
"""
|
||||
import spack.environment as ev # break circular
|
||||
|
||||
_replacements = replacements()
|
||||
env = ev.active_environment()
|
||||
if env:
|
||||
_replacements.update({"env": env.path})
|
||||
else:
|
||||
# If a previous invocation added env, remove it
|
||||
_replacements.pop("env", None)
|
||||
|
||||
# Look up replacements
|
||||
def repl(match):
|
||||
m = match.group(0).strip("${}")
|
||||
return _replacements.get(m.lower(), match.group(0))
|
||||
m = match.group(0)
|
||||
key = m.strip("${}").lower()
|
||||
repl = _replacements.get(key, lambda: m)()
|
||||
return m if repl is NOMATCH else str(repl)
|
||||
|
||||
# Replace $var or ${var}.
|
||||
return re.sub(r"(\$\w+\b|\$\{\w+\})", repl, path)
|
||||
|
|
Loading…
Reference in a new issue