use crate::cmd_debug;
use crate::exec::UpDuct;
use color_eyre::Result;
use duct::Expression;
use std::thread;
use std::time::Duration;
use tracing::debug;
use tracing::info;
use tracing::trace;
use tracing::warn;
pub(crate) fn get_and_keep_sudo(yes: bool) -> Result<()> {
let tty = cmd_debug!("tty")
.read()
.unwrap_or_else(|e| format!("Failed with: {e}"));
debug!("Current tty is: {tty}");
if current_user_is_root() {
debug!("Not getting sudo as we're already running as root.");
return Ok(());
}
if cmd_debug!("sudo", "-kn", "true")
.stderr_null()
.run_with(Expression::stdout_null)
.is_ok()
{
info!("Looks like passwordless sudo is enabled, not prompting for sudo.");
return Ok(());
}
let sudo_arg = if yes { "-vn" } else { "-v" };
info!("Prompting for your sudo password (the one you use to log in to this Mac)...");
cmd_debug!("sudo", sudo_arg).run_with(Expression::stdout_to_stderr)?;
thread::spawn(|| {
for _ in 1..1440 {
thread::sleep(Duration::from_secs(60));
if let Err(e) = cmd_debug!("sudo", "-vn").run_with(Expression::stdout_to_stderr) {
warn!("Refreshing sudo with 'sudo -vn' failed with: {e:#}");
}
}
});
Ok(())
}
pub(crate) fn current_user_is_root() -> bool {
let current_user_id = uzers::get_current_uid();
trace!("Found current user ID to be: {current_user_id}");
current_user_id == 0
}