diff --git a/e2e/backend/test_npm_dep_warning_suppressed b/e2e/backend/test_npm_dep_warning_suppressed new file mode 100644 index 0000000000..996d58e117 --- /dev/null +++ b/e2e/backend/test_npm_dep_warning_suppressed @@ -0,0 +1,34 @@ +#!/usr/bin/env bash + +# Test that "npm may be required" warning is NOT shown when node is configured +# in the same mise.toml alongside an npm package (even if node isn't installed yet). +# Regression test for https://github.com/jdx/mise/discussions/8919 + +# Create a PATH that has mise but not npm/node +MISE_BIN="$(command -v mise)" +MISE_DIR="$(dirname "$MISE_BIN")" +export PATH="$MISE_DIR:/usr/bin:/bin:/usr/sbin:/sbin" + +# Verify npm is not on PATH — if it is, the restricted PATH isn't working +if command -v npm >/dev/null 2>&1; then + echo "ERROR: npm is found in restricted PATH, test cannot verify behavior" + exit 1 +fi + +# Create a mise.toml that has both node and an npm package +cat >mise.toml <<'EOF' +[tools] +node = "latest" +"npm:prettier" = "3" +EOF + +# Run ls-remote for the npm package — should NOT show the warning since node is configured +output=$(MISE_LOG_LEVEL=warn mise ls-remote npm:prettier 2>&1 || true) + +if [[ $output == *"npm may be required but was not found"* ]]; then + echo "FAIL: warning was shown even though node is configured in mise.toml" + echo "Output: $output" + exit 1 +fi + +echo "PASS: no spurious npm warning when node is configured" diff --git a/src/backend/cargo.rs b/src/backend/cargo.rs index 08474173e7..54063be403 100644 --- a/src/backend/cargo.rs +++ b/src/backend/cargo.rs @@ -86,6 +86,7 @@ impl Backend for CargoBackend { self.warn_if_dependency_missing( &ctx.config, "cargo", + &["rust", "cargo"], "To use cargo packages with mise, you need to install Rust first:\n\ mise use rust@latest\n\n\ Or install Rust via https://rustup.rs/", diff --git a/src/backend/dotnet.rs b/src/backend/dotnet.rs index f0052930e1..7a342c107d 100644 --- a/src/backend/dotnet.rs +++ b/src/backend/dotnet.rs @@ -79,6 +79,7 @@ impl Backend for DotnetBackend { self.warn_if_dependency_missing( &ctx.config, "dotnet", + &["dotnet"], "To use dotnet tools with mise, you need to install .NET SDK first:\n\ mise use dotnet@latest\n\n\ Or install .NET SDK via https://dotnet.microsoft.com/download", diff --git a/src/backend/gem.rs b/src/backend/gem.rs index c41cd93817..4701c3f98c 100644 --- a/src/backend/gem.rs +++ b/src/backend/gem.rs @@ -66,6 +66,7 @@ impl Backend for GemBackend { self.warn_if_dependency_missing( &ctx.config, "gem", + &["ruby", "gem"], "To use gem packages with mise, you need to install Ruby first:\n\ mise use ruby@latest", ) diff --git a/src/backend/go.rs b/src/backend/go.rs index 4abd01e2c8..73313f2acf 100644 --- a/src/backend/go.rs +++ b/src/backend/go.rs @@ -47,6 +47,7 @@ impl Backend for GoBackend { self.warn_if_dependency_missing( config, "go", + &["go"], "To use go packages with mise, you need to install Go first:\n\ mise use go@latest\n\n\ Or install Go via https://go.dev/dl/", @@ -112,6 +113,7 @@ impl Backend for GoBackend { self.warn_if_dependency_missing( &ctx.config, "go", + &["go"], "To use go packages with mise, you need to install Go first:\n\ mise use go@latest\n\n\ Or install Go via https://go.dev/dl/", diff --git a/src/backend/mod.rs b/src/backend/mod.rs index e1962343e0..3e5cd62af5 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -1335,12 +1335,15 @@ pub trait Backend: Debug + Send + Sync { } /// Check if a required dependency is available and show a warning if not. - /// This provides a consistent warning message format across all backends. - /// Changed to warning instead of error to avoid CI failures on Windows. + /// `provided_by` lists tool names that are known to provide the `program` binary + /// (e.g., "npm" is provided by &["node"]). If any of these tools are configured + /// in the toolset (even if not yet installed), the warning is suppressed since + /// mise will install them as dependencies first. async fn warn_if_dependency_missing( &self, config: &Arc, program: &str, + provided_by: &[&str], install_instructions: &str, ) { let found = if self.dependency_which(config, program).await.is_some() { @@ -1365,6 +1368,17 @@ pub trait Backend: Debug + Send + Sync { }; if !found { + // Check if a tool that provides this program is configured in the toolset + // (even if not yet installed). If so, mise will install it as a dependency + // before this tool needs it, so the warning is spurious. + if let Ok(ts) = self.dependency_toolset(config).await + && ts + .versions + .keys() + .any(|ba| provided_by.contains(&ba.short.as_str())) + { + return; + } warn!( "{} may be required but was not found.\n\n{}", program, install_instructions diff --git a/src/backend/npm.rs b/src/backend/npm.rs index e932adfc16..243e9fc63a 100644 --- a/src/backend/npm.rs +++ b/src/backend/npm.rs @@ -316,6 +316,7 @@ impl NPMBackend { self.warn_if_dependency_missing( config, "npm", // Use "npm" for dependency check, which will check npm.cmd on Windows + &["node", "npm"], "To use npm packages with mise, you need to install Node.js first:\n\ mise use node@latest\n\n\ Note: npm is required for querying package information, even when using bun for installation.", @@ -330,6 +331,7 @@ impl NPMBackend { self.warn_if_dependency_missing( config, "bun", + &["bun"], "To use npm packages with bun, you need to install bun first:\n\ mise use bun@latest\n\n\ Or switch back to npm by setting:\n\ @@ -341,6 +343,7 @@ impl NPMBackend { self.warn_if_dependency_missing( config, "pnpm", + &["pnpm"], "To use npm packages with pnpm, you need to install pnpm first:\n\ mise use pnpm@latest\n\n\ Or switch back to npm by setting:\n\ @@ -352,6 +355,7 @@ impl NPMBackend { self.warn_if_dependency_missing( config, "npm", + &["node", "npm"], "To use npm packages with mise, you need to install Node.js first:\n\ mise use node@latest\n\n\ Alternatively, you can use bun or pnpm instead of npm by setting:\n\ diff --git a/src/backend/pipx.rs b/src/backend/pipx.rs index f4bcc1bac2..d8b0766b8d 100644 --- a/src/backend/pipx.rs +++ b/src/backend/pipx.rs @@ -203,6 +203,7 @@ impl Backend for PIPXBackend { self.warn_if_dependency_missing( &ctx.config, "pipx", + &["pipx"], "To use pipx packages with mise, you need to install pipx first:\n\ mise use pipx@latest\n\n\ Alternatively, you can use uv/uvx by installing uv:\n\ diff --git a/src/backend/spm.rs b/src/backend/spm.rs index 757555773b..aa8a942f0d 100644 --- a/src/backend/spm.rs +++ b/src/backend/spm.rs @@ -87,6 +87,7 @@ impl Backend for SPMBackend { self.warn_if_dependency_missing( &ctx.config, "swift", + &["swift"], "To use Swift Package Manager (spm) tools with mise, you need to install Swift first:\n\ mise use swift@latest\n\n\ Or install Swift via https://swift.org/download/",