From 263b6b971db60135e655914e7e33b8c26290a421 Mon Sep 17 00:00:00 2001 From: David Sherret Date: Wed, 8 May 2024 23:16:44 -0400 Subject: [PATCH] fix(task): regression where `npx ` sometimes couldn't find command (#23730) Closes https://github.com/denoland/deno/issues/23724 --- Cargo.lock | 4 +-- cli/Cargo.toml | 2 +- cli/tools/task.rs | 26 +++++++++++++++---- .../__test__.jsonc | 11 ++++++++ .../npx_installed_pkg_non_byonm/deno.jsonc | 7 +++++ .../task/npx_installed_pkg_non_byonm/main.out | 9 +++++++ .../npx_installed_pkg_non_byonm/package.json | 5 ++++ tests/testdata/task/npx/non_existent.out | 4 ++- 8 files changed, 59 insertions(+), 9 deletions(-) create mode 100644 tests/specs/task/npx_installed_pkg_non_byonm/__test__.jsonc create mode 100644 tests/specs/task/npx_installed_pkg_non_byonm/deno.jsonc create mode 100644 tests/specs/task/npx_installed_pkg_non_byonm/main.out create mode 100644 tests/specs/task/npx_installed_pkg_non_byonm/package.json diff --git a/Cargo.lock b/Cargo.lock index dd59fde101..1176afee70 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1876,9 +1876,9 @@ dependencies = [ [[package]] name = "deno_task_shell" -version = "0.16.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b44af10161906e1bccc1fc966f074bec0148997bb7e2221ecd29416dcad90b3" +checksum = "97e5ff66a1e89edb7ca0c36b73a8fcdc008ba426c4ad7a36e1dfb3f4a166179e" dependencies = [ "anyhow", "futures", diff --git a/cli/Cargo.toml b/cli/Cargo.toml index c33a1599bd..6d88c5614f 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -75,7 +75,7 @@ deno_lockfile.workspace = true deno_npm = "=0.18.0" deno_runtime = { workspace = true, features = ["include_js_files_for_snapshotting"] } deno_semver = "=0.5.4" -deno_task_shell = "=0.16.0" +deno_task_shell = "=0.16.1" deno_terminal.workspace = true eszip = "=0.68.2" napi_sym.workspace = true diff --git a/cli/tools/task.rs b/cli/tools/task.rs index 63c7f9a946..a1ee40973c 100644 --- a/cli/tools/task.rs +++ b/cli/tools/task.rs @@ -16,6 +16,7 @@ use deno_core::futures; use deno_core::futures::future::LocalBoxFuture; use deno_runtime::deno_node::NodeResolver; use deno_semver::package::PackageNv; +use deno_task_shell::ExecutableCommand; use deno_task_shell::ExecuteResult; use deno_task_shell::ShellCommand; use deno_task_shell::ShellCommandContext; @@ -236,7 +237,15 @@ fn prepend_to_path(env_vars: &mut HashMap, value: String) { fn collect_env_vars() -> HashMap { // get the starting env vars (the PWD env var will be set by deno_task_shell) - let mut env_vars = std::env::vars().collect::>(); + let mut env_vars = std::env::vars() + .map(|(k, v)| { + if cfg!(windows) { + (k.to_uppercase(), v) + } else { + (k, v) + } + }) + .collect::>(); const INIT_CWD_NAME: &str = "INIT_CWD"; if !env_vars.contains_key(INIT_CWD_NAME) { if let Ok(cwd) = std::env::current_dir() { @@ -318,10 +327,17 @@ impl ShellCommand for NpxCommand { }; command.execute(context) } else { - let _ = context - .stderr - .write_line(&format!("npx: could not resolve command '{first_arg}'")); - Box::pin(futures::future::ready(ExecuteResult::from_exit_code(1))) + // can't find the command, so fallback to running the real npx command + let npx_path = match context.resolve_command_path("npx") { + Ok(npx) => npx, + Err(err) => { + let _ = context.stderr.write_line(&format!("{}", err)); + return Box::pin(futures::future::ready( + ExecuteResult::from_exit_code(err.exit_code()), + )); + } + }; + ExecutableCommand::new("npx".to_string(), npx_path).execute(context) } } else { let _ = context.stderr.write_line("npx: missing command"); diff --git a/tests/specs/task/npx_installed_pkg_non_byonm/__test__.jsonc b/tests/specs/task/npx_installed_pkg_non_byonm/__test__.jsonc new file mode 100644 index 0000000000..ae9e640e64 --- /dev/null +++ b/tests/specs/task/npx_installed_pkg_non_byonm/__test__.jsonc @@ -0,0 +1,11 @@ +{ + "tempDir": true, + "steps": [{ + "commandName": "npm", + "args": "install", + "output": "[WILDCARD]" + }, { + "args": "task say", + "output": "main.out" + }] +} diff --git a/tests/specs/task/npx_installed_pkg_non_byonm/deno.jsonc b/tests/specs/task/npx_installed_pkg_non_byonm/deno.jsonc new file mode 100644 index 0000000000..00303820ba --- /dev/null +++ b/tests/specs/task/npx_installed_pkg_non_byonm/deno.jsonc @@ -0,0 +1,7 @@ +{ + // not byonm + "nodeModulesDir": true, + "tasks": { + "say": "npx cowsay moo" + } +} diff --git a/tests/specs/task/npx_installed_pkg_non_byonm/main.out b/tests/specs/task/npx_installed_pkg_non_byonm/main.out new file mode 100644 index 0000000000..db58009ce2 --- /dev/null +++ b/tests/specs/task/npx_installed_pkg_non_byonm/main.out @@ -0,0 +1,9 @@ +Task say npx cowsay moo + _____ +< moo > + ----- + \ ^__^ + \ (oo)\_______ + (__)\ )\/\ + ||----w | + || || diff --git a/tests/specs/task/npx_installed_pkg_non_byonm/package.json b/tests/specs/task/npx_installed_pkg_non_byonm/package.json new file mode 100644 index 0000000000..7a519e140a --- /dev/null +++ b/tests/specs/task/npx_installed_pkg_non_byonm/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "cowsay": "*" + } +} diff --git a/tests/testdata/task/npx/non_existent.out b/tests/testdata/task/npx/non_existent.out index 5df04917e6..37b0be2203 100644 --- a/tests/testdata/task/npx/non_existent.out +++ b/tests/testdata/task/npx/non_existent.out @@ -1,2 +1,4 @@ Task non-existent npx this-command-should-not-exist-for-you -npx: could not resolve command 'this-command-should-not-exist-for-you' +npm ERR! code E404 +npm ERR! 404 Not Found - GET http://localhost:4260/this-command-should-not-exist-for-you +[WILDCARD]