Ask before installing macOS upgrades (#433)

This commit is contained in:
Roey Darwish Dror
2020-06-15 15:43:59 +03:00
committed by GitHub
parent 69f5857b2e
commit 4d8dc69e7f
3 changed files with 69 additions and 10 deletions

View File

@@ -141,6 +141,8 @@ fn run() -> Result<()> {
#[cfg(unix)] #[cfg(unix)]
{ {
if config.should_run(Step::PackageManagers) { if config.should_run(Step::PackageManagers) {
#[cfg(target_os = "macos")]
runner.execute("Microsoft AutoUpdate", || macos::run_msupdate(&ctx))?;
runner.execute("brew", || unix::run_homebrew(&ctx))?; runner.execute("brew", || unix::run_homebrew(&ctx))?;
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
runner.execute("MacPorts", || macos::run_macports(&ctx))?; runner.execute("MacPorts", || macos::run_macports(&ctx))?;
@@ -361,9 +363,8 @@ fn run() -> Result<()> {
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
{ {
if config.should_run(Step::System) { if config.should_run(Step::System) {
runner.execute("Microsoft AutoUpdate", || macos::run_msupdate(&ctx))?;
runner.execute("App Store", || macos::run_mas(run_type))?; runner.execute("App Store", || macos::run_mas(run_type))?;
runner.execute("System upgrade", || macos::upgrade_macos(run_type))?; runner.execute("System upgrade", || macos::upgrade_macos(&ctx))?;
} }
} }

View File

@@ -1,9 +1,13 @@
use crate::execution_context::ExecutionContext; use crate::execution_context::ExecutionContext;
use crate::executor::RunType; use crate::executor::RunType;
use crate::terminal::print_separator; use crate::terminal::{print_separator, prompt_yesno};
use crate::utils::{require, PathExt}; use crate::{
error::{SkipStep, TopgradeError},
utils::{require, PathExt},
};
use anyhow::Result; use anyhow::Result;
use std::path::Path; use log::debug;
use std::{path::Path, process::Command};
pub fn run_msupdate(ctx: &ExecutionContext) -> Result<()> { pub fn run_msupdate(ctx: &ExecutionContext) -> Result<()> {
let msupdate = let msupdate =
@@ -41,11 +45,43 @@ pub fn run_mas(run_type: RunType) -> Result<()> {
run_type.execute(mas).arg("upgrade").check_run() run_type.execute(mas).arg("upgrade").check_run()
} }
pub fn upgrade_macos(run_type: RunType) -> Result<()> { pub fn upgrade_macos(ctx: &ExecutionContext) -> Result<()> {
print_separator("macOS system update"); print_separator("macOS system update");
run_type let should_ask = !(ctx.config().yes()) || (ctx.config().dry_run());
.execute("softwareupdate") if should_ask {
.args(&["--install", "--all"]) println!("Finding available software");
.check_run() if system_update_available()? {
let answer = prompt_yesno("A system update is available. Do you wish to install it?")?;
if !answer {
return Err(SkipStep.into());
}
println!();
} else {
println!("No new software available.");
return Err(SkipStep.into());
}
}
let mut command = ctx.run_type().execute("softwareupdate");
command.args(&["--install", "--all"]);
if should_ask {
command.arg("--no-scan");
}
command.check_run()
}
fn system_update_available() -> Result<bool> {
let output = Command::new("softwareupdate").arg("--list").output()?;
debug!("{:?}", output);
let status = output.status;
if !status.success() {
return Err(TopgradeError::ProcessFailed(status).into());
}
let string_output = String::from_utf8(output.stderr)?;
debug!("{:?}", string_output);
Ok(!string_output.contains("No new software available"))
} }

View File

@@ -176,6 +176,23 @@ impl Terminal {
.ok(); .ok();
} }
#[allow(dead_code)]
fn prompt_yesno(&mut self, question: &str) -> Result<bool, io::Error> {
self.term
.write_fmt(format_args!(
"{}",
style(format!("{} (y)es/(N)o", question,)).yellow().bold()
))
.ok();
loop {
match self.term.read_char()? {
'y' | 'Y' => break Ok(true),
'n' | 'N' | '\r' | '\n' => break Ok(false),
_ => (),
}
}
}
#[allow(unused_variables)] #[allow(unused_variables)]
fn should_retry(&mut self, interrupted: bool, step_name: &str) -> Result<bool, io::Error> { fn should_retry(&mut self, interrupted: bool, step_name: &str) -> Result<bool, io::Error> {
if self.width.is_none() { if self.width.is_none() {
@@ -275,3 +292,8 @@ pub fn set_desktop_notifications(desktop_notifications: bool) {
.unwrap() .unwrap()
.set_desktop_notifications(desktop_notifications); .set_desktop_notifications(desktop_notifications);
} }
#[allow(dead_code)]
pub fn prompt_yesno(question: &str) -> Result<bool, io::Error> {
TERMINAL.lock().unwrap().prompt_yesno(question)
}