-
Notifications
You must be signed in to change notification settings - Fork 3.2k
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
[BUG] Passing CLI arguments via a Node scripts no longer works #7375
Comments
It seems like adding another argument delimiter ( i.e. running with |
same here, its broken! |
I'm also affected by this issue. It appears to be a shenanigan of both PowerShell and NPM working together. Node.js is not involved. A proof: package.json: {
"name": "cli-test",
"scripts": {
"showcli": "echo",
"showbatcli": "test.cmd"
}
} test.cmd: @echo %*
|
Digging more into this, the problem appears to be with OTOH, running the
|
Confirmed this does not fix the issue. |
Looking at Powershell docs it appears that there are different semantics to get it to stop argument parsing. Can you try At this point it might be a better idea for |
@lukekarrys, thanks for looking into this. On Windows, E.g.: package.json:
index.js: console.dir(process.argv); test.cmd: @echo %* With
Note that
Here is the correct wanted behavior (via explicit
On Linux,
|
@noseratio Thanks for the thorough reproductions and examples. I see how Tbh, I'm not sure how to get the same behavior of |
@lukekarrys, thank you and maybe the following could help. Besides traditional E.g.: ps-test.ps1: param (
[string]$firstArg
)
Write-Host "First Parameter: $firstArg"
Write-Host "Remaining Arguments: $args"
Write-Host "PSCommandPath: $PSCommandPath"
Write-Host "MyInvocation: $($MyInvocation | ConvertTo-Json)"
Write-Host "Process command line: $([System.Environment]::CommandLine)" Running it:
|
@lukekarrys, I've now invested more time into this and come up with a working fix, based on what I said above. Here is a complete version of #!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
$nodeexe = "node$exe"
$nodebin = $(Get-Command $nodeexe -ErrorAction SilentlyContinue -ErrorVariable F).Source
if ($nodebin -eq $null) {
Write-Host "$nodeexe not found."
exit 1
}
$nodedir = Split-Path $nodebin
$npmprefixjs="$nodedir/node_modules/npm/bin/npm-prefix.js"
$npmprefix=(& $nodeexe $npmprefixjs)
if ($LASTEXITCODE -ne 0) {
Write-Host "Could not determine Node.js install directory"
exit 1
}
$npmprefixclijs="$npmprefix/node_modules/npm/bin/npm-cli.js"
$npmparams = $MyInvocation.Statement.Substring($MyInvocation.InvocationName.Length).Trim()
$invokenpm = "$nodeexe $npmprefixclijs $npmparams"
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | Invoke-Expression $invokenpm
} else {
Invoke-Expression $invokenpm
}
$ret=$LASTEXITCODE
exit $ret The fix itself, in a nutshell: $npmparams = $MyInvocation.Statement.Substring($MyInvocation.InvocationName.Length).Trim()
$invokenpm = "$nodeexe $npmprefixclijs $npmparams"
# ...
Invoke-Expression $invokenpm I've also replaced: $nodedir = $(New-Object -ComObject Scripting.FileSystemObject).GetFile("$nodebin").ParentFolder.Path with: $nodedir = Split-Path $nodebin which produces the same result. I can't think of any benefits of using legacy, Windows-only COM objects nowadays, unless there is something really subtle? In which case, a cross-platform Please feel free to create a PR for this fix, as I don't have access rights to this repo. I understand it will have to make its way into a future Node.js release, to become a proper fix, and can't be fixed with just an NPM update. Still better than nothing, I recon 🙂 Thanks much! |
@lemire and I fixed the problem on |
My current take at patching |
Hi @lukekarrys, Mentioned workaround does not help: npm run test-local --TEST_ENV=ENV --tags=@tc Previous and expected behavior for Powershell: |
this came after i updated node & npm, not powershell. |
This sounds very much like the same problem as #3136. I posted a workaround that may help some people: #3136 (comment) |
We just upgraded from node 20 to node 22, and now we need |
I'm not sure if this is related to this issue, but I also can't seem to pass any additional arguments when running tests, like |
Nowadays, every time there is a new Node.js release on Windows which I just have installed (v23.1.0 at the time of writing), the next thing I do is to execute Where @echo off
cd /d "%~dp0"
fc /a npm.ps1 npm.ps1.orig >nul
if errorlevel 1 goto err
copy npm.ps1 npm.ps1.orig
copy npm.ps1.patch npm.ps1
exit /b 0
:err
echo Something has changed in npm.ps1, exiting without patching.
exit /b 1 And #!/usr/bin/env pwsh
$NODE_EXE="$PSScriptRoot/node.exe"
if (-not (Test-Path $NODE_EXE)) {
$NODE_EXE="$PSScriptRoot/node"
}
if (-not (Test-Path $NODE_EXE)) {
$NODE_EXE="node"
}
$NPM_PREFIX_JS="$PSScriptRoot/node_modules/npm/bin/npm-prefix.js"
$NPM_CLI_JS="$PSScriptRoot/node_modules/npm/bin/npm-cli.js"
$NPM_PREFIX=(& $NODE_EXE $NPM_PREFIX_JS)
if ($LASTEXITCODE -ne 0) {
Write-Host "Could not determine Node.js install directory"
exit 1
}
$NPM_PREFIX_NPM_CLI_JS="$NPM_PREFIX/node_modules/npm/bin/npm-cli.js"
if (Test-Path $NPM_PREFIX_NPM_CLI_JS) {
$NPM_CLI_JS=$NPM_PREFIX_NPM_CLI_JS
}
function Normalize {
[CmdletBinding()]
param(
[Parameter(Mandatory=$true, ValueFromPipeline=$true, Position=0)]
[string]$Path
)
$Path = [System.IO.Path]::GetFullPath($Path)
# remove trailing " or ' quotes (if any) and put back " quotes around the path
$Path = $Path -replace '^\s*"\s*(.*?)\s*"\s*$', '$1'
$Path = $Path -replace "^\s*'\s*(.*?)\s*'\s*$", "$1"
return """$Path"""
}
$NPM_ARGS = $MyInvocation.Statement.Substring($MyInvocation.InvocationName.Length).Trim()
$INVOKE_NPM = "& $(Normalize $NODE_EXE) $(Normalize $NPM_CLI_JS) $NPM_ARGS"
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | Invoke-Expression $INVOKE_NPM
} else {
Invoke-Expression $INVOKE_NPM
}
exit $LASTEXITCODE Solves the problem for local Windows development, but of course it is a nightmare for CI builds. I hope my proposed patch will be merged in one day 🙏 |
Any idea when it will be fixed ? PS C:\tmp\hello-ts> npm run tsc -- --init
PS C:\tmp\hello-ts> npm run tsc -- --version PS C:\tmp\hello-ts> npm --version |
Found solution: PS C:\tmp\hello-ts> npm run tsc "--" --version <<<<===== need to specify "--" instead of --
Version 5.6.3 |
Is there an existing issue for this?
This issue exists in the latest npm version
Current Behavior
With the following
index.js
NodeJS file in the root of a new clean NodeJS project:I get the following output when I run
node ./index.js -test-arg test-arg-value
:When I add an NPM script with:
and then run it with either of the following:
npm run arg-test -- -test-arg test-arg-value
,npm run arg-test -test-arg test-arg-value
,I simply get:
[ 'test-arg-value' ]
This leaves me unable to run CLI tools, such as Yargs, via NPM scripts like we used to be able to.
Expected Behavior
When using NPM to compose reusable scripts, CLI arguments should still be supported - which enables the use of CLI tools such as Yargs
Steps To Reproduce
index.js
file in the root of a new NodeJS project containing the following:index.js
:node ./index.js -test-arg test-arg-value
[ '-test-arg', 'test-arg-value' ]
package.json
file to run the file:package.json
:npm run arg-test -- -test-arg test-arg-value
,npm run arg-test -test-arg test-arg-value
,[ 'test-arg-value' ]
Notes:
"type": "module",
in thepackage.json
file.Environment
The text was updated successfully, but these errors were encountered: