-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: error when script-shell
is configured to a .bat
or .cmd
file
#7945
Conversation
// A .exe file to configure as the scriptShell option would be necessary to test | ||
// this behavior on Windows. Skip this test for now since compiling a custom | ||
// .exe would be quite involved and hard to maintain. | ||
skipOnWindows('pnpm run with custom shell', async () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we do want to support this test, I can compile a .exe
file to @pnpm.e2e/shell-mock
that matches the behavior of shell-mock.js
. Would that be useful, or overkill?
(I actually think we shouldn't do this since it's hard to audit .exe
files on CI and it would run locally for pnpm contributors using Windows.)
@@ -441,3 +443,14 @@ Run ${chalk.yellow('pnpm dedupe')} to apply the changes above. | |||
`, | |||
} | |||
} | |||
|
|||
function reportInvalidScriptShellWindowsError (_err: unknown): ErrorInfo { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_err
isn't used. Why declare it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Intention was to be explicit that the original error is unused and a new one with a more detailed explanation is created.
Happy to just remove the argument if you think that's clearer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, it's kinda subjective. I do personally think that not passing the error as function argument would communicate the intention of ignoring the error object in a more explicit manner.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Appreciate the thoughts nonetheless! I think I'm going to inline the hint
instead of throwing a generic error and adding pnpm-specific reporting afterward, which should remove the changes in the cli/default-reporter
package.
pnpm/exec/lifecycle/src/runLifecycleHook.ts
Lines 60 to 66 in 6d71b29
throw new PnpmError('ERR_PNPM_INVALID_SCRIPT_SHELL_WINDOWS', 'Cannot spawn .bat or .cmd as a script shell.', { | |
hint: `\ | |
The .npmrc script-shell option was configured to a .bat or .cmd file. These cannot be used as a script shell reliably. | |
Please unset the script-shell option, or configure it to a .exe instead. | |
`, | |
}) |
I originally didn't want to assume runLifecycleHook
's scriptShell
option was always configured from .npmrc
, but the changes in this PR can be a lot simpler under that assumption.
1ecde86
to
6d71b29
Compare
Problem
Configuring
script-shell
in.npmrc
on Windows to a.bat
or.cmd
file,will result in:
This previously worked, but changed after the Node.js security release on April 10th, 2024.
Prior Attempt
Yesterday, I attempted to update
@pnpm/npm-lifecycle
to support.bat
/.cmd
files, but this change was reverted after discovering behavior differences with arguments passed to these.bat
/.cmd
files.pnpm/npm-lifecycle#42
What does npm do?
As of version 10.5.0, npm doesn't handle
.cmd
files forscript-shell
either on Node.js 21.7.3.Proposal
Let's show an error if
.bat
/.cmd
files are set as thescript-shell
for now.I think there's several strong reasons for this:
To elaborate on the first point, I haven't found an easy way to support
.bat
/.cmd
files as shells on newer versions of Node.js without making.bat
or.cmd
files behave differently than.exe
files or shells on Linux or macOS. Arguments are parsed regardless ofspawn
,exec
,execFile
, orwindowsVerbatimArguments
options. I believe the correct behavior would involve manually escaping variables like%PATH%
so they're passed verbatim to thescript-shell
. The Rust team attempted to do something similar so arguments are passed verbatim, but their implementation was incorrect. I don't think we should try to do the same given that. From their blog post (emphasis mine):Changes
Here's a screenshot of the new error users will see under this unsupported configuration.