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

View file

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

View file

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

View file

@ -7,13 +7,22 @@ use dap::{
latest_github_release, latest_github_release,
}, },
}; };
use fs::Fs;
use gpui::{AsyncApp, SharedString}; use gpui::{AsyncApp, SharedString};
use language::LanguageName; 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 task::TcpArgumentsTemplate;
use util; use util;
use std::{
env::consts,
ffi::OsStr,
path::{Path, PathBuf},
str::FromStr,
sync::OnceLock,
};
use crate::*; use crate::*;
#[derive(Default, Debug)] #[derive(Default, Debug)]
@ -437,22 +446,34 @@ impl DebugAdapter for GoDebugAdapter {
adapter_path.join("dlv").to_string_lossy().to_string() adapter_path.join("dlv").to_string_lossy().to_string()
}; };
let cwd = task_definition let cwd = Some(
task_definition
.config .config
.get("cwd") .get("cwd")
.and_then(|s| s.as_str()) .and_then(|s| s.as_str())
.map(PathBuf::from) .map(PathBuf::from)
.unwrap_or_else(|| delegate.worktree_root_path().to_path_buf()); .unwrap_or_else(|| delegate.worktree_root_path().to_path_buf()),
);
let arguments; let arguments;
let command; let command;
let connection; let connection;
let mut configuration = task_definition.config.clone(); let mut configuration = task_definition.config.clone();
let mut envs = HashMap::default();
if let Some(configuration) = configuration.as_object_mut() { if let Some(configuration) = configuration.as_object_mut() {
configuration configuration
.entry("cwd") .entry("cwd")
.or_insert_with(|| delegate.worktree_root_path().to_string_lossy().into()); .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 { if let Some(connection_options) = &task_definition.tcp_connection {
@ -494,8 +515,8 @@ impl DebugAdapter for GoDebugAdapter {
Ok(DebugAdapterBinary { Ok(DebugAdapterBinary {
command, command,
arguments, arguments,
cwd: Some(cwd), cwd,
envs: HashMap::default(), envs,
connection, connection,
request_args: StartDebuggingRequestArguments { request_args: StartDebuggingRequestArguments {
configuration, 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 collections.workspace = true
debug_adapter_extension.workspace = true debug_adapter_extension.workspace = true
dirs.workspace = true dirs.workspace = true
dotenv.workspace = true dotenvy.workspace = true
env_logger.workspace = true env_logger.workspace = true
extension.workspace = true extension.workspace = true
fs.workspace = true fs.workspace = true

View file

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