From 1f4590f4368bd12f0886a0e8d53713270f4bd76d Mon Sep 17 00:00:00 2001 From: Ryan Kopf Date: Thu, 9 Apr 2026 20:59:40 -0500 Subject: [PATCH 1/2] Update to show the message relevant to your system. --- src/cli/self_update.rs | 45 ++++++++++------------------- src/cli/self_update/shell.rs | 56 ++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 30 deletions(-) diff --git a/src/cli/self_update.rs b/src/cli/self_update.rs index 762a1f1b07..1d6a2e623c 100644 --- a/src/cli/self_update.rs +++ b/src/cli/self_update.rs @@ -445,36 +445,20 @@ but will not be added automatically." }; } -#[cfg(not(windows))] -macro_rules! post_install_msg_unix_source_env { - () => { - r#"To configure your current shell, you need to source -the corresponding `env` file under {cargo_home}. - -This is usually done by running one of the following (note the leading DOT): - . "{cargo_home}/env" # For sh/bash/zsh/ash/dash/pdksh - source "{cargo_home}/env.fish" # For fish - source "{cargo_home_nushell}/env.nu" # For nushell - source "{cargo_home}/env.tcsh" # For tcsh - . "{cargo_home}/env.ps1" # For pwsh - source "{cargo_home}/env.xsh" # For xonsh -"# - }; -} - #[cfg(not(windows))] macro_rules! post_install_msg_unix { () => { - concat!( - r"# Rust is installed now. Great! + r"# Rust is installed now. Great! To get started you may need to restart your current shell. This would reload your `PATH` environment variable to include Cargo's bin directory ({cargo_home}/bin). -", - post_install_msg_unix_source_env!(), - ) +To configure your current shell, you need to source +the corresponding `env` file under {cargo_home}. + +This is usually done by running one of the following (note the leading DOT): +{source_env_lines}" }; } @@ -494,15 +478,16 @@ Cargo's bin directory ({cargo_home}\\bin). #[cfg(not(windows))] macro_rules! post_install_msg_unix_no_modify_path { () => { - concat!( - r"# Rust is installed now. Great! + r"# Rust is installed now. Great! To get started you need Cargo's bin directory ({cargo_home}/bin) in your `PATH` environment variable. This has not been done automatically. -", - post_install_msg_unix_source_env!(), - ) +To configure your current shell, you need to source +the corresponding `env` file under {cargo_home}. + +This is usually done by running one of the following (note the leading DOT): +{source_env_lines}" }; } @@ -661,19 +646,19 @@ pub(crate) async fn install( format!(post_install_msg_win!(), cargo_home = cargo_home) }; #[cfg(not(windows))] - let cargo_home_nushell = Nu.cargo_home_str(cfg.process)?; + let source_env_lines = shell::build_source_env_lines(cfg.process); #[cfg(not(windows))] let msg = if no_modify_path { format!( post_install_msg_unix_no_modify_path!(), cargo_home = cargo_home, - cargo_home_nushell = cargo_home_nushell, + source_env_lines = source_env_lines, ) } else { format!( post_install_msg_unix!(), cargo_home = cargo_home, - cargo_home_nushell = cargo_home_nushell, + source_env_lines = source_env_lines, ) }; md(&mut term, msg); diff --git a/src/cli/self_update/shell.rs b/src/cli/self_update/shell.rs index 04396f5b60..2dd1454f77 100644 --- a/src/cli/self_update/shell.rs +++ b/src/cli/self_update/shell.rs @@ -84,6 +84,9 @@ pub(crate) trait UnixShell { // heuristic should be used, assuming shells exist if any traces do. fn does_exist(&self, process: &Process) -> bool; + // Returns the display name of the shell, used in post-install messages. + fn name(&self) -> &'static str; + // Gives all rcfiles of a given shell that Rustup is concerned with. // Used primarily in checking rcfiles for cleanup. fn rcfiles(&self, process: &Process) -> Vec; @@ -128,6 +131,10 @@ impl UnixShell for Posix { true } + fn name(&self) -> &'static str { + "sh/ash/dash/pdksh" + } + fn rcfiles(&self, process: &Process) -> Vec { match process.home_dir() { Some(dir) => vec![dir.join(".profile")], @@ -149,6 +156,10 @@ impl UnixShell for Bash { !self.update_rcs(process).is_empty() } + fn name(&self) -> &'static str { + "bash" + } + fn rcfiles(&self, process: &Process) -> Vec { // Bash also may read .profile, however Rustup already includes handling // .profile as part of POSIX and always does setup for POSIX shells. @@ -197,6 +208,10 @@ impl UnixShell for Zsh { || utils::find_cmd(&["zsh"], process).is_some() } + fn name(&self) -> &'static str { + "zsh" + } + fn rcfiles(&self, process: &Process) -> Vec { [Zsh::zdotdir(process).ok(), process.home_dir()] .iter() @@ -229,6 +244,10 @@ impl UnixShell for Fish { || utils::find_cmd(&["fish"], process).is_some() } + fn name(&self) -> &'static str { + "fish" + } + // > "$XDG_CONFIG_HOME/fish/conf.d" (or "~/.config/fish/conf.d" if that variable is unset) for the user // from fn rcfiles(&self, process: &Process) -> Vec { @@ -278,6 +297,10 @@ impl UnixShell for Nu { || utils::find_cmd(&["nu"], process).is_some() } + fn name(&self) -> &'static str { + "nushell" + } + fn rcfiles(&self, process: &Process) -> Vec { let mut paths = vec![]; @@ -329,6 +352,10 @@ impl UnixShell for Tcsh { || utils::find_cmd(&["tcsh"], process).is_some() } + fn name(&self) -> &'static str { + "tcsh" + } + fn rcfiles(&self, process: &Process) -> Vec { let mut paths = vec![]; @@ -378,6 +405,10 @@ impl UnixShell for Pwsh { || utils::find_cmd(&["pwsh"], process).is_some() } + fn name(&self) -> &'static str { + "pwsh" + } + fn rcfiles(&self, process: &Process) -> Vec { let mut paths = vec![]; @@ -453,6 +484,10 @@ impl UnixShell for Xonsh { process.var("XONSHRC").is_ok() || utils::find_cmd(&["xonsh"], process).is_some() } + fn name(&self) -> &'static str { + "xonsh" + } + fn rcfiles(&self, process: &Process) -> Vec { let mut paths = vec![]; @@ -501,6 +536,27 @@ impl UnixShell for Xonsh { } } +/// Builds the shell source lines for the post-install message, showing only +/// shells that are available on the current system. Shells sharing the same +/// env file are grouped onto one line (e.g. sh/bash/zsh all use `env`). +pub(crate) fn build_source_env_lines(process: &Process) -> String { + let mut groups: Vec<(String, Vec<&'static str>)> = Vec::new(); + for shell in get_available_shells(process) { + let Ok(src) = shell.source_string(process) else { + continue; + }; + if let Some(group) = groups.iter_mut().find(|(s, _)| *s == src) { + group.1.push(shell.name()); + } else { + groups.push((src, vec![shell.name()])); + } + } + groups + .into_iter() + .map(|(src, names)| format!(" {} # For {}\n", src, names.join("/"))) + .collect() +} + pub(crate) fn legacy_paths(process: &Process) -> impl Iterator + '_ { let zprofiles = Zsh::zdotdir(process) .into_iter() From db659f06a55e4cbf1d1694c40ecb89f56ede0af0 Mon Sep 17 00:00:00 2001 From: Ryan Kopf Date: Fri, 10 Apr 2026 10:49:41 -0500 Subject: [PATCH 2/2] Update nits --- src/cli/self_update/shell.rs | 42 ++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/cli/self_update/shell.rs b/src/cli/self_update/shell.rs index 2dd1454f77..06d10a87b9 100644 --- a/src/cli/self_update/shell.rs +++ b/src/cli/self_update/shell.rs @@ -73,6 +73,27 @@ fn enumerate_shells() -> Vec { ] } +/// Builds the shell source lines for the post-install message, showing only +/// shells that are available on the current system. Shells sharing the same +/// env file are grouped onto one line (e.g. sh/bash/zsh all use `env`). +pub(crate) fn build_source_env_lines(process: &Process) -> String { + let mut groups = Vec::<(String, Vec<&'static str>)>::new(); + for shell in get_available_shells(process) { + let Ok(src) = shell.source_string(process) else { + continue; + }; + if let Some(group) = groups.iter_mut().find(|(s, _)| *s == src) { + group.1.push(shell.name()); + } else { + groups.push((src, vec![shell.name()])); + } + } + groups + .into_iter() + .map(|(src, names)| format!(" {} # For {}\n", src, names.join("/"))) + .collect() +} + pub(crate) fn get_available_shells(process: &Process) -> impl Iterator + '_ { enumerate_shells() .into_iter() @@ -536,27 +557,6 @@ impl UnixShell for Xonsh { } } -/// Builds the shell source lines for the post-install message, showing only -/// shells that are available on the current system. Shells sharing the same -/// env file are grouped onto one line (e.g. sh/bash/zsh all use `env`). -pub(crate) fn build_source_env_lines(process: &Process) -> String { - let mut groups: Vec<(String, Vec<&'static str>)> = Vec::new(); - for shell in get_available_shells(process) { - let Ok(src) = shell.source_string(process) else { - continue; - }; - if let Some(group) = groups.iter_mut().find(|(s, _)| *s == src) { - group.1.push(shell.name()); - } else { - groups.push((src, vec![shell.name()])); - } - } - groups - .into_iter() - .map(|(src, names)| format!(" {} # For {}\n", src, names.join("/"))) - .collect() -} - pub(crate) fn legacy_paths(process: &Process) -> impl Iterator + '_ { let zprofiles = Zsh::zdotdir(process) .into_iter()