From 0068de03867488207b8022134895b205dfdafd87 Mon Sep 17 00:00:00 2001 From: Julia Ryan Date: Tue, 1 Jul 2025 09:14:59 -0700 Subject: [PATCH] debugger: Handle the `envFile` setting for Go (#33666) Fixes #32984 Release Notes: - The Go debugger now respects the `envFile` setting. --- Cargo.lock | 10 ++--- Cargo.toml | 2 +- crates/dap_adapters/Cargo.toml | 2 + crates/dap_adapters/src/go.rs | 82 +++++++++++++++++++++++++++++----- crates/eval/Cargo.toml | 2 +- crates/eval/src/eval.rs | 2 +- 6 files changed, 80 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c523c12b13..36d08ec201 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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", diff --git a/Cargo.toml b/Cargo.toml index bc686419e5..e7926f025f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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" diff --git a/crates/dap_adapters/Cargo.toml b/crates/dap_adapters/Cargo.toml index 07356c2084..65544fbb6a 100644 --- a/crates/dap_adapters/Cargo.toml +++ b/crates/dap_adapters/Cargo.toml @@ -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 diff --git a/crates/dap_adapters/src/go.rs b/crates/dap_adapters/src/go.rs index bc3f500745..d32f5cbf34 100644 --- a/crates/dap_adapters/src/go.rs +++ b/crates/dap_adapters/src/go.rs @@ -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, + envs: &mut HashMap, + cwd: Option<&Path>, + fs: Arc, +) -> Option<()> { + let env_files = match config.get("envFile")? { + Value::Array(arr) => arr.iter().map(|v| v.as_str()).collect::>(), + 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(()) +} diff --git a/crates/eval/Cargo.toml b/crates/eval/Cargo.toml index 7ecba7c1ec..d5db7f71a4 100644 --- a/crates/eval/Cargo.toml +++ b/crates/eval/Cargo.toml @@ -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 diff --git a/crates/eval/src/eval.rs b/crates/eval/src/eval.rs index 5e8dd8961c..39121377bb 100644 --- a/crates/eval/src/eval.rs +++ b/crates/eval/src/eval.rs @@ -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();