Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

- **Perf** When tasks miss the cache, `vp run` no longer waits for the disk after saving each task's result, so the run finishes sooner. If the computer loses power or the operating system crashes during `vp run`, the cache entries that the run saved can be lost, and those tasks run again next time instead of hitting the cache ([#871](https://github.com/voidzero-dev/vite-task/pull/871)).
- **Fixed** Running `vp run` in a package that sits inside a workspace folder but isn't listed in its `pnpm-workspace.yaml` `packages` or `package.json` `workspaces` now runs that package's own tasks, instead of treating the enclosing workspace as its root. When both configurations exist, `pnpm-workspace.yaml` takes precedence ([#859](https://github.com/voidzero-dev/vite-task/pull/859)).
- **Fixed** In a script like `cd ui && vpr hello`, where `ui` is a separate project outside the workspace, the nested `vp run` now runs `ui`'s `hello` instead of the workspace root's ([vite-plus#3129](https://github.com/voidzero-dev/vite-plus/issues/3129), [#867](https://github.com/voidzero-dev/vite-task/pull/867)).
- **Fixed** A mistyped or misplaced setting in a task now gets an error that names it. For example, `cache: { outputs: [...] }` now fails with an `unknown field` error that names `outputs` and lists the accepted settings, instead of `data did not match any variant of untagged enum UserTaskDefinition` ([vite-plus#2635](https://github.com/voidzero-dev/vite-plus/issues/2635), [#815](https://github.com/voidzero-dev/vite-task/pull/815)).
- **Fixed** In cached tasks on Linux and macOS, programs that pass `-1` as a directory descriptor to calls such as `openat` no longer abort. For example, `ps -p <pid>` from procps-ng 4.0.6 or later aborted when the process had already exited ([#862](https://github.com/voidzero-dev/vite-task/pull/862)).
- **Fixed** `vp run` no longer panics before running a script that contains non-ASCII characters, such as `echo こんにちは`, and no longer cuts off such commands where it displays them ([#861](https://github.com/voidzero-dev/vite-task/pull/861)).
Expand Down
2 changes: 1 addition & 1 deletion crates/vt_plan/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ vt_powershell = { workspace = true }
vt_shell = { workspace = true }
vt_str = { workspace = true }
vt_graph = { workspace = true }
vt_workspace = { workspace = true }
which = { workspace = true }

[dev-dependencies]
Expand All @@ -46,7 +47,6 @@ tokio = { workspace = true, features = ["rt", "macros"] }
toml = { workspace = true }
vt = { workspace = true }
vt_bin = { workspace = true }
vt_workspace = { workspace = true }

[[test]]
name = "plan_snapshots"
Expand Down
26 changes: 25 additions & 1 deletion crates/vt_plan/src/plan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ use vt_graph::{
use vt_path::{AbsolutePath, AbsolutePathBuf, RelativePathBuf, relative::InvalidPathDataError};
use vt_shell::try_parse_as_and_list;
use vt_str::Str;
use vt_workspace::find_workspace_root;

use crate::{
ExecutionItem, ExecutionItemDisplay, ExecutionItemKind, LeafExecutionKind, PlanContext,
Expand All @@ -45,6 +46,13 @@ use crate::{
resolve_cache_with_override,
};

/// Whether `cwd` belongs to a workspace other than the one rooted at `workspace_path`.
///
/// Directories without any discoverable workspace root are treated as part of `workspace_path`.
fn is_in_other_workspace(cwd: &AbsolutePath, workspace_path: &AbsolutePath) -> bool {
find_workspace_root(cwd).is_ok_and(|(root, _)| &*root.path != workspace_path)
}

/// Locate the executable path for a given program name in the provided envs and cwd.
fn which(
program: &Arc<OsStr>,
Expand Down Expand Up @@ -229,7 +237,10 @@ async fn plan_task_as_execution_node(
envs,
cwd: Arc::clone(&cwd),
};
let plan_request =
// The command as written, before the callback rewrites it (e.g. `vpr` -> `vt run`).
let original_program = script_command.program.clone();
let original_args = Arc::clone(&script_command.args);
let mut plan_request =
context.callbacks().get_plan_request(&mut script_command).await.map_err(
|error| Error::ParsePlanRequest {
program: script_command.program.clone(),
Expand All @@ -239,6 +250,19 @@ async fn plan_task_as_execution_node(
},
)?;

// After a `cd` into a project that is not part of this workspace (it has its own
// workspace root), this workspace's task graph cannot resolve the nested run:
// it would fall back to the enclosing package. Run the command as written
// instead, so it discovers its own workspace like it does in a shell.
if matches!(plan_request, Some(PlanRequest::Query(_)))
&& *cwd != *task_node.resolved_config.resolved_options.cwd
&& is_in_other_workspace(&cwd, context.workspace_path())
{
plan_request = None;
script_command.program = original_program;
script_command.args = original_args;
}

let execution_item_kind: ExecutionItemKind = match plan_request {
// Expand task query like `vp run -r build`
Some(PlanRequest::Query(query_plan_request)) => {
Expand Down
1 change: 1 addition & 0 deletions crates/vt_plan/tests/plan_snapshots/fake-bin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ never actually executed during plan tests — only its resolved path appears in

- `vtt` — Unix stub (executable shell script)
- `vtt.cmd` — Windows stub (looked up via `PATHEXT`)
- `vpr`, `vpr.cmd` — the same stubs for `vpr`, which is spawned as written when a script `cd`s into a project outside the workspace
1 change: 1 addition & 0 deletions crates/vt_plan/tests/plan_snapshots/fake-bin/vpr
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#\!/bin/sh
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "root",
"private": true,
"scripts": {
"hello": "echo ROOT",
"plain": "cd ui && vpr hello"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Tests that after `cd` into a nested project outside this workspace (no workspace file lists it),
# a nested `vpr` runs as written instead of planning the enclosing package's task.

[fields]
key = true
execution_item_display = { command = true, cwd = true }
spawn_command = { program_path = true, args = true, cwd = true }

[[plan]]
name = "cd_into_other_project_then_vpr"
args = ["run", "plain"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// run plain
{
"graph": [
{
"key": [
"<workspace>/",
"plain"
],
"node": {
"items": [
{
"execution_item_display": {
"command": "vpr hello",
"cwd": "<workspace>/ui"
},
"kind": {
"Leaf": {
"Spawn": {
"spawn_command": {
"program_path": "<tools>/vpr",
"args": [
"hello"
],
"cwd": "<workspace>/ui"
}
}
}
}
}
]
}
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# task graph

```mermaid
flowchart TD
task_0["<workspace>/#hello"]
task_1["<workspace>/#plain"]
```

## `<workspace>/#hello`

```json
{
"task_display": {
"package_name": "root",
"task_name": "hello",
"package_path": "<workspace>/"
},
"resolved_config": {
"commands": [
"echo ROOT"
],
"resolved_options": {
"cwd": "<workspace>/",
"cache_config": {
"remote_cache_allowed": true,
"env_config": {
"fingerprinted_envs": [],
"untracked_env": [
"<default untracked envs>"
]
},
"input_config": {
"includes_auto": true,
"positive_globs": [],
"negative_globs": []
},
"output_config": {
"includes_auto": true,
"positive_globs": [],
"negative_globs": []
}
}
}
},
"source": "PackageJsonScript"
}
```

## `<workspace>/#plain`

```json
{
"task_display": {
"package_name": "root",
"task_name": "plain",
"package_path": "<workspace>/"
},
"resolved_config": {
"commands": [
"cd ui && vpr hello"
],
"resolved_options": {
"cwd": "<workspace>/",
"cache_config": {
"remote_cache_allowed": true,
"env_config": {
"fingerprinted_envs": [],
"untracked_env": [
"<default untracked envs>"
]
},
"input_config": {
"includes_auto": true,
"positive_globs": [],
"negative_globs": []
},
"output_config": {
"includes_auto": true,
"positive_globs": [],
"negative_globs": []
}
}
}
},
"source": "PackageJsonScript"
}
```

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"name":"ui","private":true,"scripts":{"hello":"echo UI"}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"cache": true
}