Skip to content
Merged
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
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ Tasks are defined in `vite-task.json`:
```

- `cache` (root): workspace-wide cache toggle. Default: `{ "scripts": false, "tasks": true }`
- `command`: shell command to run (falls back to package.json script if omitted)
- `command`: shell command to run (required)
- `cwd`: working directory relative to the package root
- `dependsOn`: explicit task dependencies (`taskName` or `package#task`)
- `cache` (task): enable/disable caching for this task (default: `true`)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
{
"name": "app",
"scripts": {
"build": "echo build app",
"test": "echo test app"
},
"dependencies": {
"lib": "workspace:*"
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
{
"tasks": {
"build": {},
"test": {},
"build": {
"command": "echo build app"
},
"test": {
"command": "echo test app"
},
"lint": {
"command": "echo lint app"
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
{
"name": "lib",
"scripts": {
"build": "echo build lib"
}
"name": "lib"
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
{
"tasks": {
"build": {}
"build": {
"command": "echo build lib"
}
}
}
4 changes: 1 addition & 3 deletions crates/vite_task_graph/run-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@
export type Task = {
/**
* The command to run for the task.
*
* If omitted, the script from `package.json` with the same name will be used
*/
command?: string;
command: string;
/**
* The working directory for the task, relative to the package root (not workspace root).
*/
Expand Down
22 changes: 3 additions & 19 deletions crates/vite_task_graph/src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,14 +243,6 @@ pub struct EnvConfig {

#[derive(Debug, thiserror::Error)]
pub enum ResolveTaskConfigError {
/// Both package.json script and vite.config.* task define commands for the task
#[error("Both package.json script and vite.config.* task define commands for the task")]
CommandConflict,

/// Neither package.json script nor vite.config.* task define a command for the task
#[error("Neither package.json script nor vite.config.* task define a command for the task")]
NoCommand,

/// A glob pattern resolves to a path outside the workspace root
#[error("glob pattern '{pattern}' resolves outside the workspace root")]
GlobOutsideWorkspace { pattern: Str },
Expand Down Expand Up @@ -288,26 +280,18 @@ impl ResolvedTaskConfig {
})
}

/// Resolves from user config, package dir, and package.json script (if any).
/// Resolves from user config and package dir.
///
/// # Errors
///
/// Returns [`ResolveTaskConfigError::CommandConflict`] if both the user config and
/// package.json define a command, or [`ResolveTaskConfigError::NoCommand`] if neither does.
/// Returns [`ResolveTaskConfigError`] if glob resolution fails.
pub fn resolve(
user_config: UserTaskConfig,
package_dir: &Arc<AbsolutePath>,
package_json_script: Option<&str>,
workspace_root: &AbsolutePath,
) -> Result<Self, ResolveTaskConfigError> {
let command = match (&user_config.command, package_json_script) {
(Some(_), Some(_)) => return Err(ResolveTaskConfigError::CommandConflict),
(None, None) => return Err(ResolveTaskConfigError::NoCommand),
(Some(cmd), None) => cmd.as_ref(),
(None, Some(script)) => script,
};
Ok(Self {
command: command.into(),
command: Str::from(user_config.command.as_ref()),
resolved_options: ResolvedTaskOptions::resolve(
user_config.options,
package_dir,
Expand Down
25 changes: 16 additions & 9 deletions crates/vite_task_graph/src/config/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,7 @@ impl Default for UserTaskOptions {
#[serde(rename_all = "camelCase")]
pub struct UserTaskConfig {
/// The command to run for the task.
///
/// If omitted, the script from `package.json` with the same name will be used
pub command: Option<Box<str>>,
pub command: Box<str>,

/// Fields other than the command
#[serde(flatten)]
Expand Down Expand Up @@ -365,22 +363,30 @@ mod tests {
use super::*;

#[test]
fn test_defaults() {
fn test_command_required() {
let user_config_json = json!({});
assert!(
serde_json::from_value::<UserTaskConfig>(user_config_json).is_err(),
"task config without command should fail to deserialize"
);
}

#[test]
fn test_command_with_defaults() {
let user_config_json = json!({
"command": "echo hello"
});
let user_config: UserTaskConfig = serde_json::from_value(user_config_json).unwrap();
assert_eq!(
user_config,
UserTaskConfig {
command: None,
// A empty task config (`{}`) should be equivalent to not specifying any config at all (just package.json script)
options: UserTaskOptions::default(),
}
UserTaskConfig { command: "echo hello".into(), options: UserTaskOptions::default() }
);
}

#[test]
fn test_cwd_rename() {
let user_config_json = json!({
"command": "echo test",
"cwd": "src"
});
let user_config: UserTaskConfig = serde_json::from_value(user_config_json).unwrap();
Expand All @@ -390,6 +396,7 @@ mod tests {
#[test]
fn test_cache_disabled() {
let user_config_json = json!({
"command": "echo test",
"cache": false
});
let user_config: UserTaskConfig = serde_json::from_value(user_config_json).unwrap();
Expand Down
21 changes: 17 additions & 4 deletions crates/vite_task_graph/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,12 @@ pub enum TaskGraphLoadError {
error: anyhow::Error,
},

#[error(
"Task {task_display} conflicts with a package.json script of the same name. \
Remove the script from package.json or rename the task"
)]
ScriptConflict { task_display: TaskDisplay },

#[error("Failed to resolve task config for task {task_display}")]
ResolveConfigError {
task_display: TaskDisplay,
Expand Down Expand Up @@ -264,18 +270,25 @@ impl IndexedTaskGraph {
.collect();

for (task_name, task_user_config) in user_config.tasks.unwrap_or_default() {
// For each task defined in the config, look up the corresponding package.json script (if any)
let package_json_script = package_json_scripts.remove(task_name.as_str());
// Error if a package.json script with the same name exists
if package_json_scripts.remove(task_name.as_str()).is_some() {
return Err(TaskGraphLoadError::ScriptConflict {
task_display: TaskDisplay {
package_name: package.package_json.name.clone(),
task_name: task_name.clone(),
package_path: Arc::clone(&package_dir),
},
});
}

let task_id = TaskId { task_name: task_name.clone(), package_index };

let dependency_specifiers = task_user_config.options.depends_on.clone();

// Resolve the task configuration combining config and package.json script
// Resolve the task configuration from the user config
let resolved_config = ResolvedTaskConfig::resolve(
task_user_config,
&package_dir,
package_json_script,
&workspace_root.path,
)
.map_err(|err| TaskGraphLoadError::ResolveConfigError {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{
"name": "@test/cache-scripts-task-override",
"scripts": {
"build": "print-file package.json",
"test": "print-file package.json"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
name = "task cached by default"
args = ["run", "build"]

# Task with explicit command should be cached
# Another task should also be cached
[[plan]]
name = "task with command cached by default"
name = "another task cached by default"
args = ["run", "deploy"]

# Script not wrapped by a task should not be cached
# Script not in the tasks map should not be cached
[[plan]]
name = "script not cached by default"
args = ["run", "test"]
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
{
"tasks": {
"build": {},
"build": {
"command": "print-file package.json"
},
"deploy": {
"command": "print-file package.json"
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{
"name": "@test/cache-tasks-disabled",
"scripts": {
"build": "print-file package.json",
"test": "print-file package.json"
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
{
"cache": { "tasks": false },
"tasks": {
"build": {},
"build": {
"command": "print-file package.json"
},
"deploy": {
"command": "print-file package.json",
"cache": true
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{
"name": "@test/cache-true-no-force-enable",
"scripts": {
"build": "print-file package.json",
"test": "print-file package.json"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"cache": true,
"tasks": {
"build": {
"command": "print-file package.json",
"cache": false
},
"deploy": {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "@test/script-conflict",
"scripts": {
"build": "echo from script"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
source: crates/vite_task_plan/tests/plan_snapshots/main.rs
expression: err_str.as_ref()
input_file: crates/vite_task_plan/tests/plan_snapshots/fixtures/script-conflict
---
Task @test/script-conflict#build conflicts with a package.json script of the same name. Remove the script from package.json or rename the task
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"tasks": {
"build": {
"command": "echo from task"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
"name": "test-workspace",
"private": true,
"scripts": {
"build": "vp run -r build",
"lint": "echo linting"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"cache": true,
"tasks": {
"build": {
"command": "vp run -r build",
"dependsOn": ["lint"]
}
}
Expand Down
Loading