diff --git a/src/executor.rs b/src/executor.rs index 3b9558b5..4280037c 100644 --- a/src/executor.rs +++ b/src/executor.rs @@ -37,7 +37,6 @@ impl RunType { } } - #[cfg(feature = "self-update")] /// Tells whether we're performing a dry run. pub fn dry(self) -> bool { match self { diff --git a/src/main.rs b/src/main.rs index fd5a2f53..42a2df80 100644 --- a/src/main.rs +++ b/src/main.rs @@ -136,7 +136,7 @@ fn run() -> Result<(), Error> { execute( &mut report, remote_topgrade, - || generic::run_remote_topgrade(run_type, remote_topgrade), + || generic::run_remote_topgrade(run_type, remote_topgrade, config.run_in_tmux()), config.no_retry(), )?; } diff --git a/src/steps/generic.rs b/src/steps/generic.rs index ff0b0dfc..4d9a2bc2 100644 --- a/src/steps/generic.rs +++ b/src/steps/generic.rs @@ -137,17 +137,27 @@ pub fn run_composer_update(base_dirs: &BaseDirs, run_type: RunType) -> Result<() Ok(()) } -pub fn run_remote_topgrade(run_type: RunType, hostname: &str) -> Result<(), Error> { +pub fn run_remote_topgrade(run_type: RunType, hostname: &str, run_in_tmux: bool) -> Result<(), Error> { let ssh = utils::require("ssh")?; - run_type - .execute(&ssh) - .args(&[ - "-t", - hostname, - "env", - &format!("TOPGRADE_PREFIX={}", hostname), - "topgrade", - ]) - .check_run() + if run_in_tmux && !run_type.dry() { + #[cfg(unix)] + { + crate::tmux::run_remote_topgrade(hostname, &ssh)?; + Err(ErrorKind::SkipStep)? + } + + unreachable!("Tmux execution is only implemented in Unix"); + } else { + run_type + .execute(&ssh) + .args(&[ + "-t", + hostname, + "env", + &format!("TOPGRADE_PREFIX={}", hostname), + "topgrade", + ]) + .check_run() + } } diff --git a/src/steps/tmux.rs b/src/steps/tmux.rs index cc7a0414..32e7056f 100644 --- a/src/steps/tmux.rs +++ b/src/steps/tmux.rs @@ -82,3 +82,19 @@ pub fn run_in_tmux() -> ! { exit(0); } } + +pub fn run_remote_topgrade(hostname: &str, ssh: &Path) -> Result<(), Error> { + let command = format!( + "{ssh} -t {hostname} env TOPGRADE_PREFIX={hostname} topgrade", + ssh = ssh.display(), + hostname = hostname + ); + Command::new(which("tmux").unwrap()) + .args(&["new-window", "-a", "-t", "topgrade:1", "-n", hostname, &command]) + .env_remove("TMUX") + .spawn() + .context(ErrorKind::ProcessExecution)? + .wait() + .context(ErrorKind::ProcessExecution)? + .check() +}