windows: Fix project prepare_ssh_shell to support setting PATH on Windows (#12370)
Release Notes: - N/A Update to use `std::env::join_paths` to prepare `PATH` env. Ref https://github.com/zed-industries/zed/pull/12087#issuecomment-2122852384 @mrnugget --------- Co-authored-by: Thorsten Ball <mrnugget@gmail.com>
This commit is contained in:
parent
d0142b820f
commit
ae55d35f19
1 changed files with 58 additions and 21 deletions
|
@ -1,4 +1,5 @@
|
||||||
use crate::Project;
|
use crate::Project;
|
||||||
|
use anyhow::Context as _;
|
||||||
use collections::HashMap;
|
use collections::HashMap;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
AnyWindowHandle, AppContext, Context, Entity, Model, ModelContext, SharedString, WeakModel,
|
AnyWindowHandle, AppContext, Context, Entity, Model, ModelContext, SharedString, WeakModel,
|
||||||
|
@ -268,19 +269,8 @@ impl Project {
|
||||||
path.to_string_lossy().to_string(),
|
path.to_string_lossy().to_string(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let path_bin = path.join("bin");
|
|
||||||
// We need to set the PATH to include the virtual environment's bin directory
|
// We need to set the PATH to include the virtual environment's bin directory
|
||||||
if let Some(paths) = std::env::var_os("PATH") {
|
add_environment_path(env, &path.join("bin")).log_err();
|
||||||
let paths = std::iter::once(path_bin).chain(std::env::split_paths(&paths));
|
|
||||||
if let Some(new_path) = std::env::join_paths(paths).log_err() {
|
|
||||||
env.insert("PATH".to_string(), new_path.to_string_lossy().to_string());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
env.insert(
|
|
||||||
"PATH".to_string(),
|
|
||||||
path.join("bin").to_string_lossy().to_string(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -381,17 +371,64 @@ fn prepare_ssh_shell(
|
||||||
// todo(windows)
|
// todo(windows)
|
||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(not(target_os = "windows"))]
|
||||||
std::fs::set_permissions(ssh_path, smol::fs::unix::PermissionsExt::from_mode(0o755))?;
|
std::fs::set_permissions(ssh_path, smol::fs::unix::PermissionsExt::from_mode(0o755))?;
|
||||||
let path = format!(
|
|
||||||
"{}:{}",
|
add_environment_path(env, tmp_dir)?;
|
||||||
tmp_dir.to_string_lossy(),
|
|
||||||
env.get("PATH")
|
|
||||||
.cloned()
|
|
||||||
.or(env::var("PATH").ok())
|
|
||||||
.unwrap_or_default()
|
|
||||||
);
|
|
||||||
env.insert("PATH".to_string(), path);
|
|
||||||
|
|
||||||
let mut args = shlex::split(&ssh_command).unwrap_or_default();
|
let mut args = shlex::split(&ssh_command).unwrap_or_default();
|
||||||
let program = args.drain(0..1).next().unwrap_or("ssh".to_string());
|
let program = args.drain(0..1).next().unwrap_or("ssh".to_string());
|
||||||
Ok(Shell::WithArguments { program, args })
|
Ok(Shell::WithArguments { program, args })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn add_environment_path(env: &mut HashMap<String, String>, new_path: &Path) -> anyhow::Result<()> {
|
||||||
|
let mut env_paths = vec![new_path.to_path_buf()];
|
||||||
|
if let Some(path) = env.get("PATH").or(env::var("PATH").ok().as_ref()) {
|
||||||
|
let mut paths = std::env::split_paths(&path).collect::<Vec<_>>();
|
||||||
|
env_paths.append(&mut paths);
|
||||||
|
}
|
||||||
|
|
||||||
|
let paths = std::env::join_paths(env_paths).context("failed to create PATH env variable")?;
|
||||||
|
env.insert("PATH".to_string(), paths.to_string_lossy().to_string());
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use collections::HashMap;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_add_environment_path_with_existing_path() {
|
||||||
|
let tmp_path = std::path::PathBuf::from("/tmp/new");
|
||||||
|
let mut env = HashMap::default();
|
||||||
|
let old_path = if cfg!(windows) {
|
||||||
|
"/usr/bin;/usr/local/bin"
|
||||||
|
} else {
|
||||||
|
"/usr/bin:/usr/local/bin"
|
||||||
|
};
|
||||||
|
env.insert("PATH".to_string(), old_path.to_string());
|
||||||
|
env.insert("OTHER".to_string(), "aaa".to_string());
|
||||||
|
|
||||||
|
super::add_environment_path(&mut env, &tmp_path).unwrap();
|
||||||
|
if cfg!(windows) {
|
||||||
|
assert_eq!(env.get("PATH").unwrap(), &format!("/tmp/new;{}", old_path));
|
||||||
|
} else {
|
||||||
|
assert_eq!(env.get("PATH").unwrap(), &format!("/tmp/new:{}", old_path));
|
||||||
|
}
|
||||||
|
assert_eq!(env.get("OTHER").unwrap(), "aaa");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_add_environment_path_with_empty_path() {
|
||||||
|
let tmp_path = std::path::PathBuf::from("/tmp/new");
|
||||||
|
let mut env = HashMap::default();
|
||||||
|
env.insert("OTHER".to_string(), "aaa".to_string());
|
||||||
|
let os_path = std::env::var("PATH").unwrap();
|
||||||
|
super::add_environment_path(&mut env, &tmp_path).unwrap();
|
||||||
|
if cfg!(windows) {
|
||||||
|
assert_eq!(env.get("PATH").unwrap(), &format!("/tmp/new;{}", os_path));
|
||||||
|
} else {
|
||||||
|
assert_eq!(env.get("PATH").unwrap(), &format!("/tmp/new:{}", os_path));
|
||||||
|
}
|
||||||
|
assert_eq!(env.get("OTHER").unwrap(), "aaa");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue