summaryrefslogtreecommitdiff
path: root/cli/tools/task.rs
diff options
context:
space:
mode:
authorDavid Sherret <dsherret@users.noreply.github.com>2024-04-20 20:13:46 -0400
committerGitHub <noreply@github.com>2024-04-20 20:13:46 -0400
commit695f314a913da3aa691381341385cbc1ef71b503 (patch)
tree4abec8c3b8a783630071e4897768a9f8037d72a1 /cli/tools/task.rs
parente55087f57af657069090f63517ec776d8958e410 (diff)
feat(task): support running npm binary commands in deno.json (#23478)
npm binary commands like `vite` from a `node_modules/.bin` folder will now execute when defined in a deno.json Closes https://github.com/denoland/deno/issues/23477
Diffstat (limited to 'cli/tools/task.rs')
-rw-r--r--cli/tools/task.rs101
1 files changed, 64 insertions, 37 deletions
diff --git a/cli/tools/task.rs b/cli/tools/task.rs
index 5eefda73f..4d14117d8 100644
--- a/cli/tools/task.rs
+++ b/cli/tools/task.rs
@@ -48,6 +48,8 @@ pub async fn execute_script(
return Ok(1);
}
};
+ let npm_resolver = factory.npm_resolver().await?;
+ let node_resolver = factory.node_resolver().await?;
if let Some(
deno_config::Task::Definition(script)
@@ -66,20 +68,20 @@ pub async fn execute_script(
Some(path) => canonicalize_path(&PathBuf::from(path))?,
None => config_file_path.parent().unwrap().to_owned(),
};
- let script = get_script_with_args(script, cli_options);
- output_task(task_name, &script);
- let seq_list = deno_task_shell::parser::parse(&script)
- .with_context(|| format!("Error parsing script '{task_name}'."))?;
- let env_vars = collect_env_vars();
- let local = LocalSet::new();
- let future =
- deno_task_shell::execute(seq_list, env_vars, &cwd, Default::default());
- let exit_code = local.run_until(future).await;
- Ok(exit_code)
+
+ let npm_commands =
+ resolve_npm_commands(npm_resolver.as_ref(), node_resolver)?;
+ run_task(
+ task_name,
+ script,
+ &cwd,
+ cli_options,
+ npm_commands,
+ npm_resolver.as_ref(),
+ )
+ .await
} else if package_json_scripts.contains_key(task_name) {
let package_json_deps_provider = factory.package_json_deps_provider();
- let npm_resolver = factory.npm_resolver().await?;
- let node_resolver = factory.node_resolver().await?;
if let Some(package_deps) = package_json_deps_provider.deps() {
for (key, value) in package_deps {
@@ -122,30 +124,19 @@ pub async fn execute_script(
task_name.clone(),
format!("post{}", task_name),
];
+ let npm_commands =
+ resolve_npm_commands(npm_resolver.as_ref(), node_resolver)?;
for task_name in task_names {
if let Some(script) = package_json_scripts.get(&task_name) {
- let script = get_script_with_args(script, cli_options);
- output_task(&task_name, &script);
- let seq_list = deno_task_shell::parser::parse(&script)
- .with_context(|| format!("Error parsing script '{task_name}'."))?;
- let npx_commands = match npm_resolver.as_inner() {
- InnerCliNpmResolverRef::Managed(npm_resolver) => {
- resolve_npm_commands(npm_resolver, node_resolver)?
- }
- InnerCliNpmResolverRef::Byonm(npm_resolver) => {
- let node_modules_dir =
- npm_resolver.root_node_modules_path().unwrap();
- resolve_npm_commands_from_bin_dir(node_modules_dir)?
- }
- };
- let env_vars = match npm_resolver.root_node_modules_path() {
- Some(dir_path) => collect_env_vars_with_node_modules_dir(dir_path),
- None => collect_env_vars(),
- };
- let local = LocalSet::new();
- let future =
- deno_task_shell::execute(seq_list, env_vars, &cwd, npx_commands);
- let exit_code = local.run_until(future).await;
+ let exit_code = run_task(
+ &task_name,
+ script,
+ &cwd,
+ cli_options,
+ npm_commands.clone(),
+ npm_resolver.as_ref(),
+ )
+ .await?;
if exit_code > 0 {
return Ok(exit_code);
}
@@ -160,6 +151,27 @@ pub async fn execute_script(
}
}
+async fn run_task(
+ task_name: &str,
+ script: &str,
+ cwd: &Path,
+ cli_options: &CliOptions,
+ npm_commands: HashMap<String, Rc<dyn ShellCommand>>,
+ npm_resolver: &dyn CliNpmResolver,
+) -> Result<i32, AnyError> {
+ let script = get_script_with_args(script, cli_options);
+ output_task(task_name, &script);
+ let seq_list = deno_task_shell::parser::parse(&script)
+ .with_context(|| format!("Error parsing script '{}'.", task_name))?;
+ let env_vars = match npm_resolver.root_node_modules_path() {
+ Some(dir_path) => collect_env_vars_with_node_modules_dir(dir_path),
+ None => collect_env_vars(),
+ };
+ let local = LocalSet::new();
+ let future = deno_task_shell::execute(seq_list, env_vars, cwd, npm_commands);
+ Ok(local.run_until(future).await)
+}
+
fn get_script_with_args(script: &str, options: &CliOptions) -> String {
let additional_args = options
.argv()
@@ -358,9 +370,24 @@ impl ShellCommand for NodeModulesFileRunCommand {
}
}
+fn resolve_npm_commands(
+ npm_resolver: &dyn CliNpmResolver,
+ node_resolver: &NodeResolver,
+) -> Result<HashMap<String, Rc<dyn ShellCommand>>, AnyError> {
+ match npm_resolver.as_inner() {
+ InnerCliNpmResolverRef::Byonm(npm_resolver) => {
+ let node_modules_dir = npm_resolver.root_node_modules_path().unwrap();
+ Ok(resolve_npm_commands_from_bin_dir(node_modules_dir))
+ }
+ InnerCliNpmResolverRef::Managed(npm_resolver) => {
+ resolve_managed_npm_commands(npm_resolver, node_resolver)
+ }
+ }
+}
+
fn resolve_npm_commands_from_bin_dir(
node_modules_dir: &Path,
-) -> Result<HashMap<String, Rc<dyn ShellCommand>>, AnyError> {
+) -> HashMap<String, Rc<dyn ShellCommand>> {
let mut result = HashMap::<String, Rc<dyn ShellCommand>>::new();
let bin_dir = node_modules_dir.join(".bin");
log::debug!("Resolving commands in '{}'.", bin_dir.display());
@@ -379,7 +406,7 @@ fn resolve_npm_commands_from_bin_dir(
log::debug!("Failed read_dir for '{}': {:#}", bin_dir.display(), err);
}
}
- Ok(result)
+ result
}
fn resolve_bin_dir_entry_command(
@@ -436,7 +463,7 @@ fn resolve_execution_path_from_npx_shim(
}
}
-fn resolve_npm_commands(
+fn resolve_managed_npm_commands(
npm_resolver: &ManagedCliNpmResolver,
node_resolver: &NodeResolver,
) -> Result<HashMap<String, Rc<dyn ShellCommand>>, AnyError> {