use dialoguer::Confirm;
use tokio::process::Command;
use crate::{
cli::atomic::{should_accept_all, should_dry_run, should_not_restart_services},
log_dry, log_err, log_info, log_prompt, log_warn,
};
use anyhow::{Context, Result};
#[must_use]
pub fn confirm(prompt: &str) -> bool {
if should_accept_all() {
log_prompt!("{prompt} (auto-accepted)");
return true;
}
Confirm::new()
.with_prompt(prompt)
.interact()
.unwrap_or_default()
}
pub async fn open(arg: &str) -> Result<()> {
let _ = Command::new("open")
.arg(arg)
.status()
.await
.with_context(|| format!("Failed to run: open {arg}"))?;
Ok(())
}
pub async fn restart_services() {
if should_not_restart_services() {
return;
}
let dry_run = should_dry_run();
const SERVICES: &[&str] = &[
"SystemUIServer",
"Dock",
"Finder",
"ControlCenter",
"NotificationCenter",
];
let mut failed: bool = false;
for svc in SERVICES {
if dry_run {
log_dry!("Would restart {svc}");
} else if let Ok(out) = Command::new("killall").arg(svc).output().await {
if out.status.success() {
log_info!("{svc} restarted");
} else {
log_err!("Failed to restart {svc}");
failed = true;
}
} else {
log_err!("Could not restart {svc}");
continue;
}
}
if failed {
log_warn!("Being quick with commands can cause your computer to run out of breath.");
}
}