mirror of
https://github.com/denoland/deno.git
synced 2024-11-21 15:04:11 -05:00
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.
This commit is contained in:
parent
897159dc6e
commit
b3f1f3ba04
8 changed files with 60 additions and 5 deletions
32
cli/main.rs
32
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 {
|
||||
|
|
|
@ -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
|
||||
))));
|
||||
};
|
||||
|
|
|
@ -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(),
|
||||
|
|
13
tests/specs/run/run_task/__test__.jsonc
Normal file
13
tests/specs/run/run_task/__test__.jsonc
Normal file
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
5
tests/specs/run/run_task/deno.json
Normal file
5
tests/specs/run/run_task/deno.json
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"tasks": {
|
||||
"main": "deno run main.ts"
|
||||
}
|
||||
}
|
2
tests/specs/run/run_task/main.out
Normal file
2
tests/specs/run/run_task/main.out
Normal file
|
@ -0,0 +1,2 @@
|
|||
Task main deno run main.ts
|
||||
main
|
1
tests/specs/run/run_task/main.ts
Normal file
1
tests/specs/run/run_task/main.ts
Normal file
|
@ -0,0 +1 @@
|
|||
console.log("main");
|
1
tests/specs/run/run_task/not_found.out
Normal file
1
tests/specs/run/run_task/not_found.out
Normal file
|
@ -0,0 +1 @@
|
|||
error: Module not found "file:///[WILDCARD]/not_found".
|
Loading…
Reference in a new issue