|
| 1 | +# Plan: Resolve Globs to Workspace-Root-Relative at Task Graph Stage |
| 2 | + |
| 3 | +## Context |
| 4 | + |
| 5 | +`ResolvedInputConfig` currently stores raw user-provided glob strings (e.g. `src/**/*.ts`, `../shared/dist/**`) relative to the package directory. These are resolved at execution time using the now-removed `AnchoredGlob` type. The code is broken — `AnchoredGlob` was removed from `vite_glob` (commit f880ca10) but 3 files in `vite_task` still reference it. |
| 6 | + |
| 7 | +Moving glob resolution to the task_graph stage makes globs workspace-root-relative, eliminating `AnchoredGlob`, `glob_base`, and `base_dir` from the execution pipeline. |
| 8 | + |
| 9 | +## Algorithm: Resolve a single glob to workspace-root-relative |
| 10 | + |
| 11 | +``` |
| 12 | +partition(glob) → (invariant_prefix, variant) |
| 13 | +joined = package_dir.join(invariant_prefix) |
| 14 | +cleaned = path_clean::clean(joined) |
| 15 | +stripped = cleaned.strip_prefix(workspace_root) // error if fails |
| 16 | +result = wax::escape(stripped) + "/" + variant // or just escaped if no variant |
| 17 | +``` |
| 18 | + |
| 19 | +`AbsolutePath::strip_prefix` already normalizes separators, so no special Windows handling needed. |
| 20 | + |
| 21 | +--- |
| 22 | + |
| 23 | +## Steps |
| 24 | + |
| 25 | +### 1. Add deps to `vite_task_graph` |
| 26 | + |
| 27 | +**File:** `crates/vite_task_graph/Cargo.toml` |
| 28 | + |
| 29 | +Add `wax` and `path-clean` (already workspace deps). |
| 30 | + |
| 31 | +### 2. Add glob resolution to `ResolvedInputConfig` |
| 32 | + |
| 33 | +**File:** `crates/vite_task_graph/src/config/mod.rs` |
| 34 | + |
| 35 | +- Add error variants to `ResolveTaskConfigError`: |
| 36 | + - `GlobOutsideWorkspace { pattern: Str }` — "glob pattern '...' resolves outside the workspace root" |
| 37 | + - `InvalidGlob { pattern: Str, source: wax::BuildError }` |
| 38 | + |
| 39 | +- Add helper `resolve_glob_to_workspace_relative(pattern, package_dir, workspace_root) -> Result<Str, ResolveTaskConfigError>` implementing the algorithm above. |
| 40 | + |
| 41 | +- Change `from_user_config` signature to accept `package_dir` and `workspace_root`, return `Result`. Each raw glob goes through `resolve_glob_to_workspace_relative`. |
| 42 | + |
| 43 | +- Change `ResolvedTaskOptions::resolve()` to accept `workspace_root`, return `Result`. |
| 44 | + |
| 45 | +- Change `ResolvedTaskConfig::resolve()` and `resolve_package_json_script()` to accept `workspace_root`, return `Result`. |
| 46 | + |
| 47 | +### 3. Thread `workspace_root` in `IndexedTaskGraph::load()` |
| 48 | + |
| 49 | +**File:** `crates/vite_task_graph/src/lib.rs` |
| 50 | + |
| 51 | +Pass `&workspace_root.path` to `ResolvedTaskConfig::resolve()` (line ~275) and `resolve_package_json_script()` (line ~307). Propagate the new `Result`. |
| 52 | + |
| 53 | +### 4. Remove `glob_base` from `CacheMetadata` |
| 54 | + |
| 55 | +**File:** `crates/vite_task_plan/src/cache_metadata.rs` |
| 56 | + |
| 57 | +Remove `glob_base: Arc<AbsolutePath>` field. |
| 58 | + |
| 59 | +### 5. Remove `glob_base` from plan construction |
| 60 | + |
| 61 | +**File:** `crates/vite_task_plan/src/plan.rs` |
| 62 | + |
| 63 | +Remove `glob_base: Arc::clone(package_path)` at line ~558. |
| 64 | + |
| 65 | +### 6. Remove `glob_base` from `CacheEntryKey` + bump DB version |
| 66 | + |
| 67 | +**File:** `crates/vite_task/src/session/cache/mod.rs` |
| 68 | + |
| 69 | +- Remove `glob_base: RelativePathBuf` from `CacheEntryKey` (line 43). |
| 70 | +- Simplify `from_metadata()` — remove glob_base strip_prefix logic (lines 56-66). |
| 71 | +- Bump cache version: `1..=8` → `1..=9`, `9 => break` → `10 => break`, new DB `PRAGMA user_version = 10`, unrecognized `10..` → `11..`. |
| 72 | + |
| 73 | +### 7. Simplify `compute_globbed_inputs()` |
| 74 | + |
| 75 | +**File:** `crates/vite_task/src/session/execute/glob_inputs.rs` |
| 76 | + |
| 77 | +- Remove `use vite_glob::AnchoredGlob` import. |
| 78 | +- Remove `base_dir` parameter — globs are already workspace-root-relative. |
| 79 | +- For each positive glob: `Glob::new(pattern).walk(workspace_root).not(negatives)` — `.not()` supports directory pruning for efficiency. No partition/join/clean. |
| 80 | +- Parse all negative globs upfront as `Vec<Glob<'static>>` and pass to `.not()` for each positive walk. |
| 81 | + |
| 82 | +### 8. Simplify fspy filtering in `spawn.rs` |
| 83 | + |
| 84 | +**File:** `crates/vite_task/src/session/execute/spawn.rs` |
| 85 | + |
| 86 | +- Remove `use vite_glob::AnchoredGlob`. |
| 87 | +- Change `resolved_negatives: &[AnchoredGlob]` → `resolved_negatives: &[wax::Glob<'static>]`. |
| 88 | +- At lines 216-224: match `relative_path` directly against negative globs (both are workspace-relative). Remove `path_clean`, `workspace_root.join`, `AbsolutePath::new`. |
| 89 | + |
| 90 | +### 9. Simplify `execute_spawn()` in `mod.rs` |
| 91 | + |
| 92 | +**File:** `crates/vite_task/src/session/execute/mod.rs` |
| 93 | + |
| 94 | +- Remove `resolve_negative_globs()` function (lines 425-434). |
| 95 | +- Update `compute_globbed_inputs` call: remove `cache_metadata.glob_base`, pass `cache_base_path` as workspace root. |
| 96 | +- Build negative globs inline: `negative_globs.iter().map(|p| Glob::new(p).into_owned()).collect()`. |
| 97 | + |
| 98 | +### 10. Update tests |
| 99 | + |
| 100 | +- **`config/mod.rs` tests**: Add `package_dir` + `workspace_root` params. Assert workspace-root-relative patterns. Add test for `..` resolution and outside-workspace error. |
| 101 | +- **`glob_inputs.rs` tests**: Remove `base_dir` param, pass workspace-root-relative globs. |
| 102 | +- **Plan snapshots**: `INSTA_UPDATE=always cargo test -p vite_task_plan --test plan_snapshots` (removes `glob_base` lines). |
| 103 | +- **E2E snapshots**: `INSTA_UPDATE=always cargo test -p vite_task_bin --test e2e_snapshots`. |
| 104 | + |
| 105 | +--- |
| 106 | + |
| 107 | +## Verification |
| 108 | + |
| 109 | +```bash |
| 110 | +cargo check --all-targets |
| 111 | +cargo test |
| 112 | +INSTA_UPDATE=always cargo test -p vite_task_plan --test plan_snapshots |
| 113 | +INSTA_UPDATE=always cargo test -p vite_task_bin --test e2e_snapshots |
| 114 | +just lint |
| 115 | +``` |
0 commit comments