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:
parent
a11647d07f
commit
0068de0386
6 changed files with 80 additions and 20 deletions
10
Cargo.lock
generated
10
Cargo.lock
generated
|
@ -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",
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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(
|
||||||
.config
|
task_definition
|
||||||
.get("cwd")
|
.config
|
||||||
.and_then(|s| s.as_str())
|
.get("cwd")
|
||||||
.map(PathBuf::from)
|
.and_then(|s| s.as_str())
|
||||||
.unwrap_or_else(|| delegate.worktree_root_path().to_path_buf());
|
.map(PathBuf::from)
|
||||||
|
.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(())
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue