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

10
Cargo.lock generated
View file

@ -4147,6 +4147,8 @@ dependencies = [
"async-trait",
"collections",
"dap",
"dotenvy",
"fs",
"futures 0.3.31",
"gpui",
"json_dotpath",
@ -4675,12 +4677,6 @@ dependencies = [
"syn 2.0.101",
]
[[package]]
name = "dotenv"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f"
[[package]]
name = "dotenvy"
version = "0.15.7"
@ -5114,7 +5110,7 @@ dependencies = [
"collections",
"debug_adapter_extension",
"dirs 4.0.0",
"dotenv",
"dotenvy",
"env_logger 0.11.8",
"extension",
"fs",

View file

@ -449,7 +449,7 @@ dashmap = "6.0"
derive_more = "0.99.17"
dirs = "4.0"
documented = "0.9.1"
dotenv = "0.15.0"
dotenvy = "0.15.0"
ec4rs = "1.1"
emojis = "0.6.1"
env_logger = "0.11"

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(())
}

View file

@ -32,7 +32,7 @@ client.workspace = true
collections.workspace = true
debug_adapter_extension.workspace = true
dirs.workspace = true
dotenv.workspace = true
dotenvy.workspace = true
env_logger.workspace = true
extension.workspace = true
fs.workspace = true

View file

@ -63,7 +63,7 @@ struct Args {
}
fn main() {
dotenv::from_filename(CARGO_MANIFEST_DIR.join(".env")).ok();
dotenvy::from_filename(CARGO_MANIFEST_DIR.join(".env")).ok();
env_logger::init();