Bail and signal error when the cwd of a resolved task doesn't exist (#32777)
Closes #32688 Release Notes: - Fixed tasks (including build tasks for debug configurations) silently using `/` as a working directory when the specified `cwd` didn't exist.
This commit is contained in:
parent
0f0ff40c6d
commit
22a2ff4f12
6 changed files with 54 additions and 4 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -15835,6 +15835,7 @@ dependencies = [
|
||||||
"serde_json_lenient",
|
"serde_json_lenient",
|
||||||
"sha2",
|
"sha2",
|
||||||
"shellexpand 2.1.2",
|
"shellexpand 2.1.2",
|
||||||
|
"smol",
|
||||||
"util",
|
"util",
|
||||||
"workspace-hack",
|
"workspace-hack",
|
||||||
"zed_actions",
|
"zed_actions",
|
||||||
|
|
|
@ -850,9 +850,18 @@ impl RunningState {
|
||||||
(task, None)
|
(task, None)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let Some(task) = task_template.resolve_task("debug-build-task", &task_context) else {
|
let Some(task) = task_template.resolve_task_and_check_cwd("debug-build-task", &task_context, cx.background_executor().clone()) else {
|
||||||
anyhow::bail!("Could not resolve task variables within a debug scenario");
|
anyhow::bail!("Could not resolve task variables within a debug scenario");
|
||||||
};
|
};
|
||||||
|
let task = match task.await {
|
||||||
|
Ok(task) => task,
|
||||||
|
Err(e) => {
|
||||||
|
workspace.update(cx, |workspace, cx| {
|
||||||
|
workspace.show_error(&e, cx);
|
||||||
|
}).ok();
|
||||||
|
return Err(e)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let locator_name = if let Some(locator_name) = locator_name {
|
let locator_name = if let Some(locator_name) = locator_name {
|
||||||
debug_assert!(!config_is_valid);
|
debug_assert!(!config_is_valid);
|
||||||
|
|
|
@ -29,6 +29,7 @@ serde_json.workspace = true
|
||||||
serde_json_lenient.workspace = true
|
serde_json_lenient.workspace = true
|
||||||
sha2.workspace = true
|
sha2.workspace = true
|
||||||
shellexpand.workspace = true
|
shellexpand.workspace = true
|
||||||
|
smol.workspace = true
|
||||||
util.workspace = true
|
util.workspace = true
|
||||||
workspace-hack.workspace = true
|
workspace-hack.workspace = true
|
||||||
zed_actions.workspace = true
|
zed_actions.workspace = true
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use anyhow::{Context as _, bail};
|
use anyhow::{Context as _, Result, anyhow, bail};
|
||||||
use collections::{HashMap, HashSet};
|
use collections::{HashMap, HashSet};
|
||||||
|
use gpui::{BackgroundExecutor, Task};
|
||||||
use schemars::{JsonSchema, r#gen::SchemaSettings};
|
use schemars::{JsonSchema, r#gen::SchemaSettings};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use sha2::{Digest, Sha256};
|
use sha2::{Digest, Sha256};
|
||||||
|
@ -270,6 +271,27 @@ impl TaskTemplate {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn resolve_task_and_check_cwd(
|
||||||
|
&self,
|
||||||
|
id_base: &str,
|
||||||
|
task_context: &TaskContext,
|
||||||
|
executor: BackgroundExecutor,
|
||||||
|
) -> Option<Task<Result<ResolvedTask>>> {
|
||||||
|
let resolved_task = self.resolve_task(id_base, task_context)?;
|
||||||
|
let task = executor.spawn(async move {
|
||||||
|
if let Some(cwd) = resolved_task.resolved.cwd.as_deref() {
|
||||||
|
match smol::fs::metadata(cwd).await {
|
||||||
|
Ok(metadata) if metadata.is_dir() => Ok(resolved_task),
|
||||||
|
Ok(_) => Err(anyhow!("cwd for resolved task is not a directory: {cwd:?}")),
|
||||||
|
Err(e) => Err(e).context(format!("reading cwd of resolved task: {cwd:?}")),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Ok(resolved_task)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Some(task)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const MAX_DISPLAY_VARIABLE_LENGTH: usize = 15;
|
const MAX_DISPLAY_VARIABLE_LENGTH: usize = 15;
|
||||||
|
|
|
@ -1461,10 +1461,27 @@ impl workspace::TerminalProvider for TerminalProvider {
|
||||||
&self,
|
&self,
|
||||||
task: SpawnInTerminal,
|
task: SpawnInTerminal,
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
cx: &mut App,
|
cx: &mut Context<Workspace>,
|
||||||
) -> Task<Option<Result<ExitStatus>>> {
|
) -> Task<Option<Result<ExitStatus>>> {
|
||||||
let terminal_panel = self.0.clone();
|
let terminal_panel = self.0.clone();
|
||||||
|
let workspace = cx.weak_entity();
|
||||||
window.spawn(cx, async move |cx| {
|
window.spawn(cx, async move |cx| {
|
||||||
|
if let Some(cwd) = task.cwd.as_deref() {
|
||||||
|
let result = match smol::fs::metadata(cwd).await {
|
||||||
|
Ok(metadata) if metadata.is_dir() => Ok(()),
|
||||||
|
Ok(_) => Err(anyhow!("cwd for resolved task is not a directory: {cwd:?}")),
|
||||||
|
Err(e) => Err(e).context(format!("reading cwd of resolved task: {cwd:?}")),
|
||||||
|
};
|
||||||
|
if let Err(e) = result {
|
||||||
|
workspace
|
||||||
|
.update(cx, |workspace, cx| {
|
||||||
|
workspace.show_error(&e, cx);
|
||||||
|
})
|
||||||
|
.ok();
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let terminal = terminal_panel
|
let terminal = terminal_panel
|
||||||
.update_in(cx, |terminal_panel, window, cx| {
|
.update_in(cx, |terminal_panel, window, cx| {
|
||||||
terminal_panel.spawn_task(&task, window, cx)
|
terminal_panel.spawn_task(&task, window, cx)
|
||||||
|
|
|
@ -135,7 +135,7 @@ pub trait TerminalProvider {
|
||||||
&self,
|
&self,
|
||||||
task: SpawnInTerminal,
|
task: SpawnInTerminal,
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
cx: &mut App,
|
cx: &mut Context<Workspace>,
|
||||||
) -> Task<Option<Result<ExitStatus>>>;
|
) -> Task<Option<Result<ExitStatus>>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue