fix(oh-my-zsh): fix remote oh-my-zsh issue (#496)

* fix(oh-my-zsh): fix remote oh-my-zsh issue
This commit is contained in:
SteveLauC
2023-07-18 13:59:55 +08:00
committed by GitHub
parent 42188af02b
commit 9415d7c61f
2 changed files with 31 additions and 0 deletions

View File

@@ -5,6 +5,7 @@ use crate::sudo::Sudo;
use crate::utils::{require_option, REQUIRE_SUDO}; use crate::utils::{require_option, REQUIRE_SUDO};
use crate::{config::Config, executor::Executor}; use crate::{config::Config, executor::Executor};
use color_eyre::eyre::Result; use color_eyre::eyre::Result;
use std::env::var;
use std::path::Path; use std::path::Path;
use std::sync::Mutex; use std::sync::Mutex;
@@ -17,16 +18,20 @@ pub struct ExecutionContext<'a> {
/// This is used in `./steps/remote/ssh.rs`, where we want to run `topgrade` in a new /// This is used in `./steps/remote/ssh.rs`, where we want to run `topgrade` in a new
/// tmux window for each remote. /// tmux window for each remote.
tmux_session: Mutex<Option<String>>, tmux_session: Mutex<Option<String>>,
/// True if topgrade is running under ssh.
under_ssh: bool,
} }
impl<'a> ExecutionContext<'a> { impl<'a> ExecutionContext<'a> {
pub fn new(run_type: RunType, sudo: Option<Sudo>, git: &'a Git, config: &'a Config) -> Self { pub fn new(run_type: RunType, sudo: Option<Sudo>, git: &'a Git, config: &'a Config) -> Self {
let under_ssh = var("SSH_CLIENT").is_ok() || var("SSH_TTY").is_ok();
Self { Self {
run_type, run_type,
sudo, sudo,
git, git,
config, config,
tmux_session: Mutex::new(None), tmux_session: Mutex::new(None),
under_ssh,
} }
} }
@@ -51,6 +56,10 @@ impl<'a> ExecutionContext<'a> {
self.config self.config
} }
pub fn under_ssh(&self) -> bool {
self.under_ssh
}
pub fn set_tmux_session(&self, session_name: String) { pub fn set_tmux_session(&self, session_name: String) {
self.tmux_session.lock().unwrap().replace(session_name); self.tmux_session.lock().unwrap().replace(session_name);
} }

View File

@@ -165,6 +165,28 @@ pub fn run_zim(ctx: &ExecutionContext) -> Result<()> {
pub fn run_oh_my_zsh(ctx: &ExecutionContext) -> Result<()> { pub fn run_oh_my_zsh(ctx: &ExecutionContext) -> Result<()> {
require("zsh")?; require("zsh")?;
// When updating `oh-my-zsh` on a remote machine through topgrade, the
// following processes will be created:
//
// SSH -> ZSH -> ZSH ($SHELL) -> topgrade -> ZSH
//
// The first ZSH process, won't source zshrc (as it is a login shell),
// and thus it won't have the ZSH environment variable, as a result, the
// children processes won't get it either, so we source the zshrc and set
// the ZSH variable for topgrade here.
if ctx.under_ssh() {
let zshrc_path = zshrc().require()?;
let output = Command::new("zsh")
.args([
"-c",
// ` > /dev/null` is used in case the user's zshrc will have some stdout output.
format!("source {} > /dev/null && echo $ZSH", zshrc_path.display()).as_str(),
])
.output_checked_utf8()?;
env::set_var("ZSH", output.stdout.trim());
}
let oh_my_zsh = env::var("ZSH") let oh_my_zsh = env::var("ZSH")
.map(PathBuf::from) .map(PathBuf::from)
// default to `~/.oh-my-zsh` // default to `~/.oh-my-zsh`