acp_thread: Respect terminal settings shell for terminal tool environment (#39349)
When sourcing the project environment for the terminal tool, we will now do so by spawning the shell specified by the users `terminal.shell` setting (or as usual fall back to the login shell). Closes #37687 Release Notes: - N/A
This commit is contained in:
+3
-126
@@ -8,6 +8,7 @@ pub mod redact;
|
||||
pub mod rel_path;
|
||||
pub mod schemars;
|
||||
pub mod serde;
|
||||
pub mod shell;
|
||||
pub mod shell_env;
|
||||
pub mod size;
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
@@ -367,7 +368,7 @@ pub async fn load_login_shell_environment() -> Result<()> {
|
||||
// into shell's `cd` command (and hooks) to manipulate env.
|
||||
// We do this so that we get the env a user would have when spawning a shell
|
||||
// in home directory.
|
||||
for (name, value) in shell_env::capture(paths::home_dir()).await? {
|
||||
for (name, value) in shell_env::capture(get_system_shell(), &[], paths::home_dir()).await? {
|
||||
unsafe { env::set_var(&name, &value) };
|
||||
}
|
||||
|
||||
@@ -555,108 +556,6 @@ pub fn wrapped_usize_outward_from(
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
pub fn get_windows_system_shell() -> String {
|
||||
use std::path::PathBuf;
|
||||
|
||||
fn find_pwsh_in_programfiles(find_alternate: bool, find_preview: bool) -> Option<PathBuf> {
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
let env_var = if find_alternate {
|
||||
"ProgramFiles(x86)"
|
||||
} else {
|
||||
"ProgramFiles"
|
||||
};
|
||||
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
let env_var = if find_alternate {
|
||||
"ProgramW6432"
|
||||
} else {
|
||||
"ProgramFiles"
|
||||
};
|
||||
|
||||
let install_base_dir = PathBuf::from(std::env::var_os(env_var)?).join("PowerShell");
|
||||
install_base_dir
|
||||
.read_dir()
|
||||
.ok()?
|
||||
.filter_map(Result::ok)
|
||||
.filter(|entry| matches!(entry.file_type(), Ok(ft) if ft.is_dir()))
|
||||
.filter_map(|entry| {
|
||||
let dir_name = entry.file_name();
|
||||
let dir_name = dir_name.to_string_lossy();
|
||||
|
||||
let version = if find_preview {
|
||||
let dash_index = dir_name.find('-')?;
|
||||
if &dir_name[dash_index + 1..] != "preview" {
|
||||
return None;
|
||||
};
|
||||
dir_name[..dash_index].parse::<u32>().ok()?
|
||||
} else {
|
||||
dir_name.parse::<u32>().ok()?
|
||||
};
|
||||
|
||||
let exe_path = entry.path().join("pwsh.exe");
|
||||
if exe_path.exists() {
|
||||
Some((version, exe_path))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.max_by_key(|(version, _)| *version)
|
||||
.map(|(_, path)| path)
|
||||
}
|
||||
|
||||
fn find_pwsh_in_msix(find_preview: bool) -> Option<PathBuf> {
|
||||
let msix_app_dir =
|
||||
PathBuf::from(std::env::var_os("LOCALAPPDATA")?).join("Microsoft\\WindowsApps");
|
||||
if !msix_app_dir.exists() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let prefix = if find_preview {
|
||||
"Microsoft.PowerShellPreview_"
|
||||
} else {
|
||||
"Microsoft.PowerShell_"
|
||||
};
|
||||
msix_app_dir
|
||||
.read_dir()
|
||||
.ok()?
|
||||
.filter_map(|entry| {
|
||||
let entry = entry.ok()?;
|
||||
if !matches!(entry.file_type(), Ok(ft) if ft.is_dir()) {
|
||||
return None;
|
||||
}
|
||||
|
||||
if !entry.file_name().to_string_lossy().starts_with(prefix) {
|
||||
return None;
|
||||
}
|
||||
|
||||
let exe_path = entry.path().join("pwsh.exe");
|
||||
exe_path.exists().then_some(exe_path)
|
||||
})
|
||||
.next()
|
||||
}
|
||||
|
||||
fn find_pwsh_in_scoop() -> Option<PathBuf> {
|
||||
let pwsh_exe =
|
||||
PathBuf::from(std::env::var_os("USERPROFILE")?).join("scoop\\shims\\pwsh.exe");
|
||||
pwsh_exe.exists().then_some(pwsh_exe)
|
||||
}
|
||||
|
||||
static SYSTEM_SHELL: LazyLock<String> = LazyLock::new(|| {
|
||||
find_pwsh_in_programfiles(false, false)
|
||||
.or_else(|| find_pwsh_in_programfiles(true, false))
|
||||
.or_else(|| find_pwsh_in_msix(false))
|
||||
.or_else(|| find_pwsh_in_programfiles(false, true))
|
||||
.or_else(|| find_pwsh_in_msix(true))
|
||||
.or_else(|| find_pwsh_in_programfiles(true, true))
|
||||
.or_else(find_pwsh_in_scoop)
|
||||
.map(|p| p.to_string_lossy().into_owned())
|
||||
.unwrap_or("powershell.exe".to_string())
|
||||
});
|
||||
|
||||
(*SYSTEM_SHELL).clone()
|
||||
}
|
||||
|
||||
pub trait ResultExt<E> {
|
||||
type Ok;
|
||||
|
||||
@@ -1100,29 +999,7 @@ pub fn default<D: Default>() -> D {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
pub fn get_system_shell() -> String {
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
get_windows_system_shell()
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
{
|
||||
std::env::var("SHELL").unwrap_or("/bin/sh".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_default_system_shell() -> String {
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
get_windows_system_shell()
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
{
|
||||
"/bin/sh".to_string()
|
||||
}
|
||||
}
|
||||
pub use self::shell::{get_default_system_shell, get_system_shell};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ConnectionResult<O> {
|
||||
|
||||
Reference in New Issue
Block a user