Skip to content

Commit fd7d9de

Browse files
authored
fix(gemset): Preserve env vars (#150)
Pass `Worktree` shell environment variables to Ruby language servers by preserving `GEM_PATH` while allowing other variables to pass through. This should resolve some issues with remote development when the Ruby extension loses env variables.
1 parent 1351f2e commit fd7d9de

File tree

2 files changed

+48
-7
lines changed

2 files changed

+48
-7
lines changed

src/gemset.rs

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,19 @@ impl Gemset {
2525
.ok_or_else(|| format!("Failed to convert path for '{bin_name}'"))
2626
}
2727

28-
pub fn gem_path_env(&self) -> Vec<(String, String)> {
29-
vec![(
28+
pub fn env(&self, envs: Option<&[(&str, &str)]>) -> Vec<(String, String)> {
29+
let mut env_map: std::collections::HashMap<String, String> = envs
30+
.unwrap_or(&[])
31+
.iter()
32+
.map(|(k, v)| (k.to_string(), v.to_string()))
33+
.collect();
34+
35+
env_map.insert(
3036
"GEM_PATH".to_string(),
3137
format!("{}:$GEM_PATH", self.gem_home.display()),
32-
)]
38+
);
39+
40+
env_map.into_iter().collect()
3341
}
3442

3543
pub fn install_gem(&self, name: &str) -> Result<(), String> {
@@ -217,17 +225,45 @@ mod tests {
217225
}
218226

219227
#[test]
220-
fn test_gem_path_env() {
228+
fn test_gem_env() {
221229
let gemset = Gemset::new(
222230
TEST_GEM_HOME.into(),
223231
Box::new(MockGemCommandExecutor::new()),
224232
);
225-
let env = gemset.gem_path_env();
233+
let env = gemset.env(None);
226234
assert_eq!(env.len(), 1);
227235
assert_eq!(env[0].0, "GEM_PATH");
228236
assert_eq!(env[0].1, "/test/gem_home:$GEM_PATH");
229237
}
230238

239+
#[test]
240+
fn test_gem_env_with_env_vars() {
241+
let gemset = Gemset::new(
242+
TEST_GEM_HOME.into(),
243+
Box::new(MockGemCommandExecutor::new()),
244+
);
245+
let env = gemset.env(Some(&[("GEM_HOME", "/home/user/.gem")]));
246+
assert_eq!(env.len(), 2);
247+
248+
let env_map: std::collections::HashMap<String, String> = env.into_iter().collect();
249+
assert_eq!(env_map.get("GEM_HOME").unwrap(), "/home/user/.gem");
250+
assert_eq!(env_map.get("GEM_PATH").unwrap(), "/test/gem_home:$GEM_PATH");
251+
}
252+
253+
#[test]
254+
fn test_gem_env_with_env_vars_overwrite() {
255+
let gemset = Gemset::new(
256+
TEST_GEM_HOME.into(),
257+
Box::new(MockGemCommandExecutor::new()),
258+
);
259+
let env = gemset.env(Some(&[("GEM_PATH", "/home/user/.gem")]));
260+
assert_eq!(env.len(), 1);
261+
262+
// GEM_PATH should be overwritten with our value
263+
let env_map: std::collections::HashMap<String, String> = env.into_iter().collect();
264+
assert_eq!(env_map.get("GEM_PATH").unwrap(), "/test/gem_home:$GEM_PATH");
265+
}
266+
231267
#[test]
232268
fn test_install_gem_success() {
233269
let mock_executor = MockGemCommandExecutor::new();

src/language_servers/language_server.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,11 @@ pub trait LanguageServer {
223223
.to_string();
224224

225225
let gemset = Gemset::new(PathBuf::from(&gem_home), Box::new(RealCommandExecutor));
226+
let worktree_shell_env = worktree.shell_env();
227+
let worktree_shell_env_vars: Vec<(&str, &str)> = worktree_shell_env
228+
.iter()
229+
.map(|(key, value)| (key.as_str(), value.as_str()))
230+
.collect();
226231

227232
zed::set_language_server_installation_status(
228233
language_server_id,
@@ -256,7 +261,7 @@ pub trait LanguageServer {
256261
Ok(LanguageServerBinary {
257262
path: executable_path,
258263
args: Some(self.get_executable_args(worktree)),
259-
env: Some(gemset.gem_path_env()),
264+
env: Some(gemset.env(Some(&worktree_shell_env_vars))),
260265
})
261266
}
262267
Ok(None) => {
@@ -276,7 +281,7 @@ pub trait LanguageServer {
276281
Ok(LanguageServerBinary {
277282
path: executable_path,
278283
args: Some(self.get_executable_args(worktree)),
279-
env: Some(gemset.gem_path_env()),
284+
env: Some(gemset.env(Some(&worktree_shell_env_vars))),
280285
})
281286
}
282287
Err(e) => Err(e),

0 commit comments

Comments
 (0)