From f6c7a4722073afbaf06b5eea24866af11793f71f Mon Sep 17 00:00:00 2001 From: Alessio Attilio Date: Mon, 12 Jan 2026 00:55:02 +0100 Subject: [PATCH] fix(engine): fallback to package scripts for missing tasks --- crates/turborepo-engine/src/builder.rs | 29 ++++++++++++------- .../repro-10516/package.json | 10 +++++++ .../task_dependencies/repro-10516/turbo.json | 9 ++++++ .../repro-10516/workspace-a/package.json | 9 ++++++ .../repro-10516/workspace-b/package.json | 6 ++++ .../tests/task-dependencies/repro-10516.t | 15 ++++++++++ 6 files changed, 68 insertions(+), 10 deletions(-) create mode 100644 turborepo-tests/integration/fixtures/task_dependencies/repro-10516/package.json create mode 100644 turborepo-tests/integration/fixtures/task_dependencies/repro-10516/turbo.json create mode 100644 turborepo-tests/integration/fixtures/task_dependencies/repro-10516/workspace-a/package.json create mode 100644 turborepo-tests/integration/fixtures/task_dependencies/repro-10516/workspace-b/package.json create mode 100644 turborepo-tests/integration/tests/task-dependencies/repro-10516.t diff --git a/crates/turborepo-engine/src/builder.rs b/crates/turborepo-engine/src/builder.rs index 9841a6d6e2907..7dcf344cac595 100644 --- a/crates/turborepo-engine/src/builder.rs +++ b/crates/turborepo-engine/src/builder.rs @@ -667,16 +667,25 @@ impl<'a, L: TurboJsonLoader> EngineBuilder<'a, L> { } } - if task_definitions.is_empty() && self.should_validate_engine { - let (span, text) = task_id.span_and_text("turbo.json"); - return Err(BuilderError::MissingPackageTask(Box::new( - MissingPackageTaskError { - span, - text, - task_id: task_id.to_string(), - task_name: task_name.to_string(), - }, - ))); + if task_definitions.is_empty() { + let has_script_in_package_json = self + .package_graph + .package_json(&package_name) + .is_some_and(|pkg_json| pkg_json.scripts.contains_key(task_name.task())); + + if has_script_in_package_json { + task_definitions.push(ProcessedTaskDefinition::default()); + } else if self.should_validate_engine { + let (span, text) = task_id.span_and_text("turbo.json"); + return Err(BuilderError::MissingPackageTask(Box::new( + MissingPackageTaskError { + span, + text, + task_id: task_id.to_string(), + task_name: task_name.to_string(), + }, + ))); + } } Ok(task_definitions) diff --git a/turborepo-tests/integration/fixtures/task_dependencies/repro-10516/package.json b/turborepo-tests/integration/fixtures/task_dependencies/repro-10516/package.json new file mode 100644 index 0000000000000..3951359aed3bd --- /dev/null +++ b/turborepo-tests/integration/fixtures/task_dependencies/repro-10516/package.json @@ -0,0 +1,10 @@ +{ + "name": "root-tasks", + "scripts": { + "test": "echo 'root test'" + }, + "workspaces": [ + "workspace-a", + "workspace-b" + ] +} diff --git a/turborepo-tests/integration/fixtures/task_dependencies/repro-10516/turbo.json b/turborepo-tests/integration/fixtures/task_dependencies/repro-10516/turbo.json new file mode 100644 index 0000000000000..2f05525e8fec4 --- /dev/null +++ b/turborepo-tests/integration/fixtures/task_dependencies/repro-10516/turbo.json @@ -0,0 +1,9 @@ +{ + "tasks": { + "dev": { + "dependsOn": [ + "workspace-a#build:openapi" + ] + } + } +} \ No newline at end of file diff --git a/turborepo-tests/integration/fixtures/task_dependencies/repro-10516/workspace-a/package.json b/turborepo-tests/integration/fixtures/task_dependencies/repro-10516/workspace-a/package.json new file mode 100644 index 0000000000000..6843b766191fa --- /dev/null +++ b/turborepo-tests/integration/fixtures/task_dependencies/repro-10516/workspace-a/package.json @@ -0,0 +1,9 @@ +{ + "name": "workspace-a", + "scripts": { + "build:openapi": "echo 'build:openapi workspace-a'" + }, + "dependencies": { + "workspace-b": "*" + } +} \ No newline at end of file diff --git a/turborepo-tests/integration/fixtures/task_dependencies/repro-10516/workspace-b/package.json b/turborepo-tests/integration/fixtures/task_dependencies/repro-10516/workspace-b/package.json new file mode 100644 index 0000000000000..558ea00a54201 --- /dev/null +++ b/turborepo-tests/integration/fixtures/task_dependencies/repro-10516/workspace-b/package.json @@ -0,0 +1,6 @@ +{ + "name": "workspace-b", + "scripts": { + "build": "echo 'build workspace-b'" + } +} diff --git a/turborepo-tests/integration/tests/task-dependencies/repro-10516.t b/turborepo-tests/integration/tests/task-dependencies/repro-10516.t new file mode 100644 index 0000000000000..a50282473e90d --- /dev/null +++ b/turborepo-tests/integration/tests/task-dependencies/repro-10516.t @@ -0,0 +1,15 @@ +Setup + $ . ${TESTDIR}/../../../helpers/setup_integration_test.sh task_dependencies/repro-10516 + +Test reproduction of issue 10516 + $ ${TURBO} run dev --graph + + digraph { + compound = "true" + newrank = "true" + subgraph "root" { + " workspace-a#build:openapi" -> " ___ROOT___" + " workspace-a#dev" -> " workspace-a#build:openapi" + " workspace-b#dev" -> " workspace-a#build:openapi" + } + }