Windows: shell variables are case-insensitive (#36813)
If we modify both Path and PATH, on Windows they will clobber one another. This PR updates the shell modification logic to automatically convert variable names to upper-case on Windows.
This commit is contained in:
parent
255c9ed5e9
commit
d8451b0c3f
@ -164,7 +164,7 @@ def setup_custom_environment(self, pkg, env):
|
||||
out = out.decode("utf-16le", errors="replace") # novermin
|
||||
|
||||
int_env = dict(
|
||||
(key.lower(), value)
|
||||
(key, value)
|
||||
for key, _, value in (line.partition("=") for line in out.splitlines())
|
||||
if key and value
|
||||
)
|
||||
|
@ -14,6 +14,7 @@
|
||||
import re
|
||||
import socket
|
||||
import sys
|
||||
from functools import wraps
|
||||
from typing import Any, Callable, Dict, List, MutableMapping, Optional, Tuple, Union
|
||||
|
||||
from llnl.util import tty
|
||||
@ -83,6 +84,28 @@ def double_quote_escape(s):
|
||||
return '"' + s.replace('"', r"\"") + '"'
|
||||
|
||||
|
||||
def system_env_normalize(func):
|
||||
"""Decorator wrapping calls to system env modifications,
|
||||
converting all env variable names to all upper case on Windows, no-op
|
||||
on other platforms before calling env modification method.
|
||||
|
||||
Windows, due to a DOS holdover, treats all env variable names case
|
||||
insensitively, however Spack's env modification class does not,
|
||||
meaning setting `Path` and `PATH` would be distinct env operations
|
||||
for Spack, but would cause a collision when actually performing the
|
||||
env modification operations on the env.
|
||||
Normalize all env names to all caps to prevent this collision from the
|
||||
Spack side."""
|
||||
|
||||
@wraps(func)
|
||||
def case_insensitive_modification(self, name: str, *args, **kwargs):
|
||||
if sys.platform == "win32":
|
||||
name = name.upper()
|
||||
return func(self, name, *args, **kwargs)
|
||||
|
||||
return case_insensitive_modification
|
||||
|
||||
|
||||
def is_system_path(path: Path) -> bool:
|
||||
"""Returns True if the argument is a system path, False otherwise."""
|
||||
return bool(path) and (os.path.normpath(path) in SYSTEM_DIRS)
|
||||
@ -466,6 +489,7 @@ def _trace(self) -> Optional[Trace]:
|
||||
|
||||
return Trace(filename=filename, lineno=lineno, context=current_context)
|
||||
|
||||
@system_env_normalize
|
||||
def set(self, name: str, value: str, *, force: bool = False):
|
||||
"""Stores a request to set an environment variable.
|
||||
|
||||
@ -477,6 +501,7 @@ def set(self, name: str, value: str, *, force: bool = False):
|
||||
item = SetEnv(name, value, trace=self._trace(), force=force)
|
||||
self.env_modifications.append(item)
|
||||
|
||||
@system_env_normalize
|
||||
def append_flags(self, name: str, value: str, sep: str = " "):
|
||||
"""Stores a request to append 'flags' to an environment variable.
|
||||
|
||||
@ -488,6 +513,7 @@ def append_flags(self, name: str, value: str, sep: str = " "):
|
||||
item = AppendFlagsEnv(name, value, separator=sep, trace=self._trace())
|
||||
self.env_modifications.append(item)
|
||||
|
||||
@system_env_normalize
|
||||
def unset(self, name: str):
|
||||
"""Stores a request to unset an environment variable.
|
||||
|
||||
@ -497,6 +523,7 @@ def unset(self, name: str):
|
||||
item = UnsetEnv(name, trace=self._trace())
|
||||
self.env_modifications.append(item)
|
||||
|
||||
@system_env_normalize
|
||||
def remove_flags(self, name: str, value: str, sep: str = " "):
|
||||
"""Stores a request to remove flags from an environment variable
|
||||
|
||||
@ -508,6 +535,7 @@ def remove_flags(self, name: str, value: str, sep: str = " "):
|
||||
item = RemoveFlagsEnv(name, value, separator=sep, trace=self._trace())
|
||||
self.env_modifications.append(item)
|
||||
|
||||
@system_env_normalize
|
||||
def set_path(self, name: str, elements: List[str], separator: str = os.pathsep):
|
||||
"""Stores a request to set an environment variable to a list of paths,
|
||||
separated by a character defined in input.
|
||||
@ -520,6 +548,7 @@ def set_path(self, name: str, elements: List[str], separator: str = os.pathsep):
|
||||
item = SetPath(name, elements, separator=separator, trace=self._trace())
|
||||
self.env_modifications.append(item)
|
||||
|
||||
@system_env_normalize
|
||||
def append_path(self, name: str, path: str, separator: str = os.pathsep):
|
||||
"""Stores a request to append a path to list of paths.
|
||||
|
||||
@ -531,6 +560,7 @@ def append_path(self, name: str, path: str, separator: str = os.pathsep):
|
||||
item = AppendPath(name, path, separator=separator, trace=self._trace())
|
||||
self.env_modifications.append(item)
|
||||
|
||||
@system_env_normalize
|
||||
def prepend_path(self, name: str, path: str, separator: str = os.pathsep):
|
||||
"""Stores a request to prepend a path to list of paths.
|
||||
|
||||
@ -542,6 +572,7 @@ def prepend_path(self, name: str, path: str, separator: str = os.pathsep):
|
||||
item = PrependPath(name, path, separator=separator, trace=self._trace())
|
||||
self.env_modifications.append(item)
|
||||
|
||||
@system_env_normalize
|
||||
def remove_path(self, name: str, path: str, separator: str = os.pathsep):
|
||||
"""Stores a request to remove a path from a list of paths.
|
||||
|
||||
@ -553,6 +584,7 @@ def remove_path(self, name: str, path: str, separator: str = os.pathsep):
|
||||
item = RemovePath(name, path, separator=separator, trace=self._trace())
|
||||
self.env_modifications.append(item)
|
||||
|
||||
@system_env_normalize
|
||||
def deprioritize_system_paths(self, name: str, separator: str = os.pathsep):
|
||||
"""Stores a request to deprioritize system paths in a path list,
|
||||
otherwise preserving the order.
|
||||
@ -564,6 +596,7 @@ def deprioritize_system_paths(self, name: str, separator: str = os.pathsep):
|
||||
item = DeprioritizeSystemPaths(name, separator=separator, trace=self._trace())
|
||||
self.env_modifications.append(item)
|
||||
|
||||
@system_env_normalize
|
||||
def prune_duplicate_paths(self, name: str, separator: str = os.pathsep):
|
||||
"""Stores a request to remove duplicates from a path list, otherwise
|
||||
preserving the order.
|
||||
|
Loading…
Reference in New Issue
Block a user