diff --git a/crates/debugger_ui/src/attach_modal.rs b/crates/debugger_ui/src/attach_modal.rs index 1afe8ba275..e054985f92 100644 --- a/crates/debugger_ui/src/attach_modal.rs +++ b/crates/debugger_ui/src/attach_modal.rs @@ -237,7 +237,7 @@ impl PickerDelegate for AttachModalDelegate { .flatten(); if let Some(panel) = panel { panel.update(cx, |panel, cx| { - panel.start_session(scenario, Default::default(), None, window, cx); + panel.start_session(scenario, Default::default(), None, None, window, cx); }); } diff --git a/crates/debugger_ui/src/debugger_panel.rs b/crates/debugger_ui/src/debugger_panel.rs index 846c374b27..4c6367bd25 100644 --- a/crates/debugger_ui/src/debugger_panel.rs +++ b/crates/debugger_ui/src/debugger_panel.rs @@ -22,8 +22,8 @@ use gpui::{ }; use language::Buffer; -use project::Fs; use project::debugger::session::{Session, SessionStateEvent}; +use project::{Fs, WorktreeId}; use project::{Project, debugger::session::ThreadStatus}; use rpc::proto::{self}; use settings::Settings; @@ -208,6 +208,7 @@ impl DebugPanel { scenario: DebugScenario, task_context: TaskContext, active_buffer: Option>, + worktree_id: Option, window: &mut Window, cx: &mut Context, ) { @@ -233,6 +234,7 @@ impl DebugPanel { scenario, task_context, active_buffer, + worktree_id, window, cx, ) @@ -1283,7 +1285,7 @@ impl workspace::DebuggerProvider for DebuggerProvider { ) { self.0.update(cx, |_, cx| { cx.defer_in(window, |this, window, cx| { - this.start_session(definition, context, buffer, window, cx); + this.start_session(definition, context, buffer, None, window, cx); }) }) } diff --git a/crates/debugger_ui/src/new_session_modal.rs b/crates/debugger_ui/src/new_session_modal.rs index 06398336bc..73aa4b095e 100644 --- a/crates/debugger_ui/src/new_session_modal.rs +++ b/crates/debugger_ui/src/new_session_modal.rs @@ -150,6 +150,7 @@ impl NewSessionModal { let task_contexts = workspace .update_in(cx, |this, window, cx| task_contexts(this, window, cx))? .await; + let worktree_id = task_contexts.worktree(); let task_context = task_contexts .active_item_context .map(|(_, _, context)| context) @@ -159,8 +160,9 @@ impl NewSessionModal { .map(|(_, context)| context) }) .unwrap_or_default(); + debug_panel.update_in(cx, |debug_panel, window, cx| { - debug_panel.start_session(config, task_context, None, window, cx) + debug_panel.start_session(config, task_context, None, worktree_id, window, cx) })?; this.update(cx, |_, cx| { cx.emit(DismissEvent); @@ -937,19 +939,27 @@ impl PickerDelegate for DebugScenarioDelegate { .await .task_context_for_worktree_id(worktree_id) .cloned() + .map(|context| (context, Some(worktree_id))) }) } else { gpui::Task::ready(None) }; cx.spawn_in(window, async move |this, cx| { - let task_context = task_context.await.unwrap_or_default(); + let (task_context, worktree_id) = task_context.await.unwrap_or_default(); this.update_in(cx, |this, window, cx| { this.delegate .debug_panel .update(cx, |panel, cx| { - panel.start_session(debug_scenario, task_context, None, window, cx); + panel.start_session( + debug_scenario, + task_context, + None, + worktree_id, + window, + cx, + ); }) .ok(); diff --git a/crates/debugger_ui/src/session/running.rs b/crates/debugger_ui/src/session/running.rs index caf227cf9c..34baa44caa 100644 --- a/crates/debugger_ui/src/session/running.rs +++ b/crates/debugger_ui/src/session/running.rs @@ -29,7 +29,7 @@ use language::Buffer; use loaded_source_list::LoadedSourceList; use module_list::ModuleList; use project::{ - Project, + Project, WorktreeId, debugger::session::{Session, SessionEvent, ThreadId, ThreadStatus}, terminals::TerminalKind, }; @@ -684,6 +684,7 @@ impl RunningState { scenario: DebugScenario, task_context: TaskContext, buffer: Option>, + worktree_id: Option, window: &Window, cx: &mut Context, ) -> Task> { @@ -712,7 +713,7 @@ impl RunningState { this.task_inventory().and_then(|inventory| { inventory .read(cx) - .task_template_by_label(buffer, &build, cx) + .task_template_by_label(buffer, worktree_id, &build, cx) }) })? else { diff --git a/crates/project/src/task_inventory.rs b/crates/project/src/task_inventory.rs index 6bb7fd0d1c..642ee2c086 100644 --- a/crates/project/src/task_inventory.rs +++ b/crates/project/src/task_inventory.rs @@ -229,10 +229,11 @@ impl Inventory { pub fn task_template_by_label( &self, buffer: Option>, + worktree_id: Option, label: &str, cx: &App, ) -> Option { - let (worktree_id, file, language) = buffer + let (buffer_worktree_id, file, language) = buffer .map(|buffer| { let buffer = buffer.read(cx); let file = buffer.file().cloned(); @@ -244,7 +245,7 @@ impl Inventory { }) .unwrap_or((None, None, None)); - self.list_tasks(file, language, worktree_id, cx) + self.list_tasks(file, language, worktree_id.or(buffer_worktree_id), cx) .iter() .find(|(_, template)| template.label == label) .map(|val| val.1.clone()) diff --git a/crates/task/src/debug_format.rs b/crates/task/src/debug_format.rs index f25243df87..068b0885b0 100644 --- a/crates/task/src/debug_format.rs +++ b/crates/task/src/debug_format.rs @@ -47,12 +47,35 @@ impl TcpArgumentsTemplate { } /// Represents the attach request information of the debug adapter -#[derive(Default, Deserialize, Serialize, PartialEq, Eq, JsonSchema, Clone, Debug)] +#[derive(Default, Serialize, PartialEq, Eq, JsonSchema, Clone, Debug)] pub struct AttachRequest { /// The processId to attach to, if left empty we will show a process picker pub process_id: Option, } +impl<'de> Deserialize<'de> for AttachRequest { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + process_id: Option, + } + + let helper = Helper::deserialize(deserializer)?; + + // Skip creating an AttachRequest if process_id is None + if helper.process_id.is_none() { + return Err(serde::de::Error::custom("process_id is required")); + } + + Ok(AttachRequest { + process_id: helper.process_id, + }) + } +} + /// Represents the launch request information of the debug adapter #[derive(Deserialize, Serialize, Default, PartialEq, Eq, JsonSchema, Clone, Debug)] pub struct LaunchRequest { @@ -204,7 +227,7 @@ impl DebugTaskFile { #[cfg(test)] mod tests { - use crate::{DebugRequest, LaunchRequest}; + use crate::{DebugRequest, DebugScenario, LaunchRequest}; #[test] fn test_can_deserialize_non_attach_task() { @@ -218,4 +241,52 @@ mod tests { }) ); } + + #[test] + fn test_empty_scenario_has_none_request() { + let json = r#"{ + "label": "Build & debug rust", + "build": "rust", + "adapter": "CodeLLDB" + }"#; + + let deserialized: DebugScenario = serde_json::from_str(json).unwrap(); + assert_eq!(deserialized.request, None); + } + + #[test] + fn test_launch_scenario_deserialization() { + let json = r#"{ + "label": "Launch program", + "adapter": "CodeLLDB", + "program": "target/debug/myapp", + "args": ["--test"] + }"#; + + let deserialized: DebugScenario = serde_json::from_str(json).unwrap(); + match deserialized.request { + Some(DebugRequest::Launch(launch)) => { + assert_eq!(launch.program, "target/debug/myapp"); + assert_eq!(launch.args, vec!["--test"]); + } + _ => panic!("Expected Launch request"), + } + } + + #[test] + fn test_attach_scenario_deserialization() { + let json = r#"{ + "label": "Attach to process", + "adapter": "CodeLLDB", + "process_id": 1234 + }"#; + + let deserialized: DebugScenario = serde_json::from_str(json).unwrap(); + match deserialized.request { + Some(DebugRequest::Attach(attach)) => { + assert_eq!(attach.process_id, Some(1234)); + } + _ => panic!("Expected Attach request"), + } + } }