nvm icon indicating copy to clipboard operation
nvm copied to clipboard

"help" intercepts commands run by exec and run

Open cseitz opened this issue 2 years ago • 9 comments

Command

# Run node --help with the specified version
nvm exec lts/hydrogen node --help

What happened?

NVM outputs its help command.

What did you expect to happen?

I expected the --help flag to be passed to node

Potential Solution

I understand why the help command takes precedense since its useful for just plopping it at the end of a command to get help on said command. However, this really ruins any situations where one might be using nvm exec as a replacement to node, effectively making it a pain to run anything else's help command.

My primary usage is to use nvm behind-the-scenes as an environment manager, so any time someone specifies "help" in my use-case, it is intended for node, npm, or whatever the command they are running is and not NVM. The user would never be running nvm directly, but rather a custom CLI that passes args through NVM when necessary to run them at the correct version without updating the default NVM version that's in use elsewhere on the user's machine.

Thus, I propose NVM_NO_HELP=1.

...
  # nvm.sh, line 2820
  case $i in
    --) break ;;
    '-h'|'help'|'--help')
    NVM_NO_COLORS=""
+   if [[ "$NVM_NO_HELP" -eq 1 ]]; then
+     break;
+   fi
    for j in "$@"; do
...

This flag, if specified, will instruct NVM to not respond to help requests.

I'm not very skilled with bash so I imagine there's a better solution out there; but the code snippet above works on my local installation of nvm and lets me bypass the help command.

NVM_NO_HELP=1 nvm exec lts/hydrogen node --help
# correctly outputs node v18's help command!

Conclusion

Please let me know if you think this is something that is worth fixing in future versions of NVM. It would certainly help my use-case and allow me to avoid modifying nvm.sh just to escape help commands.

Thanks.

cseitz avatar Jun 06 '23 17:06 cseitz

The solution here is to use -- to tell nvm to stop processing dashed commands, which is a universal shell convention.

ljharb avatar Jun 06 '23 17:06 ljharb

(In the future you may want to hold off on a PR until you're sure the maintainer is interested)

ljharb avatar Jun 06 '23 17:06 ljharb

Oh, thank you! I tried adding -- but apparently I did it in the wrong place thus lead me down this path.

nvm exec lts/hydrogen -- node --help

Good to know this is already implemented. Thanks!

Is this something we should add to the docs?

cseitz avatar Jun 06 '23 17:06 cseitz

Sure, let's update your PR to change the docs instead :-) It should be able to appear anywhere.

ljharb avatar Jun 06 '23 17:06 ljharb

# ❌ - shows NVM help
nvm -- exec lts/hydrogen node --help
# ❌ - error in nvm-exec line 15
nvm exec -- lts/hydrogen node --help
# ✅ - works perfectly
nvm exec lts/hydrogen -- node --help
# ❌ - nodejs: module not found "--help"
nvm exec lts/hydrogen node -- --help

My initial attempt was the 4th one, but this results in Node.js MODULE_NOT_FOUND: cannot find module '--help'

cseitz avatar Jun 06 '23 17:06 cseitz

it certainly has to go after exec lts/hydrogen, but the last one should certainly work - I'd consider that a bug.

ljharb avatar Jun 06 '23 21:06 ljharb

For interest, an alternative approach is to have run and exec pass through following arguments (including options). I got used to this convenience with docker:

% docker run ubuntu ls --help
Usage: ls [OPTION]... [FILE]...
List information about the FILEs (the current directory by default).
Sort entries alphabetically if none of -cftuvSUX nor --sort is specified.
...

n follows this pattern:

% n exec hydrogen node --version
v18.16.1

shadowspawn avatar Jul 16 '23 11:07 shadowspawn

@shadowspawn i worry that would cause problems if there's nvm-specific options passed to run and exec.

I certainly think that anything that's not used by nvm should be passed through, though.

ljharb avatar Aug 05 '23 06:08 ljharb

Given that nvm exec lts/hydrogen -- node --help works, i think it actually does make sense to not remove a -- inside the executed command - iow, there's no guarantee it's node, and the -- could be meaningful. I'm not sure there's anything to do here except perhaps update the docs?

ljharb avatar Aug 05 '23 06:08 ljharb