npm / cmd-shim

The cmd-shim used in npm
ISC License
76 stars 40 forks source link

[BUG] No way to shim a non-Node.js file #152

Open nex3 opened 3 months ago

nex3 commented 3 months ago

Is there an existing issue for this?

Current Behavior

The current shim behavior mostly works in a cross-platform way if the script you're providing is intended to run in Node.js specifically, because it's guaranteed that node.exe will be installed in the user's path on Windows. But it completely falls apart if you want to run anything else, such as a shell script (which can be very useful as a way to efficiently call out to another executable, for example).

I'm filing this as a bug because it's clearly the intention for the shim generation to support multiple different execution environments, since it has all this logic for sniffing the shebang. But that logic doesn't actually work. Let's say I have a shell script that starts with #!/bin/sh. Here's (the relevant part of) the shim that will be generate for Windows:

IF EXIST "%dp0%\/bin/bash.exe" (
  SET "_prog=%dp0%\/bin/bash.exe"
) ELSE (
  SET "_prog=/bin/bash"
  SET PATHEXT=%PATHEXT:;.JS;=;%
)

The first branch doesn't help because Bash isn't installed along with Node, and the second branch doesn't help either since Bash isn't going to be installed on the vast majority of Windows machines (and certainly won't be installed in /bin!).

Expected Behavior

Provide some way of supporting cross-platform executables that doesn't require spinning up a node.exe process. One easy option would be to detect the existence of $executable.cmd or $executable.ps1 scripts in the bin folder and call out to those; another would be to extend the package.json "bin" syntax to allow it to explicitly specify per-OS entrypoints.

Steps To Reproduce

  1. Create a package with "bin": "script", where script is:

    #!/bin/bash
    echo hello
  2. Run npm install -g . on Windows and observe that there's no way for shim to work correctly

Environment

N/A, based on reading code