Skip to content

Commit

Permalink
Improve PowerShell plugin's profile handling functionality
Browse files Browse the repository at this point in the history
* Add support for the `package_commands_sourced_first` config switch.

Prior to this change, the rez PowerShell implementation would always
source the rez context script after the user/host profile scripts, so
profile-level modifications to environment variables like `PATH` were
always squashed by the unconditional overrides in the context script.

With this change, the relative source order of the shell profile vs.
the context script can be properly controlled using the
`package_commands_sourced_first` config option, matching the behavior
of `SH`-based shells.

NOTE: Because this config option defaults to True, this commit also
implicitly changes rez's default behavior to source the shell profile
*after* the context when using PowerShell.

* Support the `norc` shell plugin option, which enables the use of
`rez-env --norc` to bypass the sourcing of any profile scripts.

Signed-off-by: Nathan Rusch <[email protected]>
  • Loading branch information
nrusch committed Jun 21, 2024
1 parent a13f7bb commit 7f3678a
Showing 1 changed file with 27 additions and 8 deletions.
35 changes: 27 additions & 8 deletions src/rezplugins/shell/_utils/powershell_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,15 @@ class PowerShellBase(Shell):
expand_env_vars = True
syspaths = None

# PowerShell does not provide built-in functionality to manually trigger
# sourcing of the user/host profile scripts in the appropriate order, so we
# have to implement it ourselves in order to be able to control the relative
# source order of the user's profile vs. the generated rez context script.
profile_source_cmd = (
'$PROFILE '
'| Get-Member -type NoteProperty '
'| ForEach-Object { if (Test-Path $PROFILE."$($_.Name)") { . $PROFILE."$($_.Name)" }}')

# Make sure that the $Env:VAR formats come before the $VAR formats since
# PowerShell Environment variables are ambiguous with Unix paths.
# Note: This is used in other parts of Rez
Expand All @@ -49,10 +58,8 @@ def startup_capabilities(cls,
stdin=False,
command=False):
cls._unsupported_option('rcfile', rcfile)
cls._unsupported_option('norc', norc)
cls._unsupported_option('stdin', stdin)
rcfile = False
norc = False
stdin = False
return (rcfile, norc, stdin, command)

Expand Down Expand Up @@ -131,14 +138,23 @@ def spawn_shell(self,
quiet=False,
pre_command=None,
add_rez=True,
package_commands_sourced_first=None,
**Popen_args):

startup_sequence = self.get_startup_sequence(rcfile, norc, bool(stdin),
command)
shell_command = None

if package_commands_sourced_first is None:
package_commands_sourced_first = config.package_commands_sourced_first

def _record_shell(ex, files, bind_rez=True, print_msg=False):
ex.source(context_file)
if package_commands_sourced_first:
ex.source(context_file)
if not norc:
ex.command(self.profile_source_cmd)
if not package_commands_sourced_first:
ex.source(context_file)
if startup_sequence["envvar"]:
ex.unsetenv(startup_sequence["envvar"])
if add_rez and bind_rez:
Expand Down Expand Up @@ -198,8 +214,14 @@ def _record_shell(ex, files, bind_rez=True, print_msg=False):

cmd += [self.executable]

# Suppresses copyright message of PowerShell and pwsh
cmd += ["-NoLogo"]
# `-NoLogo` suppresses copyright message of PowerShell and pwsh.
# `-NoProfile` skips automatic sourcing of user/host profile scripts.
# We manually inject the profile sourcing before or after the sourcing
# of the generated context script based on the value of
# `package_commands_sourced_first` (see `_record_shell` above).
cmd += ["-NoLogo", "-NoProfile"]
if shell_command is None:
cmd += ["-NoExit"]

# Powershell execution policy overrides
# Prevent injections/mistakes by ensuring policy value only contains letters.
Expand All @@ -210,9 +232,6 @@ def _record_shell(ex, files, bind_rez=True, print_msg=False):
# Generic form of sourcing that works in powershell and pwsh
cmd += ["-File", target_file]

if shell_command is None:
cmd.insert(1, "-NoExit")

p = Popen(cmd, env=env, **Popen_args)
return p

Expand Down

0 comments on commit 7f3678a

Please sign in to comment.