diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/spack/spack/modules/common.py | 17 | ||||
-rw-r--r-- | lib/spack/spack/test/modules/lmod.py | 9 | ||||
-rw-r--r-- | lib/spack/spack/test/modules/tcl.py | 9 | ||||
-rw-r--r-- | lib/spack/spack/util/environment.py | 16 |
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 |