diff --git a/src/main.rs b/src/main.rs index a26cb111..fd5a2f53 100644 --- a/src/main.rs +++ b/src/main.rs @@ -68,7 +68,7 @@ fn run() -> Result<(), Error> { let base_dirs = directories::BaseDirs::new().ok_or(ErrorKind::NoBaseDirectories)?; let config = Config::load(&base_dirs)?; - if config.run_in_tmux() && env::var("TMUX").is_err() { + if config.run_in_tmux() && env::var("TOPGRADE_INSIDE_TMUX").is_err() { #[cfg(unix)] { tmux::run_in_tmux(); @@ -498,6 +498,11 @@ fn run() -> Result<(), Error> { freebsd::audit_packages(&sudo).ok(); } + if env::var("TOPGRADE_KEEP_END").is_ok() { + println!("\nPress any key to continue"); + pause(); + } + if report.data().iter().all(|(_, succeeded)| *succeeded) { Ok(()) } else { diff --git a/src/steps/tmux.rs b/src/steps/tmux.rs index b51e432e..cc7a0414 100644 --- a/src/steps/tmux.rs +++ b/src/steps/tmux.rs @@ -8,7 +8,7 @@ use std::env; use std::io; use std::os::unix::process::CommandExt; use std::path::Path; -use std::process::Command; +use std::process::{exit, Command}; pub fn run_tpm(base_dirs: &BaseDirs, run_type: RunType) -> Result<(), Error> { let tpm = base_dirs @@ -24,6 +24,16 @@ pub fn run_tpm(base_dirs: &BaseDirs, run_type: RunType) -> Result<(), Error> { fn has_session(tmux: &Path, session_name: &str) -> Result { Ok(Command::new(tmux) .args(&["has-session", "-t", session_name]) + .env_remove("TMUX") + .output()? + .status + .success()) +} + +fn new_session(tmux: &Path, session_name: &str) -> Result { + Ok(Command::new(tmux) + .args(&["new-session", "-d", "-s", session_name, "-n", "dummy"]) + .env_remove("TMUX") .spawn()? .wait()? .success()) @@ -31,7 +41,8 @@ fn has_session(tmux: &Path, session_name: &str) -> Result { fn run_in_session(tmux: &Path, command: &str) -> Result<(), Error> { Command::new(tmux) - .args(&["new-window", "-a", "-t", "topgrade:1", command]) + .args(&["new-window", "-a", "-t", "topgrade:1", "-n", "local", command]) + .env_remove("TMUX") .spawn() .context(ErrorKind::ProcessExecution)? .wait() @@ -43,30 +54,31 @@ fn run_in_session(tmux: &Path, command: &str) -> Result<(), Error> { pub fn run_in_tmux() -> ! { let tmux = which("tmux").expect("Could not find tmux"); - let command = env::args().collect::>().join(" "); + let command = { + let mut command = vec![ + String::from("env"), + String::from("TOPGRADE_KEEP_END=1"), + String::from("TOPGRADE_INSIDE_TMUX=1"), + ]; + command.extend(env::args()); + command.join(" ") + }; - if has_session(&tmux, "topgrade").expect("Error launching tmux") { - run_in_session(&tmux, &command).expect("Error launching tmux"); + if !has_session(&tmux, "topgrade").expect("Error launching tmux") { + new_session(&tmux, "topgrade").expect("Error launching tmux"); + } + run_in_session(&tmux, &command).expect("Error launching tmux"); + Command::new(&tmux) + .args(&["kill-window", "-t", "topgrade:dummy"]) + .output() + .unwrap(); + + if env::var("TMUX").is_err() { let err = Command::new(tmux).args(&["attach", "-t", "topgrade"]).exec(); - panic!("{:?}", err); } else { - let err = Command::new(tmux) - .args(&[ - "new-session", - "-s", - "topgrade", - "-n", - "topgrade", - &command, - ";", - "set", - "remain-on-exit", - "on", - ]) - .exec(); - - panic!("{:?}", err); + println!("Topgrade launched in a new tmux session"); + exit(0); } } diff --git a/src/terminal.rs b/src/terminal.rs index 3b316ec9..2aa0927d 100644 --- a/src/terminal.rs +++ b/src/terminal.rs @@ -139,6 +139,11 @@ impl Terminal { answer } + + fn pause(&self) -> Result<(), io::Error> { + self.term.read_char()?; + Ok(()) + } } impl Default for Terminal { @@ -169,3 +174,7 @@ pub fn print_result>(key: P, succeeded: bool) { pub fn is_dumb() -> bool { TERMINAL.lock().unwrap().width.is_none() } + +pub fn pause() { + TERMINAL.lock().unwrap().pause().unwrap(); +}