debugger: Handle the envFile setting for Go (#33666)

Fixes #32984

Release Notes:

- The Go debugger now respects the `envFile` setting.
This commit is contained in:
Julia Ryan 2025-07-01 09:14:59 -07:00 committed by GitHub
parent a11647d07f
commit 0068de0386
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 80 additions and 20 deletions

View file

@ -25,7 +25,9 @@ anyhow.workspace = true
async-trait.workspace = true
collections.workspace = true
dap.workspace = true
dotenvy.workspace = true
futures.workspace = true
fs.workspace = true
gpui.workspace = true
json_dotpath.workspace = true
language.workspace = true

View file

@ -7,13 +7,22 @@ use dap::{
latest_github_release,
},
};
use fs::Fs;
use gpui::{AsyncApp, SharedString};
use language::LanguageName;
use std::{env::consts, ffi::OsStr, path::PathBuf, sync::OnceLock};
use log::warn;
use serde_json::{Map, Value};
use task::TcpArgumentsTemplate;
use util;
use std::{
env::consts,
ffi::OsStr,
path::{Path, PathBuf},
str::FromStr,
sync::OnceLock,
};
use crate::*;
#[derive(Default, Debug)]
@ -437,22 +446,34 @@ impl DebugAdapter for GoDebugAdapter {
adapter_path.join("dlv").to_string_lossy().to_string()
};
let cwd = task_definition
.config
.get("cwd")
.and_then(|s| s.as_str())
.map(PathBuf::from)
.unwrap_or_else(|| delegate.worktree_root_path().to_path_buf());
let cwd = Some(
task_definition
.config
.get("cwd")
.and_then(|s| s.as_str())
.map(PathBuf::from)
.unwrap_or_else(|| delegate.worktree_root_path().to_path_buf()),
);
let arguments;
let command;
let connection;
let mut configuration = task_definition.config.clone();
let mut envs = HashMap::default();
if let Some(configuration) = configuration.as_object_mut() {
configuration
.entry("cwd")
.or_insert_with(|| delegate.worktree_root_path().to_string_lossy().into());
handle_envs(
configuration,
&mut envs,
cwd.as_deref(),
delegate.fs().clone(),
)
.await;
}
if let Some(connection_options) = &task_definition.tcp_connection {
@ -494,8 +515,8 @@ impl DebugAdapter for GoDebugAdapter {
Ok(DebugAdapterBinary {
command,
arguments,
cwd: Some(cwd),
envs: HashMap::default(),
cwd,
envs,
connection,
request_args: StartDebuggingRequestArguments {
configuration,
@ -504,3 +525,44 @@ impl DebugAdapter for GoDebugAdapter {
})
}
}
// delve doesn't do anything with the envFile setting, so we intercept it
async fn handle_envs(
config: &mut Map<String, Value>,
envs: &mut HashMap<String, String>,
cwd: Option<&Path>,
fs: Arc<dyn Fs>,
) -> Option<()> {
let env_files = match config.get("envFile")? {
Value::Array(arr) => arr.iter().map(|v| v.as_str()).collect::<Vec<_>>(),
Value::String(s) => vec![Some(s.as_str())],
_ => return None,
};
let rebase_path = |path: PathBuf| {
if path.is_absolute() {
Some(path)
} else {
cwd.map(|p| p.join(path))
}
};
for path in env_files {
let Some(path) = path
.and_then(|s| PathBuf::from_str(s).ok())
.and_then(rebase_path)
else {
continue;
};
if let Ok(file) = fs.open_sync(&path).await {
envs.extend(dotenvy::from_read_iter(file).filter_map(Result::ok))
} else {
warn!("While starting Go debug session: failed to read env file {path:?}");
};
}
// remove envFile now that it's been handled
config.remove("entry");
Some(())
}