1use std::process::ExitStatus;
2
3use anyhow::Result;
4use gpui::{AppContext, Context, Entity, Task};
5use language::Buffer;
6use project::TaskSourceKind;
7use remote::ConnectionState;
8use task::{DebugScenario, ResolvedTask, SpawnInTerminal, TaskContext, TaskTemplate};
9use ui::Window;
10
11use crate::Workspace;
12
13impl Workspace {
14 pub fn schedule_task(
15 self: &mut Workspace,
16 task_source_kind: TaskSourceKind,
17 task_to_resolve: &TaskTemplate,
18 task_cx: &TaskContext,
19 omit_history: bool,
20 window: &mut Window,
21 cx: &mut Context<Self>,
22 ) {
23 match self.project.read(cx).ssh_connection_state(cx) {
24 None | Some(ConnectionState::Connected) => {}
25 Some(
26 ConnectionState::Connecting
27 | ConnectionState::Disconnected
28 | ConnectionState::HeartbeatMissed
29 | ConnectionState::Reconnecting,
30 ) => {
31 log::warn!("Cannot schedule tasks when disconnected from a remote host");
32 return;
33 }
34 }
35
36 if let Some(spawn_in_terminal) =
37 task_to_resolve.resolve_task(&task_source_kind.to_id_base(), task_cx)
38 {
39 self.schedule_resolved_task(
40 task_source_kind,
41 spawn_in_terminal,
42 omit_history,
43 window,
44 cx,
45 );
46 }
47 }
48
49 pub fn schedule_resolved_task(
50 self: &mut Workspace,
51 task_source_kind: TaskSourceKind,
52 resolved_task: ResolvedTask,
53 omit_history: bool,
54 window: &mut Window,
55 cx: &mut Context<Workspace>,
56 ) {
57 let spawn_in_terminal = resolved_task.resolved.clone();
58 if !omit_history {
59 self.project().update(cx, |project, cx| {
60 if let Some(task_inventory) =
61 project.task_store().read(cx).task_inventory().cloned()
62 {
63 task_inventory.update(cx, |inventory, _| {
64 inventory.task_scheduled(task_source_kind, resolved_task);
65 })
66 }
67 });
68 }
69
70 if let Some(terminal_provider) = self.terminal_provider.as_ref() {
71 let task_status = terminal_provider.spawn(spawn_in_terminal, window, cx);
72 cx.background_spawn(async move {
73 match task_status.await {
74 Some(Ok(status)) => {
75 if status.success() {
76 log::debug!("Task spawn succeeded");
77 } else {
78 log::debug!("Task spawn failed, code: {:?}", status.code());
79 }
80 }
81 Some(Err(e)) => log::error!("Task spawn failed: {e}"),
82 None => log::debug!("Task spawn got cancelled"),
83 }
84 })
85 .detach();
86 }
87 }
88
89 pub fn start_debug_session(
90 &mut self,
91 scenario: DebugScenario,
92 task_context: TaskContext,
93 active_buffer: Option<Entity<Buffer>>,
94 window: &mut Window,
95 cx: &mut Context<Self>,
96 ) {
97 if let Some(provider) = self.debugger_provider.as_mut() {
98 provider.start_session(scenario, task_context, active_buffer, window, cx)
99 }
100 }
101
102 pub fn spawn_in_terminal(
103 self: &mut Workspace,
104 spawn_in_terminal: SpawnInTerminal,
105 window: &mut Window,
106 cx: &mut Context<Workspace>,
107 ) -> Task<Option<Result<ExitStatus>>> {
108 if let Some(terminal_provider) = self.terminal_provider.as_ref() {
109 terminal_provider.spawn(spawn_in_terminal, window, cx)
110 } else {
111 Task::ready(None)
112 }
113 }
114}