fix(powershell): execution policy check breaks when run in pwsh
When topgrade is run from within pwsh, the execution policy check breaks for the Windows Update and Windows Store steps, because they use normal powershell and the inherited PSModulePath environment variable breaks the Microsoft.PowerShell.Security module import. So we unset that variable to fix the issue, but also allow for those steps to use pwsh as neither step actually requires PowerShell 5. Co-authored-by: nistee <52573120+niStee@users.noreply.github.com>
This commit is contained in:
@@ -1,14 +1,16 @@
|
||||
#![allow(dead_code)]
|
||||
use color_eyre::eyre::Result;
|
||||
use std::env::var;
|
||||
use std::path::Path;
|
||||
use std::sync::{LazyLock, Mutex};
|
||||
|
||||
use crate::executor::RunType;
|
||||
use crate::powershell::Powershell;
|
||||
#[cfg(target_os = "linux")]
|
||||
use crate::steps::linux::Distribution;
|
||||
use crate::sudo::Sudo;
|
||||
use crate::utils::{get_require_sudo_string, require_option};
|
||||
use crate::{config::Config, executor::Executor};
|
||||
use color_eyre::eyre::Result;
|
||||
use std::env::var;
|
||||
use std::path::Path;
|
||||
use std::sync::Mutex;
|
||||
|
||||
pub struct ExecutionContext<'a> {
|
||||
run_type: RunType,
|
||||
@@ -22,6 +24,7 @@ pub struct ExecutionContext<'a> {
|
||||
under_ssh: bool,
|
||||
#[cfg(target_os = "linux")]
|
||||
distribution: &'a Result<Distribution>,
|
||||
powershell: LazyLock<Powershell>,
|
||||
}
|
||||
|
||||
impl<'a> ExecutionContext<'a> {
|
||||
@@ -40,6 +43,7 @@ impl<'a> ExecutionContext<'a> {
|
||||
under_ssh,
|
||||
#[cfg(target_os = "linux")]
|
||||
distribution,
|
||||
powershell: LazyLock::new(Powershell::new),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,4 +80,8 @@ impl<'a> ExecutionContext<'a> {
|
||||
pub fn distribution(&self) -> &Result<Distribution> {
|
||||
self.distribution
|
||||
}
|
||||
|
||||
pub fn powershell(&self) -> &Powershell {
|
||||
&self.powershell
|
||||
}
|
||||
}
|
||||
|
||||
@@ -464,7 +464,7 @@ impl Step {
|
||||
Pnpm => runner.execute(*self, "pnpm", || node::run_pnpm_upgrade(ctx))?,
|
||||
Poetry => runner.execute(*self, "Poetry", || generic::run_poetry(ctx))?,
|
||||
Powershell => {
|
||||
let powershell = powershell::Powershell::new();
|
||||
let powershell = ctx.powershell();
|
||||
if powershell.is_available() {
|
||||
runner.execute(Powershell, "Powershell Modules Update", || {
|
||||
powershell.update_modules(ctx)
|
||||
|
||||
@@ -7,7 +7,6 @@ use tracing::debug;
|
||||
|
||||
use crate::command::CommandExt;
|
||||
use crate::execution_context::ExecutionContext;
|
||||
use crate::powershell;
|
||||
use crate::step::Step;
|
||||
use crate::terminal::{print_separator, print_warning};
|
||||
use crate::utils::{require, which};
|
||||
@@ -226,7 +225,7 @@ pub fn run_wsl_topgrade(ctx: &ExecutionContext) -> Result<()> {
|
||||
}
|
||||
|
||||
pub fn windows_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
let powershell = powershell::Powershell::windows_powershell();
|
||||
let powershell = ctx.powershell();
|
||||
|
||||
print_separator(t!("Windows Update"));
|
||||
|
||||
@@ -244,7 +243,7 @@ pub fn windows_update(ctx: &ExecutionContext) -> Result<()> {
|
||||
}
|
||||
|
||||
pub fn microsoft_store(ctx: &ExecutionContext) -> Result<()> {
|
||||
let powershell = powershell::Powershell::windows_powershell();
|
||||
let powershell = ctx.powershell();
|
||||
|
||||
print_separator(t!("Microsoft Store"));
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ impl Powershell {
|
||||
.or_else(|| which("powershell").map(|p| (Some(p), false)))
|
||||
.unwrap_or((None, false));
|
||||
|
||||
let profile = path.as_ref().and_then(Self::get_profile);
|
||||
let profile = path.as_ref().and_then(|path| Self::get_profile(path, is_pwsh));
|
||||
|
||||
Self { path, profile, is_pwsh }
|
||||
}
|
||||
@@ -43,29 +43,12 @@ impl Powershell {
|
||||
self.path.is_some()
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
pub fn windows_powershell() -> Self {
|
||||
if terminal::is_dumb() {
|
||||
return Self {
|
||||
path: None,
|
||||
profile: None,
|
||||
is_pwsh: false,
|
||||
};
|
||||
}
|
||||
|
||||
Self {
|
||||
path: which("powershell"),
|
||||
profile: None,
|
||||
is_pwsh: false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn profile(&self) -> Option<&PathBuf> {
|
||||
self.profile.as_ref()
|
||||
}
|
||||
|
||||
fn get_profile(path: &PathBuf) -> Option<PathBuf> {
|
||||
let profile = Self::build_command_internal(path, "Split-Path $PROFILE")
|
||||
fn get_profile(path: &PathBuf, is_pwsh: bool) -> Option<PathBuf> {
|
||||
let profile = Self::build_command_internal(path, is_pwsh, "Split-Path $PROFILE")
|
||||
.output_checked_utf8()
|
||||
.map(|output| output.stdout.trim().to_string())
|
||||
.and_then(|s| PathBuf::from(s).require())
|
||||
@@ -75,12 +58,18 @@ impl Powershell {
|
||||
}
|
||||
|
||||
/// Builds an "internal" powershell command
|
||||
fn build_command_internal(path: &PathBuf, cmd: &str) -> Command {
|
||||
fn build_command_internal(path: &PathBuf, is_pwsh: bool, cmd: &str) -> Command {
|
||||
let mut command = Command::new(path);
|
||||
|
||||
command.args(["-NoProfile", "-Command"]);
|
||||
command.arg(cmd);
|
||||
|
||||
// If topgrade was run from pwsh, but we are trying to run powershell, then
|
||||
// the inherited PSModulePath breaks module imports
|
||||
if !is_pwsh {
|
||||
command.env_remove("PSModulePath");
|
||||
}
|
||||
|
||||
command
|
||||
}
|
||||
|
||||
@@ -106,6 +95,12 @@ impl Powershell {
|
||||
command.args(["-NoProfile", "-Command"]);
|
||||
command.arg(cmd);
|
||||
|
||||
// If topgrade was run from pwsh, but we are trying to run powershell, then
|
||||
// the inherited PSModulePath breaks module imports
|
||||
if !self.is_pwsh {
|
||||
command.env_remove("PSModulePath");
|
||||
}
|
||||
|
||||
Ok(command)
|
||||
}
|
||||
|
||||
@@ -158,7 +153,7 @@ impl Powershell {
|
||||
// Find the index of our target policy
|
||||
let target_idx = valid_policies.iter().position(|&p| p == policy);
|
||||
|
||||
let mut command = Self::build_command_internal(powershell, "Get-ExecutionPolicy");
|
||||
let mut command = Self::build_command_internal(powershell, self.is_pwsh, "Get-ExecutionPolicy");
|
||||
|
||||
let current_policy = command
|
||||
.output_checked_utf8()
|
||||
@@ -187,7 +182,7 @@ impl Powershell {
|
||||
if let Some(powershell) = &self.path {
|
||||
let cmd = format!("Get-Module -ListAvailable {}", module_name);
|
||||
|
||||
return Self::build_command_internal(powershell, &cmd)
|
||||
return Self::build_command_internal(powershell, self.is_pwsh, &cmd)
|
||||
.output_checked()
|
||||
.map(|output| !output.stdout.trim_ascii().is_empty())
|
||||
.unwrap_or(false);
|
||||
|
||||
Reference in New Issue
Block a user