Giter Site home page Giter Site logo

cmd-shim's Introduction

cmd-shim

The cmd-shim used in npm to create executable scripts on Windows, since symlinks are not suitable for this purpose there.

On Unix systems, you should use a symbolic link instead.

Build Status Dependency Status npm version

Installation

npm install cmd-shim

API

cmdShim(from, to) -> Promise

Create a cmd shim at to for the command line program at from. e.g.

var cmdShim = require('cmd-shim');
cmdShim(__dirname + '/cli.js', '/usr/bin/command-name').then(() => {
  // shims are created!
})

cmdShim.ifExists(from, to) -> Promise

The same as above, but will just continue if the file does not exist.

cmd-shim's People

Contributors

10xlacroixdrinker avatar basbossink avatar bwrrp avatar commanderroot avatar copenhas avatar danielruf avatar davhdavh avatar dependabot[bot] avatar dscho avatar exe-boss avatar forbeslindesay avatar fraxken avatar github-actions[bot] avatar igorklopov avatar isaacs avatar lukekarrys avatar nlf avatar rufman avatar satazor avatar staudenmayerc avatar thefourtheye avatar wraithgar avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cmd-shim's Issues

Having a file named node.js will be "run" instead of node

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.

[BUG] <Unable to install latest version>

Is there an existing issue for this?

  • I have searched the existing issues

Current Behavior

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

Expected Behavior

Successfully download the package

Steps To Reproduce

  1. In this environment...
  2. With this config...
  3. Run '...'
  4. See error...

Environment

  • npm:
  • Node:
  • OS:
  • platform:

Support cross-drive linking

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.

basedir incorrectly resolved on msysgit

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.

[FEATURE] Powershell - Windows - Handle node.exe not on path, but node existing similar to cmd shims

What / Why

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).

Current Behavior

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

Expected Behavior

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!

[BUG] *.CMD shims don't work when they are in paths containing shell metachars

What / Why

Generated *.CMD files are unable to start correctly when the path to the CMD file contains certain characters.

When

  • Whenever the path contains a cmd.exe shell metacharacter (such as &).

Where

  • Any package with a "bin" entry.

How

Current Behavior

  • The shell metacharacters are parsed by the shell instead of the full argument being passed into node. With my npm prefix set to "C:/test(n&pm)" and after installing the mkdirp package globally, I see the following error when attempting to run "mkdirp" in cmd.exe.
'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: []
}

Steps to Reproduce

  • Orchestrate any scenario in which the .CMD files will be generated under a path containing "&" character (in theory the other shell metacharacters would also be problematic, see references for an article on windows command line escaping).

Two scenarios come to mind.

Scenario 1: Set NPM Prefix to New Path

  1. Set npm prefix to "C:/test(n&pm)"
  2. Globally install mkdirp (or any other binary package).
  3. Make sure "C:/test(n&pm)" is in your PATH.
  4. Attempt to run "mkdirp" (or whatever you installed).

Scenario 2: Local Dependencies

  1. Create an npm package in a folder like "C:/test(n&pm)/package"
  2. Install a local dependency which has a "bin" entry (like "mkdirp")
  3. Add a script to package.json which attempts to run the dependency's bin (like "trymkdir": "mkdirp mytestfolder")
  4. Attempt to run your script: npm run trymkdir

Expected Behavior

  • The .CMD files should be able to run without getting tripped up by shell metacharacters in the path.

Who

  • n/a

References

Local node incorrectly resolved on Windows

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

[FEATURE] drop env's -S flag

What / Why

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

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.

Where

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.

How

Current Behavior

The -S flag in the shebang is interpreted as the name of the executable that the shim should run.

Expected Behavior

I expect the -S flag to be ignored, since skipping it and using only the remaining shebang works on windows (according to my experiments).

Who

  • n/a

References

[BUG] .cmd @echo off

Is there an existing issue for this?

  • I have searched the existing issues

Current Behavior

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%

Expected Behavior

normal exit, no change to current prompt setting.

Steps To Reproduce

  1. Start cmd prompt
  2. Run npm -v at the prompt
  3. appears to hang, echo on fixes

Environment

  • npm: 8.12.2
  • Node: v16.14.2
  • OS: Windows
  • platform: Microsoft Windows [Version 10.0.19044.1645]

Use the value of NODE_EXE rather than wherever node is found in PATH if available

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.

Syntax error on Windows

This issue seems to be related to #16, and possibly to the change introduced in #4 by @copenhas.

Description

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

Environments

OS:

  • Windows

Node/npm versions:

  • 5.10.1 / 2.8.3
  • 4.4.2 / 2.15.0
  • 0.12.13 / 2.15.0
  • 0.10.44 / 2.15.0

Notes

  • 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.

Add "@" to start of single line .cmd files.

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.

Reporting a vulnerability

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

[BUG] Reports invalid process.cwd()

Is there an existing issue for this?

  • I have searched the existing issues

Current Behavior

The working directory changed by cd after setlocal is not maintained.
So process.cwd() returns the wrong location.

Expected Behavior

The current directory after the cd command should be kept.

Steps To Reproduce

$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")

Environment

  • npm: 8.12.2
  • Node: v16.15.1
  • OS: Windows
  • platform:

Source

+ 'endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & '

[BUG] [ReOpening] Having a file named node.js will be "run" instead of node

Is there an existing issue for this?

  • I have searched the existing issues

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.

Current Behavior

  • As described in #40 the node.js file will be "run" by the OS instead of running the node executable located somewhere in path
  • After inspecting the output shim, it appears there was an attempt to fix this, but it does not work.

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" %*

Expected Behavior

  • Running whatever bin js file is supposed to run as it does when yarn correctly generates this shim.

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" %*
)

Steps To Reproduce

  1. npm install a package with a bin script
  2. create a file called node.js in the same directory as the package.json you will be running scripts from OR the directory you run the command directly from
  3. run the script via a script in package.json OR with npx
  4. notice the file opens and the script never runs

Environment

  • npm: 8.16.0
  • Node: 16.15.1
  • OS: Windows 10 Home 21H2 (19044.1826)
  • platform: Desktop

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.