Skip to content

Commit 8c3cc35

Browse files
committed
fix: merge synthetic task's input config in inherited cache path
When a synthetic task (e.g., vp pack, vp build) runs inside a parent script task, the parent's cache config is inherited. Previously, only env and untracked_env were merged from the synthetic — the input config was silently dropped, causing negative glob exclusions to be ignored. Now the synthetic's input globs are resolved relative to the workspace root and merged into the parent's input_config. This allows callers to pass negative globs (e.g., !node_modules/.vite-temp/**) that correctly exclude paths from fspy tracking. Closes voidzero-dev/vite-plus#1095
1 parent 4b5ae3d commit 8c3cc35

8 files changed

Lines changed: 95 additions & 1 deletion

File tree

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Simulates Vite's behavior during build:
2+
// 1. Reads the source file (tracked as input by fspy)
3+
// 2. Writes a temp config to node_modules/.vite-temp/ (also tracked by fspy)
4+
// Without the negative input glob, step 2 causes a read-write overlap
5+
// that prevents caching.
6+
7+
import { readFileSync, writeFileSync, mkdirSync } from 'node:fs';
8+
9+
// Read source (tracked as input)
10+
const source = readFileSync('src/index.ts', 'utf-8');
11+
12+
// Simulate Vite writing temp config (read-write to .vite-temp)
13+
const tempDir = 'node_modules/.vite-temp';
14+
mkdirSync(tempDir, { recursive: true });
15+
const tempFile = `${tempDir}/vite.config.ts.timestamp-${Date.now()}.mjs`;
16+
writeFileSync(tempFile, `// compiled config\nexport default {};`);
17+
18+
console.log(`built: ${source.trim()}`);
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"name": "cache-negative-input-glob",
3+
"private": true
4+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Tests that negative input globs exclude paths from fspy tracking,
2+
# so tasks writing to excluded paths (like node_modules/.vite-temp) are still cached.
3+
# See: https://github.com/voidzero-dev/vite-plus/issues/1095
4+
5+
[[e2e]]
6+
name = "negative input glob excludes vite-temp from tracking"
7+
steps = [
8+
"vt run build # first run: cache miss",
9+
"vt run build # second run: should hit cache despite .vite-temp write",
10+
]
11+
12+
[[e2e]]
13+
name = "source change still causes cache miss with negative input glob"
14+
steps = [
15+
"vt run build # first run: cache miss",
16+
"replace-file-content src/index.ts world universe # modify real source",
17+
"vt run build # cache miss: source changed",
18+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
---
2+
source: crates/vite_task_bin/tests/e2e_snapshots/main.rs
3+
expression: e2e_outputs
4+
---
5+
> vt run build # first run: cache miss
6+
$ node build.mjs
7+
built: export const hello = 'world';
8+
> vt run build # second run: should hit cache despite .vite-temp write
9+
$ node build.mjscache hit, replaying
10+
built: export const hello = 'world';
11+
12+
---
13+
vt run: cache hit, <duration> saved.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
source: crates/vite_task_bin/tests/e2e_snapshots/main.rs
3+
expression: e2e_outputs
4+
---
5+
> vt run build # first run: cache miss
6+
$ node build.mjs
7+
built: export const hello = 'world';
8+
> replace-file-content src/index.ts world universe # modify real source
9+
10+
> vt run build # cache miss: source changed
11+
$ node build.mjscache miss: 'src/index.ts' modified, executing
12+
built: export const hello = 'universe';
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const hello = 'world';
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"cache": true,
3+
"tasks": {
4+
"build": {
5+
"command": "node build.mjs",
6+
"cache": true,
7+
"input": [{ "auto": true }, "!node_modules/.vite-temp/**"]
8+
}
9+
}
10+
}

crates/vite_task_plan/src/plan.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use vite_str::Str;
2020
use vite_task_graph::{
2121
TaskNodeIndex, TaskSource,
2222
config::{
23-
CacheConfig, ResolvedGlobalCacheConfig, ResolvedTaskOptions,
23+
CacheConfig, ResolvedGlobalCacheConfig, ResolvedInputConfig, ResolvedTaskOptions,
2424
user::{UserCacheConfig, UserTaskOptions},
2525
},
2626
query::TaskQuery,
@@ -464,6 +464,24 @@ fn resolve_synthetic_cache_config(
464464
if let Some(extra_pts) = enabled_cache_config.untracked_env {
465465
parent_config.env_config.untracked_env.extend(extra_pts);
466466
}
467+
// Merge synthetic's input config (resolve relative to workspace root,
468+
// since synthetic commands operate at CLI level, not package level)
469+
if let Some(ref input) = enabled_cache_config.input {
470+
let synthetic_input = ResolvedInputConfig::from_user_config(
471+
Some(input),
472+
workspace_path,
473+
workspace_path,
474+
)
475+
.map_err(Error::ResolveTaskConfig)?;
476+
parent_config
477+
.input_config
478+
.negative_globs
479+
.extend(synthetic_input.negative_globs);
480+
parent_config
481+
.input_config
482+
.positive_globs
483+
.extend(synthetic_input.positive_globs);
484+
}
467485
Some(parent_config)
468486
}
469487
})

0 commit comments

Comments
 (0)