summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSatya Rohith <me@satyarohith.com>2024-08-06 20:35:30 +0530
committerGitHub <noreply@github.com>2024-08-06 20:35:30 +0530
commitb3f1f3ba04e51554ab59d6255bf34a79a9c42bd0 (patch)
tree6455a67387f69c01803e12bc1652eeb0f7dbf7ca
parent897159dc6e1b2319cf2f5f09d8d6cecc0d3175fa (diff)
feat: deno run <task> (#24891)
This PR updates `deno run` to fallback to executing tasks when there is no script with the specified name. If there are both script and a task with the same name then `deno run` will prioritise executing the script.
-rw-r--r--cli/main.rs32
-rw-r--r--cli/standalone/mod.rs4
-rw-r--r--cli/tools/task.rs7
-rw-r--r--tests/specs/run/run_task/__test__.jsonc13
-rw-r--r--tests/specs/run/run_task/deno.json5
-rw-r--r--tests/specs/run/run_task/main.out2
-rw-r--r--tests/specs/run/run_task/main.ts1
-rw-r--r--tests/specs/run/run_task/not_found.out1
8 files changed, 60 insertions, 5 deletions
diff --git a/cli/main.rs b/cli/main.rs
index d17f0f260..9cb2b2644 100644
--- a/cli/main.rs
+++ b/cli/main.rs
@@ -37,6 +37,7 @@ use crate::util::display;
use crate::util::v8::get_v8_flags_from_env;
use crate::util::v8::init_v8_flags;
+use args::TaskFlags;
use deno_runtime::WorkerExecutionMode;
pub use deno_runtime::UNSTABLE_GRANULAR_FLAGS;
@@ -50,8 +51,10 @@ use deno_runtime::fmt_errors::format_js_error;
use deno_runtime::tokio_util::create_and_run_current_thread_with_maybe_metrics;
use deno_terminal::colors;
use factory::CliFactory;
+use standalone::MODULE_NOT_FOUND;
use std::env;
use std::future::Future;
+use std::ops::Deref;
use std::path::PathBuf;
use std::sync::Arc;
@@ -177,16 +180,39 @@ async fn run_subcommand(flags: Arc<Flags>) -> Result<i32, AnyError> {
}
DenoSubcommand::Run(run_flags) => spawn_subcommand(async move {
if run_flags.is_stdin() {
- tools::run::run_from_stdin(flags).await
+ tools::run::run_from_stdin(flags.clone()).await
} else {
- tools::run::run_script(WorkerExecutionMode::Run, flags, run_flags.watch).await
+ let result = tools::run::run_script(WorkerExecutionMode::Run, flags.clone(), run_flags.watch).await;
+ match result {
+ Ok(v) => Ok(v),
+ Err(script_err) => {
+ if script_err.to_string().starts_with(MODULE_NOT_FOUND) {
+ let mut new_flags = flags.deref().clone();
+ let task_flags = TaskFlags {
+ cwd: None,
+ task: Some(run_flags.script.clone()),
+ };
+ new_flags.subcommand = DenoSubcommand::Task(task_flags.clone());
+ let result = tools::task::execute_script(Arc::new(new_flags), task_flags.clone(), true).await;
+ match result {
+ Ok(v) => Ok(v),
+ Err(_) => {
+ // Return script error for backwards compatibility.
+ Err(script_err)
+ }
+ }
+ } else {
+ Err(script_err)
+ }
+ },
+ }
}
}),
DenoSubcommand::Serve(serve_flags) => spawn_subcommand(async move {
tools::run::run_script(WorkerExecutionMode::Serve, flags, serve_flags.watch).await
}),
DenoSubcommand::Task(task_flags) => spawn_subcommand(async {
- tools::task::execute_script(flags, task_flags).await
+ tools::task::execute_script(flags, task_flags, false).await
}),
DenoSubcommand::Test(test_flags) => {
spawn_subcommand(async {
diff --git a/cli/standalone/mod.rs b/cli/standalone/mod.rs
index 935e034df..e4661051a 100644
--- a/cli/standalone/mod.rs
+++ b/cli/standalone/mod.rs
@@ -131,6 +131,8 @@ struct EmbeddedModuleLoader {
dynamic_permissions: PermissionsContainer,
}
+pub const MODULE_NOT_FOUND: &str = "Module not found";
+
impl ModuleLoader for EmbeddedModuleLoader {
fn resolve(
&self,
@@ -336,7 +338,7 @@ impl ModuleLoader for EmbeddedModuleLoader {
let Some(module) = self.shared.eszip.get_module(original_specifier) else {
return deno_core::ModuleLoadResponse::Sync(Err(type_error(format!(
- "Module not found: {}",
+ "{MODULE_NOT_FOUND}: {}",
original_specifier
))));
};
diff --git a/cli/tools/task.rs b/cli/tools/task.rs
index f296a070f..f559ab9b4 100644
--- a/cli/tools/task.rs
+++ b/cli/tools/task.rs
@@ -12,6 +12,7 @@ use deno_config::deno_json::Task;
use deno_config::workspace::TaskOrScript;
use deno_config::workspace::WorkspaceDirectory;
use deno_config::workspace::WorkspaceTasksConfig;
+use deno_core::anyhow::anyhow;
use deno_core::anyhow::bail;
use deno_core::anyhow::Context;
use deno_core::error::AnyError;
@@ -28,6 +29,7 @@ use std::sync::Arc;
pub async fn execute_script(
flags: Arc<Flags>,
task_flags: TaskFlags,
+ using_run: bool,
) -> Result<i32, AnyError> {
let factory = CliFactory::from_flags(flags);
let cli_options = factory.cli_options()?;
@@ -140,7 +142,10 @@ pub async fn execute_script(
}
},
None => {
- log::error!("Task not found: {task_name}");
+ if using_run {
+ return Err(anyhow!("Task not found: {}", task_name));
+ }
+ log::error!("Task not found: {}", task_name);
if log::log_enabled!(log::Level::Error) {
print_available_tasks(
&mut std::io::stderr(),
diff --git a/tests/specs/run/run_task/__test__.jsonc b/tests/specs/run/run_task/__test__.jsonc
new file mode 100644
index 000000000..0d1c82efd
--- /dev/null
+++ b/tests/specs/run/run_task/__test__.jsonc
@@ -0,0 +1,13 @@
+{
+ "tests": {
+ "deno_run_task": {
+ "args": "run main",
+ "output": "main.out"
+ },
+ "deno_run_module_task_not_found": {
+ "args": "run not_found",
+ "output": "not_found.out",
+ "exitCode": 1
+ }
+ }
+}
diff --git a/tests/specs/run/run_task/deno.json b/tests/specs/run/run_task/deno.json
new file mode 100644
index 000000000..54772504e
--- /dev/null
+++ b/tests/specs/run/run_task/deno.json
@@ -0,0 +1,5 @@
+{
+ "tasks": {
+ "main": "deno run main.ts"
+ }
+}
diff --git a/tests/specs/run/run_task/main.out b/tests/specs/run/run_task/main.out
new file mode 100644
index 000000000..f946c4a79
--- /dev/null
+++ b/tests/specs/run/run_task/main.out
@@ -0,0 +1,2 @@
+Task main deno run main.ts
+main
diff --git a/tests/specs/run/run_task/main.ts b/tests/specs/run/run_task/main.ts
new file mode 100644
index 000000000..6c2ee34f3
--- /dev/null
+++ b/tests/specs/run/run_task/main.ts
@@ -0,0 +1 @@
+console.log("main");
diff --git a/tests/specs/run/run_task/not_found.out b/tests/specs/run/run_task/not_found.out
new file mode 100644
index 000000000..5d3bba059
--- /dev/null
+++ b/tests/specs/run/run_task/not_found.out
@@ -0,0 +1 @@
+error: Module not found "file:///[WILDCARD]/not_found".