1use std::process::ExitStatus;
2
3use anyhow::{Result, anyhow};
4use gpui::{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 terminal_provider
72 .spawn(spawn_in_terminal, window, cx)
73 .detach_and_log_err(cx);
74 }
75 }
76
77 pub fn start_debug_session(
78 &mut self,
79 scenario: DebugScenario,
80 task_context: TaskContext,
81 active_buffer: Option<Entity<Buffer>>,
82 window: &mut Window,
83 cx: &mut Context<Self>,
84 ) {
85 if let Some(provider) = self.debugger_provider.as_mut() {
86 provider.start_session(scenario, task_context, active_buffer, window, cx)
87 }
88 }
89
90 pub fn spawn_in_terminal(
91 self: &mut Workspace,
92 spawn_in_terminal: SpawnInTerminal,
93 window: &mut Window,
94 cx: &mut Context<Workspace>,
95 ) -> Task<Result<ExitStatus>> {
96 if let Some(terminal_provider) = self.terminal_provider.as_ref() {
97 terminal_provider.spawn(spawn_in_terminal, window, cx)
98 } else {
99 Task::ready(Err(anyhow!("No terminal provider")))
100 }
101 }
102}