debugger: Allow use of externally-managed Delve for Go debugging (#32613)

Closes #ISSUE

Release Notes:

- Go debug scenarios can now use an externally-managed Delve instance.
Use `tcp_connection` in your debug scenario definition to provide
adapter's address.
This commit is contained in:
Piotr Osiewicz 2025-06-12 17:27:44 +02:00 committed by GitHub
parent bb5a763ef7
commit 5923ba4992
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 63 additions and 25 deletions

View file

@ -2,7 +2,7 @@ use anyhow::{Context as _, bail};
use dap::{
StartDebuggingRequestArguments,
adapters::{
DebugTaskDefinition, DownloadedFileType, download_adapter_from_github,
DebugTaskDefinition, DownloadedFileType, TcpArguments, download_adapter_from_github,
latest_github_release,
},
};
@ -10,6 +10,7 @@ use dap::{
use gpui::{AsyncApp, SharedString};
use language::LanguageName;
use std::{collections::HashMap, env::consts, ffi::OsStr, path::PathBuf, sync::OnceLock};
use task::TcpArgumentsTemplate;
use util;
use crate::*;
@ -433,10 +434,6 @@ impl DebugAdapter for GoDebugAdapter {
adapter_path.join("dlv").to_string_lossy().to_string()
};
let minidelve_path = self.install_shim(delegate).await?;
let tcp_connection = task_definition.tcp_connection.clone().unwrap_or_default();
let (host, port, _) = crate::configure_tcp_connection(tcp_connection).await?;
let cwd = task_definition
.config
@ -445,22 +442,9 @@ impl DebugAdapter for GoDebugAdapter {
.map(PathBuf::from)
.unwrap_or_else(|| delegate.worktree_root_path().to_path_buf());
let arguments = if cfg!(windows) {
vec![
delve_path,
"dap".into(),
"--listen".into(),
format!("{}:{}", host, port),
"--headless".into(),
]
} else {
vec![
delve_path,
"dap".into(),
"--listen".into(),
format!("{}:{}", host, port),
]
};
let arguments;
let command;
let connection;
let mut configuration = task_definition.config.clone();
if let Some(configuration) = configuration.as_object_mut() {
@ -469,12 +453,45 @@ impl DebugAdapter for GoDebugAdapter {
.or_insert_with(|| delegate.worktree_root_path().to_string_lossy().into());
}
if let Some(connection_options) = &task_definition.tcp_connection {
command = None;
arguments = vec![];
let (host, port, timeout) =
crate::configure_tcp_connection(connection_options.clone()).await?;
connection = Some(TcpArguments {
host,
port,
timeout,
});
} else {
let minidelve_path = self.install_shim(delegate).await?;
let (host, port, _) =
crate::configure_tcp_connection(TcpArgumentsTemplate::default()).await?;
command = Some(minidelve_path.to_string_lossy().into_owned());
connection = None;
arguments = if cfg!(windows) {
vec![
delve_path,
"dap".into(),
"--listen".into(),
format!("{}:{}", host, port),
"--headless".into(),
]
} else {
vec![
delve_path,
"dap".into(),
"--listen".into(),
format!("{}:{}", host, port),
]
};
}
Ok(DebugAdapterBinary {
command: Some(minidelve_path.to_string_lossy().into_owned()),
command,
arguments,
cwd: Some(cwd),
envs: HashMap::default(),
connection: None,
connection,
request_args: StartDebuggingRequestArguments {
configuration,
request: self.request_kind(&task_definition.config)?,