npm / npx

npm package executor

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[BUG] npx runs executables in path instead of wanted package [Windows/Linux]

distante opened this issue · comments

Reproducible with node 14.15.4 installed in a windows 10 machine.

Current Behavior

If an executable exist in the path with the name of the wanted script it overrides npx command.

Steps to Reproduce

  1. Create a file named cli.bat with whatever in a directory that exists on your path.
  2. Run npx @capacitor/cli

Expected Behavior

@capacitor/cli output should be visible

What happens

cli.bat gets executed.

Same or similar issue with node v12.16.3, npm 6.14.11 running on Ubuntu 18.04

Running npx @betterer/cli produces the output:

Usage is: mono [options] program [program-options]

Development:
    --aot[=<options>]      Compiles the assembly to native code
    --debug[=<options>]    Enable debugging support, use --help-debug for details
    --debugger-agent=options Enable the debugger agent
    --profile[=profiler]   Runs in profiling mode with the specified profiler module
    --trace[=EXPR]         Enable tracing, use --help-trace for details
    --jitmap               Output a jit method map to /tmp/perf-PID.map
    --help-devel           Shows more options available to developers

Runtime:
    --config FILE          Loads FILE as the Mono config
    --verbose, -v          Increases the verbosity level
    --help, -h             Show usage information
    --version, -V          Show version information
    --runtime=VERSION      Use the VERSION runtime, instead of autodetecting
    --optimize=OPT         Turns on or off a specific optimization
                           Use --list-opt to get a list of optimizations
    --security[=mode]      Turns on the unsupported security manager (off by default)
                           mode is one of cas, core-clr, verifiable or validil
    --attach=OPTIONS       Pass OPTIONS to the attach agent in the runtime.
                           Currently the only supported option is 'disable'.
    --llvm, --nollvm       Controls whenever the runtime uses LLVM to compile code.
    --gc=[sgen,boehm]      Select SGen or Boehm GC (runs mono or mono-sgen)

Running the cli command (/usr/bin/cli) produces the exact same output

I changed the title to add Linux.

Try npx with npm 7 - if you’re still having issues there, please file an issue in the cli issue. npm 6 as well as this repo are effectively not receiving any more updates.

I'm not sure if this is an issue, I thought it was the expected behavior. That being said, it took Mac users of apply off-guard, since apply is an existing tool on that OS. npx apply tried to use the native apply utility instead of downloading apply from NPM, which was a real bummer.

Related issue: preset/preset#65

The workaround is to use --ignore-existing. Would be nice if it was actually a bug that is not intended, because requiring users to install apply or use npx apply --ignore-existing (without even a short flag) kind of ruins the beauty of that command.

I don’t think there’s a reasonable way to distinguish between a builtin and a globally installed binary, so i think it’s just incumbent in authors to pick binary names that don’t already exist :-/

Yeah, that's unfortunate. I think it's possible to distinguish them though, and I don't really see the use case for wanting npx to trigger other commands.

--ignore-existing does ignore $PATH and the current node_modules/.bin. A good default, in my opinion, would be to ignore $PATH and look into any $PATH that contains node_modules/.bin.

That would cover local installs, but wouldn't cover global installs, which could be in any location (depending on where the user configured npm root -g, where they installed node, or what --prefix they specified when running npm install -g).

My bad, I didn't explain well. I meant that that npx could look for paths in $PATH that contain node_modules/.bin, in addition to the node_modules/.bin in the current working directory. That would cover the --prefix as well, unless I misunderstood what it does.

with nvm, global binaries are in $NVM_DIR/versions/node/v14.15.5/lib/node_modules. With the typical node install, they're in /usr/local or something. It's only local installs that have node_modules or .bin in them.

Ah, I see. I thought they'd always be in this directory relative to the installation path. That said, NPM is aware of which packages are installed globally, right? With that knowledge, it could determine the paths to their binaries?

No, it’s not necessarily aware of that - /usr/local contains all the system binaries.

Hm, I'm confused then. If it's not aware of where it installs packages and their binaries, how does it uninstall them?

That’s a good question :-) it’s aware via various configs, but since some of those can be supplied at the time of the command (which means uninstall would require them too) then npx would require the same invocation args to find everything.

Either way, i think that it’s just a normal consequence of choosing a binary name that conflicts with a builtin one on some systems. “apply”, like any other builtin Mac command, is something I’d suggest is off limits as a binary name.

You're right that the name of the binary should be considered wisely. I just wasn't aware of that behavior from npx, which is unfortunate. :/

Still, if I understood correctly, what you said means that it's possible for npx to determine if the supplied package/binary name is something that has been installed... right?

Though while I do think it'd be a better default, that'd also be a breaking change, and I can't see that being implemented soon.