Files
topgrade/src/steps/powershell.rs

107 lines
3.2 KiB
Rust
Raw Normal View History

2020-02-27 22:06:14 +02:00
use crate::execution_context::ExecutionContext;
2020-07-15 08:47:15 +03:00
use crate::executor::CommandExt;
2019-08-14 21:36:57 +03:00
use crate::terminal::{is_dumb, print_separator};
use crate::utils::{require_option, which, PathExt};
use anyhow::Result;
2019-08-14 21:36:57 +03:00
use std::path::PathBuf;
use std::process::Command;
pub struct Powershell {
path: Option<PathBuf>,
profile: Option<PathBuf>,
}
impl Powershell {
/// Returns a powershell instance.
///
/// If the powershell binary is not found, or the current terminal is dumb
/// then the instance of this struct will skip all the powershell steps.
pub fn new() -> Self {
let path = which("pwsh").or_else(|| which("powershell")).filter(|_| !is_dumb());
let profile = path.as_ref().and_then(|path| {
Command::new(path)
.args(&["-Command", "echo $profile"])
.check_output()
.map(|output| PathBuf::from(output.trim()))
.and_then(|p| p.require())
.ok()
});
Powershell { path, profile }
}
#[cfg(windows)]
pub fn windows_powershell() -> Self {
Powershell {
path: which("powershell").filter(|_| !is_dumb()),
profile: None,
}
}
2019-08-14 21:36:57 +03:00
#[cfg(windows)]
pub fn has_module(powershell: &PathBuf, command: &str) -> bool {
2019-08-15 09:20:31 +03:00
Command::new(&powershell)
.args(&["-Command", &format!("Get-Module -ListAvailable {}", command)])
.check_output()
.map(|result| !result.is_empty())
.unwrap_or(false)
2019-08-14 21:36:57 +03:00
}
pub fn profile(&self) -> Option<&PathBuf> {
self.profile.as_ref()
}
2020-07-15 08:47:15 +03:00
pub fn update_modules(&self, ctx: &ExecutionContext) -> Result<()> {
2020-08-21 23:04:36 +03:00
let powershell = require_option(self.path.as_ref(), String::from("Powershell is not installed"))?;
2019-08-14 21:36:57 +03:00
print_separator("Powershell Modules Update");
2020-07-15 08:47:15 +03:00
let cmd = if ctx.config().yes() {
"Update-Module -AcceptLicense -Force"
} else {
"Update-Module"
};
println!("Updating modules...");
2020-07-15 08:47:15 +03:00
ctx.run_type().execute(&powershell).args(&["-Command", cmd]).check_run()
2019-08-14 21:36:57 +03:00
}
#[cfg(windows)]
2020-02-27 22:06:14 +02:00
pub fn supports_windows_update(&self) -> bool {
self.path
.as_ref()
.map(|p| Self::has_module(&p, "PSWindowsUpdate"))
.unwrap_or(false)
}
#[cfg(windows)]
pub fn windows_update(&self, ctx: &ExecutionContext) -> Result<()> {
2020-08-21 23:04:36 +03:00
let powershell = require_option(self.path.as_ref(), String::from("Powershell is not installed"))?;
2019-08-14 21:36:57 +03:00
2020-02-27 22:06:14 +02:00
debug_assert!(self.supports_windows_update());
2019-08-14 21:36:57 +03:00
let mut command = if let Some(sudo) = ctx.sudo() {
let mut command = ctx.run_type().execute(sudo);
command.arg(&powershell);
command
} else {
ctx.run_type().execute(&powershell)
};
command
2019-08-14 21:36:57 +03:00
.args(&[
"-Command",
&format!(
"Import-Module PSWindowsUpdate; Install-WindowsUpdate -MicrosoftUpdate {} -Verbose",
2020-02-27 22:06:14 +02:00
if ctx.config().accept_all_windows_updates() {
"-AcceptAll"
} else {
""
}
),
2019-08-14 21:36:57 +03:00
])
.check_run()
}
}