npm / cmd-shim Goto Github PK
View Code? Open in Web Editor NEWThe cmd-shim used in npm
License: ISC License
The cmd-shim used in npm
License: ISC License
Unable to install latest version. Error as below:
npm ERR! 404 'cmd-shim@^5.0.0' is not in the npm registry.
npm ERR! 404 You should bug the author to publish it (or use the name yourself!)
Able to download previous version: i.e - 4.1.0
Trying to download package that has peer dependency on this package, so I'm blocked
Successfully download the package
I created a corresponding request at npm (issue 16210). Right now, the NODE_EXE is not exported so the subshell would not see it, but the cmd does not have that problem. You just need to check for NODE_EXE:
@IF EXIST "%~dp0\node.exe" (
"%~dp0\node.exe" "%~dp0\..\proj\bin\proj" %*
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.JS;=;%
@IF EXIST "%NODE_EXE%" (
"%NODE_EXE%" "%~dp0\..\proj\bin\proj" %*
) ELSE (
node "%~dp0\..\proj\bin\proj" %*
)
)
If the npm folks fix the aforementioned issue, then the subshell script could be just as easily modified. This simple fix would be of great value to me and my CI pipeline.
Disclaimer: I am not that experienced with cmd scripting
After updating to the latest npm, some of our scripts broke. I traced this to the change in #26, which always quotes the executable name (even if it is just node
). This seems to cause issues for some paths (The system cannot find the path specified.
)
Proposed fix (using tslint as an example):
@ECHO off
SETLOCAL
CALL :find_dp0
SET _maybeQuote="
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET _maybeQuote=
SET PATHEXT=%PATHEXT:;.JS;=;%
)
%_maybeQuote%%_prog%%_maybeQuote% "%dp0%\..\tslint\bin\tslint" %*
ENDLOCAL
EXIT /b %errorlevel%
:find_dp0
SET dp0=%~dp0
EXIT /b
For the %dp0% case, this resolves to
"%dp0%\node.exe" "%dp0%\..\tslint\bin\tslint" %*
otherwise, it resolves to
node "%dp0%\..\tslint\bin\tslint" %*
Effectively, we only use quotes around the node executable when we use .bin\node.exe
See https://npm.community/t/windows-10-npm-opens-vscode-instead-of-running-postinstall-script-on/9911
I have a file named node.js, which is the node version of the code (a browser.js is coming).
I have a postinstall script with #!/usr/bin/env node
The postinstall in the package.json is
{ "scripts": {
"postinstall": "node scripts/postinstall"
},
...
}
Instead of running the postinstall script with node.exe, it opens node.js in a text editor.
I'm working on a generic binary version manager. Everything works decently well, but I recently ran into trouble with how this package generates powershell shims expecting node.exe
on the path for Windows (in my case, only node.cmd
and node.ps1
exist on the path).
The cmd shim seems fine and it will fallback to using node
instead of node.exe
when node.exe
doesn't exist (you may categorize this difference between cmd and powershell as a bug).
Example of yarn's script:
#!/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
if (Test-Path "$basedir/node$exe") {
& "$basedir/node$exe" "$basedir/node_modules/yarn/bin/yarn.js" $args
$ret=$LASTEXITCODE
} else {
& "node$exe" "$basedir/node_modules/yarn/bin/yarn.js" $args
$ret=$LASTEXITCODE
}
exit $ret
It would do Test-Path for .exe
and if that doesn't exist, then it would fallback to not providing a .exe
file extension.
Thanks!
The existing issue was closed with the reason JS
shouldn't be in your pathext environment variable. While that is a solution, it is a completely invalid solution from my perspective.
It took me 2 hours of debugging to identify that was the problem, and in case you were unaware, that is the default in Windows. Though it certainly seems like you are aware given you attempt to remove it in the shim. Now that I know what it is, its an easy fix, but that's a terrible developer experience and needs fixing.
For reference, npms generated shim for rimraf:
@ECHO off
GOTO start
:find_dp0
SET dp0=%~dp0
EXIT /b
:start
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\rimraf\bin.js" %*
For reference, yarns generated shim for rimraf:
@IF EXIST "%~dp0\node.exe" (
"%~dp0\node.exe" "%~dp0\..\rimraf\bin.js" %*
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.JS;=;%
node "%~dp0\..\rimraf\bin.js" %*
)
When writing shims for node.js application entry-points it happens that we want to pass additional flags to node when starting. env
supports this via the -S
flag. For example, one of my projects has this shebang in its entry-point:
#!/usr/bin/env -S node --loader ts-node/esm --experimental-specifier-resolution=node --no-warnings
The flag -S
tells env
to split the following text on whitespace and treat the segments as args to the executable in the first segment after the -S
(i.e. node
), instead of interpreting the rest of the line as one long command.
This works without issue on *nix based systems (tested on manjaro, ubuntu, macOS).
When using this module to create the shim for a package with an entry-point whose shebang uses the -S
flag, the -S
flag is interpreted as the name of the executable to run. This makes the resulting shim unusable.
This is the absolute opposite of a minimal example, but the issue occurs in an ongoing PR here[1].
If needed I can build a small reproduction repository.
The -S
flag in the shebang is interpreted as the name of the executable that the shim should run.
I expect the -S
flag to be ignored, since skipping it and using only the remaining shebang works on windows (according to my experiments).
npm is creating single line ".cmd" files through this package that do not start with an "@", which causes the command it contains to be echoed to the console.
C:\>test a b c
C:\>"C:\Users\SkyLined\AppData\Roaming\npm\\node_modules\test\test.js" a b c
This is a test
C:\>
I've created a pull request to fix this.
this is similar to what is raised here (never resolved):
npm/npm#19681
At a Windows command prompt running npm -v
with npm@latest
seems to hang.
Typing echo on
brings back the prompt as described in the above bug.
This seems to contradict Microsoft documentation for @echo off, that remarks (to quote)
"If used in a batch file, echo on and echo off don't affect the setting at the command prompt."
I see this behaviour on Windows 10.
If I patch the npm.cmd
file like this, it behaves well:
@SETLOCAL
@FOR /f "tokens=1,2,3 delims=. " %%G IN ('ECHO') DO @SET _echo=%%I
@ECHO off
GOTO start
:find_dp0
SET dp0=%~dp0
EXIT /b
:start
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
ENDLOCAL & (CALL) || TITLE %COMSPEC% & "%_prog%" "%dp0%\node_modules\npm\bin\npm-cli.js" %* & ECHO %_echo%
normal exit, no change to current prompt setting.
npm -v
at the promptecho on
fixes#14 was a pretty important change, and there was still no new version released since that PR got merged.
Currently batch files are always written in UTF-8, which is problematic according to wiki.
Hello!
I hope you are doing well!
We are a security research team. Our tool automatically detected a vulnerability in this repository. We want to disclose it responsibly. GitHub has a feature called Private vulnerability reporting, which enables security research to privately disclose a vulnerability. Unfortunately, it is not enabled for this repository.
Can you enable it, so that we can report it?
Thanks in advance!
PS: you can read about how to enable private vulnerability reporting here: https://docs.github.com/en/code-security/security-advisories/repository-security-advisories/configuring-private-vulnerability-reporting-for-a-repository
Currently we cannot link a file to a different drive. E.g. cmdShim('C:\\a.js', 'D:\\a', () => {})
would generate files containg "$basedir/C:/a.js"
or "%~dp0\C:\a.js"
, which are broken due to the unresolvable paths.
In this case, we can use an absolute path instead, i.e. using "C:/a.js"
rather than "$basedir/C:/a.js"
.
If this is a valid use case, I'd like to work on it.
The version on npm depends on graceful-fs@2
, the version here depends on graceful-fs@^3.0.2
. An oversight?
The working directory changed by cd after setlocal is not maintained.
So process.cwd() returns the wrong location.
The current directory after the cd
command should be kept.
$HOME\AppData\Roaming\npm\aaaa.js :
console.log('CWD:', process.cwd());
$HOME\AppData\Roaming\npm\test.cmd :
@ECHO off
GOTO start
:find_dp0
SET dp0=%~dp0
EXIT /b
:start
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\aaaa.js" %*
test.bat:
setlocal
cd C:\abcdefg\
test.cmd
endlocal
Run test.bat
CWD: C:\Users...\ (Other directory instead of "C:\abcdefg")
Line 113 in 4660668
Try "jshint" --version
in cmd.exe, for instance. It won't work because it seems that cmd.exe doesn't set %~dp0
correctly when a batch script is quoted during invocation.
Currently any non-hashbang executable referenced by an npm "bin" will not work on Windows in Git Bash (MINGW) or Cygwin.
This issue is that for "short commands" without a hashbang, $basedir
is neglected but, in fact, we still need to have $basedir set in either case.
See https://npm.community/t/globally-installed-package-does-not-execute-in-git-bash-on-windows/9394
Hi
I recently upgraded node from v0.12.4 to v5.10.0 (which comes with [email protected] which comes with [email protected]), installed jspm (but it can be any node module) globally and got:
$ jspm init
module.js:341
throw err;
^
Error: Cannot find module 'C:\Program Files\Git\node_modules\jspm\jspm.js'
at Function.Module._resolveFilename (module.js:339:15)
at Function.Module._load (module.js:290:25)
at Function.Module.runMain (module.js:447:10)
at startup (node.js:146:18)
at node.js:404:3
Path C:\Program Files\Git\node_modules\jspm\jspm.js
is incorrect as in my case it should be C:\.tools\nodejs\node_modules\jspm\jspm.js
. I found that it can be resolved by reverting change introduced by #4 (/cc @copenhas):
#!/bin/sh
-basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
+basedir=`dirname "$0"`
case `uname` in
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/node_modules/jspm/jspm.js" "$@"
ret=$?
else
node "$basedir/node_modules/jspm/jspm.js" "$@"
ret=$?
fi
I'm having the same issue on 2 machines with similar setup: Windows 10 and Git Bash which comes with Git for Windows 2.8.1 (https://chocolatey.org/packages/git).
As a workaround I found that invoking jspm.cmd init
works as it should.
Generated
*.CMD
files are unable to start correctly when the path to theCMD
file contains certain characters.
&
).'pm)\' is not recognized as an internal or external command,
operable program or batch file.
internal/modules/cjs/loader.js:969
throw err;
^
Error: Cannot find module 'C:\test(n\node_modules\mkdirp\bin\cmd.js'
�[90m at Function.Module._resolveFilename (internal/modules/cjs/loader.js:966:17)�[39m
�[90m at Function.Module._load (internal/modules/cjs/loader.js:859:27)�[39m
�[90m at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)�[39m
�[90m at internal/main/run_main_module.js:17:47�[39m {
code: �[32m'MODULE_NOT_FOUND'�[39m,
requireStack: []
}
Two scenarios come to mind.
"trymkdir": "mkdirp mytestfolder"
)npm run trymkdir
This issue seems to be related to #16, and possibly to the change introduced in #4 by @copenhas.
Running Windows builds on AppVeyor with MinGW and MSYS. When executing test commands of the sort,
/c/projects/foo/node_modules/.bin/istanbul cover \
--no-default-excludes \
-x 'node_modules/**' \
-x 'build/**' \
-x '**/test/**' \
-x '**/tests/**' \
-x 'reports/**' \
--dir /c/projects/foo/reports/coverage \
--report lcov \
/c/projects/foo/node_modules/.bin/tape -- /c/projects/foo/test/test.js /c/projects/foo/test/test.a.js
I encounter the following error
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
^^^^^^^
SyntaxError: missing ) after argument list
at exports.runInThisContext (vm.js:53:16)
at Module._compile (module.js:387:25)
at Object.Module._extensions..js (module.js:422:10)
at Object.Module._extensions.(anonymous function) [as .js] (c:\projects\foo\node_modules\istanbul\lib\hook.js:109:37)
at Module.load (module.js:357:32)
at Function.Module._load (module.js:314:12)
at Function.Module.runMain (module.js:447:10)
at runFn (c:\projects\foo\node_modules\istanbul\lib\command\common\run-with-cover.js:122:16)
at c:\projects\foo\node_modules\istanbul\lib\command\common\run-with-cover.js:251:17
at c:\projects\foo\node_modules\istanbul\lib\util\file-matcher.js:68:16
make[1]: *** [test-istanbul] Error 1
make[1]: Leaving directory `/c/projects/foo'
make: *** [test-cov] Error 2
OS:
Node/npm versions:
I am able to run other commands, such as
/c/projects/foo/node_modules/.bin/tape /c/projects/foo/test/test.js /c/projects/foo/test/test.a.js
I tried to track down where this line
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
occurs in source code. The only place I found was in this dependency, which includes it at line 135 when creating the Windows shim.
I am not able to test whether reverting the line in question fixes the problem, as I do not have access to a Windows machine.
Note that the commands in question run without error on both Mac OS X and Linux Ubuntu, so this is a Windows specific error.
Similar bugs:
Note that the above issues have all been filed post release of v2.0.2
which included #4.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.