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())
|
||||
.kill_on_drop(true);
|
||||
|
||||
let mut process = command
|
||||
.spawn()
|
||||
.with_context(|| "failed to spawn command.")?;
|
||||
let mut process = command.spawn().with_context(|| {
|
||||
format!(
|
||||
"failed to spawn command `{} {}`.",
|
||||
binary.command,
|
||||
binary.arguments.join(" ")
|
||||
)
|
||||
})?;
|
||||
|
||||
let stdin = process.stdin.take().context("Failed to open stdin")?;
|
||||
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(JsDebugAdapter::default()));
|
||||
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));
|
||||
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
|
|
|
@ -1,22 +1,87 @@
|
|||
use anyhow::{Context as _, anyhow, bail};
|
||||
use dap::{
|
||||
StartDebuggingRequestArguments, StartDebuggingRequestArgumentsRequest,
|
||||
adapters::DebugTaskDefinition,
|
||||
adapters::{
|
||||
DebugTaskDefinition, DownloadedFileType, download_adapter_from_github,
|
||||
latest_github_release,
|
||||
},
|
||||
};
|
||||
|
||||
use gpui::{AsyncApp, SharedString};
|
||||
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 crate::*;
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
pub(crate) struct GoDebugAdapter;
|
||||
pub(crate) struct GoDebugAdapter {
|
||||
shim_path: OnceLock<PathBuf>,
|
||||
}
|
||||
|
||||
impl GoDebugAdapter {
|
||||
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)]
|
||||
|
@ -384,16 +449,10 @@ 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 mut tcp_connection = task_definition.tcp_connection.clone().unwrap_or_default();
|
||||
|
||||
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 (host, port, _) = crate::configure_tcp_connection(tcp_connection).await?;
|
||||
|
||||
let cwd = task_definition
|
||||
.config
|
||||
|
@ -404,6 +463,7 @@ impl DebugAdapter for GoDebugAdapter {
|
|||
|
||||
let arguments = if cfg!(windows) {
|
||||
vec![
|
||||
delve_path,
|
||||
"dap".into(),
|
||||
"--listen".into(),
|
||||
format!("{}:{}", host, port),
|
||||
|
@ -411,6 +471,7 @@ impl DebugAdapter for GoDebugAdapter {
|
|||
]
|
||||
} else {
|
||||
vec![
|
||||
delve_path,
|
||||
"dap".into(),
|
||||
"--listen".into(),
|
||||
format!("{}:{}", host, port),
|
||||
|
@ -418,15 +479,11 @@ impl DebugAdapter for GoDebugAdapter {
|
|||
};
|
||||
|
||||
Ok(DebugAdapterBinary {
|
||||
command: delve_path,
|
||||
command: minidelve_path.to_string_lossy().into_owned(),
|
||||
arguments,
|
||||
cwd: Some(cwd),
|
||||
envs: HashMap::default(),
|
||||
connection: Some(adapters::TcpArguments {
|
||||
host,
|
||||
port,
|
||||
timeout,
|
||||
}),
|
||||
connection: None,
|
||||
request_args: StartDebuggingRequestArguments {
|
||||
configuration: task_definition.config.clone(),
|
||||
request: self.validate_config(&task_definition.config)?,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue