diff --git a/Cargo.lock b/Cargo.lock index 7c4b8a5c..9fd2b0db 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1502,6 +1502,15 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "jsonc-parser" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eb0774546269185d38da823d8583e94448ba0e158e3f50759d9c79aba946ca5" +dependencies = [ + "serde_json", +] + [[package]] name = "konst" version = "0.2.19" @@ -3319,8 +3328,10 @@ dependencies = [ "copy_dir", "cow-utils", "insta", + "jsonc-parser", "regex", "serde", + "serde_json", "tempfile", "tokio", "toml", @@ -3338,6 +3349,7 @@ dependencies = [ "anyhow", "async-trait", "clap", + "jsonc-parser", "monostate", "petgraph", "pretty_assertions", diff --git a/Cargo.toml b/Cargo.toml index 4595da9f..6ca05928 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -75,6 +75,7 @@ fspy_test_utils = { path = "crates/fspy_test_utils" } futures = "0.3.31" futures-util = "0.3.31" insta = "1.44.3" +jsonc-parser = { version = "0.29.0", features = ["serde"] } libc = "0.2.172" memmap2 = "0.9.7" monostate = "1.0.2" diff --git a/crates/vite_task_bin/Cargo.toml b/crates/vite_task_bin/Cargo.toml index 879a468b..29c22a15 100644 --- a/crates/vite_task_bin/Cargo.toml +++ b/crates/vite_task_bin/Cargo.toml @@ -14,6 +14,8 @@ path = "src/main.rs" anyhow = { workspace = true } async-trait = { workspace = true } clap = { workspace = true, features = ["derive"] } +jsonc-parser = { workspace = true } +serde_json = { workspace = true } tokio = { workspace = true, features = ["full"] } vite_path = { workspace = true } vite_str = { workspace = true } diff --git a/crates/vite_task_bin/src/lib.rs b/crates/vite_task_bin/src/lib.rs index 1284f415..49fd6a06 100644 --- a/crates/vite_task_bin/src/lib.rs +++ b/crates/vite_task_bin/src/lib.rs @@ -135,10 +135,37 @@ impl vite_task::TaskSynthesizer for TaskSynthesizer { } } +/// A `UserConfigLoader` implementation that only loads `vite-task.json`. +/// +/// This is mainly for examples and testing as it does not require Node.js environment. +#[derive(Default, Debug)] +pub struct JsonUserConfigLoader(()); + +#[async_trait::async_trait(?Send)] +impl vite_task::loader::UserConfigLoader for JsonUserConfigLoader { + async fn load_user_config_file( + &self, + package_path: &AbsolutePath, + ) -> anyhow::Result> { + let config_path = package_path.join("vite-task.json"); + let config_content = match tokio::fs::read_to_string(&config_path).await { + Ok(content) => content, + Err(err) if err.kind() == std::io::ErrorKind::NotFound => { + return Ok(None); + } + Err(err) => return Err(err.into()), + }; + let json_value = jsonc_parser::parse_to_serde_value(&config_content, &Default::default())? + .unwrap_or_default(); + let user_config: vite_task::config::UserRunConfig = serde_json::from_value(json_value)?; + Ok(Some(user_config)) + } +} + #[derive(Default)] pub struct OwnedSessionCallbacks { task_synthesizer: TaskSynthesizer, - user_config_loader: vite_task::loader::JsonUserConfigLoader, + user_config_loader: JsonUserConfigLoader, } impl OwnedSessionCallbacks { diff --git a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/vite-task-smoke/vite-task.json b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/vite-task-smoke/vite-task.json index 1d0fe9f2..43bed5d7 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/fixtures/vite-task-smoke/vite-task.json +++ b/crates/vite_task_bin/tests/e2e_snapshots/fixtures/vite-task-smoke/vite-task.json @@ -1,3 +1,4 @@ { + // Smoke test: enables caching for all package.json scripts. "cacheScripts": true } diff --git a/crates/vite_task_graph/Cargo.toml b/crates/vite_task_graph/Cargo.toml index 17fc8225..36b32dc8 100644 --- a/crates/vite_task_graph/Cargo.toml +++ b/crates/vite_task_graph/Cargo.toml @@ -15,7 +15,6 @@ petgraph = { workspace = true } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } thiserror = { workspace = true } -tokio = { workspace = true, features = ["fs"] } vec1 = { workspace = true, features = ["smallvec-v1"] } vite_graph_ser = { workspace = true } vite_path = { workspace = true } @@ -24,7 +23,6 @@ vite_workspace = { workspace = true } [dev-dependencies] pretty_assertions = { workspace = true } -tokio = { workspace = true, features = ["fs", "rt-multi-thread"] } ts-rs = { workspace = true } vite_path = { workspace = true, features = ["ts-rs"] } vite_str = { workspace = true, features = ["ts-rs"] } diff --git a/crates/vite_task_graph/src/loader.rs b/crates/vite_task_graph/src/loader.rs index 8a192fdc..d00f2dfe 100644 --- a/crates/vite_task_graph/src/loader.rs +++ b/crates/vite_task_graph/src/loader.rs @@ -12,28 +12,3 @@ pub trait UserConfigLoader: Debug + Send + Sync { package_path: &AbsolutePath, ) -> anyhow::Result>; } - -/// A `UserConfigLoader` implementation that only loads `vite-task.json`. -/// -/// This is mainly for examples and testing as it does not require Node.js environment. -#[derive(Default, Debug)] -pub struct JsonUserConfigLoader(()); - -#[async_trait::async_trait(?Send)] -impl UserConfigLoader for JsonUserConfigLoader { - async fn load_user_config_file( - &self, - package_path: &AbsolutePath, - ) -> anyhow::Result> { - let config_path = package_path.join("vite-task.json"); - let config_content = match tokio::fs::read_to_string(&config_path).await { - Ok(content) => content, - Err(err) if err.kind() == std::io::ErrorKind::NotFound => { - return Ok(None); - } - Err(err) => return Err(err.into()), - }; - let user_config: UserRunConfig = serde_json::from_str(&config_content)?; - Ok(Some(user_config)) - } -} diff --git a/crates/vite_task_plan/tests/plan_snapshots/fixtures/cache-scripts-enabled/vite-task.json b/crates/vite_task_plan/tests/plan_snapshots/fixtures/cache-scripts-enabled/vite-task.json index 1d0fe9f2..e9f7182a 100644 --- a/crates/vite_task_plan/tests/plan_snapshots/fixtures/cache-scripts-enabled/vite-task.json +++ b/crates/vite_task_plan/tests/plan_snapshots/fixtures/cache-scripts-enabled/vite-task.json @@ -1,3 +1,4 @@ { + // Enables caching for all package.json scripts in the workspace. "cacheScripts": true } diff --git a/crates/vite_task_plan/tests/plan_snapshots/fixtures/comprehensive-task-graph/vite-task.json b/crates/vite_task_plan/tests/plan_snapshots/fixtures/comprehensive-task-graph/vite-task.json index 1d0fe9f2..e9f7182a 100644 --- a/crates/vite_task_plan/tests/plan_snapshots/fixtures/comprehensive-task-graph/vite-task.json +++ b/crates/vite_task_plan/tests/plan_snapshots/fixtures/comprehensive-task-graph/vite-task.json @@ -1,3 +1,4 @@ { + // Enables caching for all package.json scripts in the workspace. "cacheScripts": true } diff --git a/crates/vite_task_plan/tests/plan_snapshots/fixtures/workspace-root-no-package-json/vite-task.json b/crates/vite_task_plan/tests/plan_snapshots/fixtures/workspace-root-no-package-json/vite-task.json index f07f1a9c..e79ab80a 100644 --- a/crates/vite_task_plan/tests/plan_snapshots/fixtures/workspace-root-no-package-json/vite-task.json +++ b/crates/vite_task_plan/tests/plan_snapshots/fixtures/workspace-root-no-package-json/vite-task.json @@ -1,4 +1,6 @@ { + // This workspace root has no package.json — only pnpm-workspace.yaml. + // vite-task.json should still be loaded and applied. "cacheScripts": true, "tasks": { "deploy": {