go: Use delve-dap-shim for spawning delve (#31700)
This allows us to support terminal with go sessions Closes #ISSUE Release Notes: - debugger: Add support for terminal when debugging Go programs
This commit is contained in:
parent
05692e298a
commit
070eac28e3
3 changed files with 84 additions and 23 deletions
|
@ -658,9 +658,13 @@ impl StdioTransport {
|
||||||
.stderr(Stdio::piped())
|
.stderr(Stdio::piped())
|
||||||
.kill_on_drop(true);
|
.kill_on_drop(true);
|
||||||
|
|
||||||
let mut process = command
|
let mut process = command.spawn().with_context(|| {
|
||||||
.spawn()
|
format!(
|
||||||
.with_context(|| "failed to spawn command.")?;
|
"failed to spawn command `{} {}`.",
|
||||||
|
binary.command,
|
||||||
|
binary.arguments.join(" ")
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
let stdin = process.stdin.take().context("Failed to open stdin")?;
|
let stdin = process.stdin.take().context("Failed to open stdin")?;
|
||||||
let stdout = process.stdout.take().context("Failed to open stdout")?;
|
let stdout = process.stdout.take().context("Failed to open stdout")?;
|
||||||
|
|
|
@ -37,7 +37,7 @@ pub fn init(cx: &mut App) {
|
||||||
registry.add_adapter(Arc::from(PhpDebugAdapter::default()));
|
registry.add_adapter(Arc::from(PhpDebugAdapter::default()));
|
||||||
registry.add_adapter(Arc::from(JsDebugAdapter::default()));
|
registry.add_adapter(Arc::from(JsDebugAdapter::default()));
|
||||||
registry.add_adapter(Arc::from(RubyDebugAdapter));
|
registry.add_adapter(Arc::from(RubyDebugAdapter));
|
||||||
registry.add_adapter(Arc::from(GoDebugAdapter));
|
registry.add_adapter(Arc::from(GoDebugAdapter::default()));
|
||||||
registry.add_adapter(Arc::from(GdbDebugAdapter));
|
registry.add_adapter(Arc::from(GdbDebugAdapter));
|
||||||
|
|
||||||
#[cfg(any(test, feature = "test-support"))]
|
#[cfg(any(test, feature = "test-support"))]
|
||||||
|
|
|
@ -1,22 +1,87 @@
|
||||||
use anyhow::{Context as _, anyhow, bail};
|
use anyhow::{Context as _, anyhow, bail};
|
||||||
use dap::{
|
use dap::{
|
||||||
StartDebuggingRequestArguments, StartDebuggingRequestArgumentsRequest,
|
StartDebuggingRequestArguments, StartDebuggingRequestArgumentsRequest,
|
||||||
adapters::DebugTaskDefinition,
|
adapters::{
|
||||||
|
DebugTaskDefinition, DownloadedFileType, download_adapter_from_github,
|
||||||
|
latest_github_release,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use gpui::{AsyncApp, SharedString};
|
use gpui::{AsyncApp, SharedString};
|
||||||
use language::LanguageName;
|
use language::LanguageName;
|
||||||
use std::{collections::HashMap, ffi::OsStr, path::PathBuf};
|
use std::{collections::HashMap, env::consts, ffi::OsStr, path::PathBuf, sync::OnceLock};
|
||||||
use util;
|
use util;
|
||||||
|
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
#[derive(Default, Debug)]
|
#[derive(Default, Debug)]
|
||||||
pub(crate) struct GoDebugAdapter;
|
pub(crate) struct GoDebugAdapter {
|
||||||
|
shim_path: OnceLock<PathBuf>,
|
||||||
|
}
|
||||||
|
|
||||||
impl GoDebugAdapter {
|
impl GoDebugAdapter {
|
||||||
const ADAPTER_NAME: &'static str = "Delve";
|
const ADAPTER_NAME: &'static str = "Delve";
|
||||||
const DEFAULT_TIMEOUT_MS: u64 = 60000;
|
async fn fetch_latest_adapter_version(
|
||||||
|
delegate: &Arc<dyn DapDelegate>,
|
||||||
|
) -> Result<AdapterVersion> {
|
||||||
|
let release = latest_github_release(
|
||||||
|
&"zed-industries/delve-shim-dap",
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
delegate.http_client(),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let os = match consts::OS {
|
||||||
|
"macos" => "apple-darwin",
|
||||||
|
"linux" => "unknown-linux-gnu",
|
||||||
|
"windows" => "pc-windows-msvc",
|
||||||
|
other => bail!("Running on unsupported os: {other}"),
|
||||||
|
};
|
||||||
|
let suffix = if consts::OS == "windows" {
|
||||||
|
".zip"
|
||||||
|
} else {
|
||||||
|
".tar.gz"
|
||||||
|
};
|
||||||
|
let asset_name = format!("delve-shim-dap-{}-{os}{suffix}", consts::ARCH);
|
||||||
|
let asset = release
|
||||||
|
.assets
|
||||||
|
.iter()
|
||||||
|
.find(|asset| asset.name == asset_name)
|
||||||
|
.with_context(|| format!("no asset found matching `{asset_name:?}`"))?;
|
||||||
|
|
||||||
|
Ok(AdapterVersion {
|
||||||
|
tag_name: release.tag_name,
|
||||||
|
url: asset.browser_download_url.clone(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
async fn install_shim(&self, delegate: &Arc<dyn DapDelegate>) -> anyhow::Result<PathBuf> {
|
||||||
|
if let Some(path) = self.shim_path.get().cloned() {
|
||||||
|
return Ok(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
let asset = Self::fetch_latest_adapter_version(delegate).await?;
|
||||||
|
let ty = if consts::OS == "windows" {
|
||||||
|
DownloadedFileType::Zip
|
||||||
|
} else {
|
||||||
|
DownloadedFileType::GzipTar
|
||||||
|
};
|
||||||
|
download_adapter_from_github(
|
||||||
|
"delve-shim-dap".into(),
|
||||||
|
asset.clone(),
|
||||||
|
ty,
|
||||||
|
delegate.as_ref(),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let path = paths::debug_adapters_dir()
|
||||||
|
.join("delve-shim-dap")
|
||||||
|
.join(format!("delve-shim-dap{}", asset.tag_name))
|
||||||
|
.join("delve-shim-dap");
|
||||||
|
self.shim_path.set(path.clone()).ok();
|
||||||
|
|
||||||
|
Ok(path)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait(?Send)]
|
#[async_trait(?Send)]
|
||||||
|
@ -384,16 +449,10 @@ impl DebugAdapter for GoDebugAdapter {
|
||||||
|
|
||||||
adapter_path.join("dlv").to_string_lossy().to_string()
|
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 mut tcp_connection = task_definition.tcp_connection.clone().unwrap_or_default();
|
let (host, port, _) = crate::configure_tcp_connection(tcp_connection).await?;
|
||||||
|
|
||||||
if tcp_connection.timeout.is_none()
|
|
||||||
|| tcp_connection.timeout.unwrap_or(0) < Self::DEFAULT_TIMEOUT_MS
|
|
||||||
{
|
|
||||||
tcp_connection.timeout = Some(Self::DEFAULT_TIMEOUT_MS);
|
|
||||||
}
|
|
||||||
|
|
||||||
let (host, port, timeout) = crate::configure_tcp_connection(tcp_connection).await?;
|
|
||||||
|
|
||||||
let cwd = task_definition
|
let cwd = task_definition
|
||||||
.config
|
.config
|
||||||
|
@ -404,6 +463,7 @@ impl DebugAdapter for GoDebugAdapter {
|
||||||
|
|
||||||
let arguments = if cfg!(windows) {
|
let arguments = if cfg!(windows) {
|
||||||
vec![
|
vec![
|
||||||
|
delve_path,
|
||||||
"dap".into(),
|
"dap".into(),
|
||||||
"--listen".into(),
|
"--listen".into(),
|
||||||
format!("{}:{}", host, port),
|
format!("{}:{}", host, port),
|
||||||
|
@ -411,6 +471,7 @@ impl DebugAdapter for GoDebugAdapter {
|
||||||
]
|
]
|
||||||
} else {
|
} else {
|
||||||
vec![
|
vec![
|
||||||
|
delve_path,
|
||||||
"dap".into(),
|
"dap".into(),
|
||||||
"--listen".into(),
|
"--listen".into(),
|
||||||
format!("{}:{}", host, port),
|
format!("{}:{}", host, port),
|
||||||
|
@ -418,15 +479,11 @@ impl DebugAdapter for GoDebugAdapter {
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(DebugAdapterBinary {
|
Ok(DebugAdapterBinary {
|
||||||
command: delve_path,
|
command: minidelve_path.to_string_lossy().into_owned(),
|
||||||
arguments,
|
arguments,
|
||||||
cwd: Some(cwd),
|
cwd: Some(cwd),
|
||||||
envs: HashMap::default(),
|
envs: HashMap::default(),
|
||||||
connection: Some(adapters::TcpArguments {
|
connection: None,
|
||||||
host,
|
|
||||||
port,
|
|
||||||
timeout,
|
|
||||||
}),
|
|
||||||
request_args: StartDebuggingRequestArguments {
|
request_args: StartDebuggingRequestArguments {
|
||||||
configuration: task_definition.config.clone(),
|
configuration: task_definition.config.clone(),
|
||||||
request: self.validate_config(&task_definition.config)?,
|
request: self.validate_config(&task_definition.config)?,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue