summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/spack/spack/modules/common.py17
-rw-r--r--lib/spack/spack/test/modules/lmod.py9
-rw-r--r--lib/spack/spack/test/modules/tcl.py9
-rw-r--r--lib/spack/spack/util/environment.py16
4 files changed, 42 insertions, 9 deletions
diff --git a/lib/spack/spack/modules/common.py b/lib/spack/spack/modules/common.py
index 6384069c42..08ef690953 100644
--- a/lib/spack/spack/modules/common.py
+++ b/lib/spack/spack/modules/common.py
@@ -671,6 +671,12 @@ class BaseContext(tengine.Context):
# the configure option section
return None
+ def modification_needs_formatting(self, modification):
+ """Returns True if environment modification entry needs to be formatted."""
+ return (
+ not isinstance(modification, (spack.util.environment.SetEnv)) or not modification.raw
+ )
+
@tengine.context_property
@memoized
def environment_modifications(self):
@@ -734,11 +740,12 @@ class BaseContext(tengine.Context):
_check_tokens_are_valid(x.name, message=msg)
# Transform them
x.name = spec.format(x.name, transform=transform)
- try:
- # Not every command has a value
- x.value = spec.format(x.value)
- except AttributeError:
- pass
+ if self.modification_needs_formatting(x):
+ try:
+ # Not every command has a value
+ x.value = spec.format(x.value)
+ except AttributeError:
+ pass
x.name = str(x.name).replace("-", "_")
return [(type(x).__name__, x) for x in env if x.name not in exclude]
diff --git a/lib/spack/spack/test/modules/lmod.py b/lib/spack/spack/test/modules/lmod.py
index 5cfb6896c3..20c7e30ce7 100644
--- a/lib/spack/spack/test/modules/lmod.py
+++ b/lib/spack/spack/test/modules/lmod.py
@@ -198,6 +198,15 @@ class TestLmod(object):
assert len([x for x in content if 'setenv("MANPATH", "/path/to/man")' in x]) == 1
assert len([x for x in content if 'append_path("MANPATH", "", ":")' in x]) == 0
+ @pytest.mark.regression("29578")
+ def test_setenv_raw_value(self, modulefile_content, module_configuration):
+ """Tests that we can set environment variable value without formatting it."""
+
+ module_configuration("autoload_direct")
+ content = modulefile_content("module-setenv-raw")
+
+ assert len([x for x in content if 'setenv("FOO", "{{name}}, {name}, {{}}, {}")' in x]) == 1
+
def test_help_message(self, modulefile_content, module_configuration):
"""Tests the generation of module help message."""
diff --git a/lib/spack/spack/test/modules/tcl.py b/lib/spack/spack/test/modules/tcl.py
index 283fad2583..9dee83bf0d 100644
--- a/lib/spack/spack/test/modules/tcl.py
+++ b/lib/spack/spack/test/modules/tcl.py
@@ -182,6 +182,15 @@ class TestTcl(object):
assert len([x for x in content if 'setenv MANPATH "/path/to/man"' in x]) == 1
assert len([x for x in content if 'append-path --delim ":" MANPATH ""' in x]) == 0
+ @pytest.mark.regression("29578")
+ def test_setenv_raw_value(self, modulefile_content, module_configuration):
+ """Tests that we can set environment variable value without formatting it."""
+
+ module_configuration("autoload_direct")
+ content = modulefile_content("module-setenv-raw")
+
+ assert len([x for x in content if 'setenv FOO "{{name}}, {name}, {{}}, {}"' in x]) == 1
+
def test_help_message(self, modulefile_content, module_configuration):
"""Tests the generation of module help message."""
diff --git a/lib/spack/spack/util/environment.py b/lib/spack/spack/util/environment.py
index ded31dcf39..bde7ce3780 100644
--- a/lib/spack/spack/util/environment.py
+++ b/lib/spack/spack/util/environment.py
@@ -351,13 +351,20 @@ class NameValueModifier:
class SetEnv(NameValueModifier):
- __slots__ = ("force",)
+ __slots__ = ("force", "raw")
def __init__(
- self, name: str, value: str, *, trace: Optional[Trace] = None, force: bool = False
+ self,
+ name: str,
+ value: str,
+ *,
+ trace: Optional[Trace] = None,
+ force: bool = False,
+ raw: bool = False,
):
super().__init__(name, value, trace=trace)
self.force = force
+ self.raw = raw
def execute(self, env: MutableMapping[str, str]):
tty.debug(f"SetEnv: {self.name}={str(self.value)}", level=3)
@@ -501,15 +508,16 @@ class EnvironmentModifications:
return Trace(filename=filename, lineno=lineno, context=current_context)
@system_env_normalize
- def set(self, name: str, value: str, *, force: bool = False):
+ def set(self, name: str, value: str, *, force: bool = False, raw: bool = False):
"""Stores a request to set an environment variable.
Args:
name: name of the environment variable
value: value of the environment variable
force: if True, audit will not consider this modification a warning
+ raw: if True, format of value string is skipped
"""
- item = SetEnv(name, value, trace=self._trace(), force=force)
+ item = SetEnv(name, value, trace=self._trace(), force=force, raw=raw)
self.env_modifications.append(item)
@system_env_normalize