Skip to content

Node CLI eval option can't take unary negation operator #43397

Description

@k-tten

Version

v17.9.0

Platform

Darwin [redacted] 19.6.0 Darwin Kernel Version 19.6.0: Tue Feb 15 21:39:11 PST 2022; root:xnu-6153.141.59~1/RELEASE_X86_64 x86_64

Subsystem

No response

What steps will reproduce the bug?

Execute the following:

$ node -pe "-0"

And you will get back:

node: --eval requires an argument

In fact, anything where the - comes first, you get this message.

For example, all of the following also result in the above message:

$ node -pe "-42"
$ node -pe "-"
$ node -pe "-NaN"

How often does it reproduce? Is there a required condition?

It's always reproducable (at least on this version and machine).

What is the expected behavior?

I'd like it to not spit back an error message and give me the evaluated value, please.

What do you see instead?

An error message detailing that the "eval" option was not given a value.

Additional information

It seems that the CLI is not properly parsing its arguments?

Prefixing the expression with 0 seems to work:

$ node -pe "0-42"
42

As well as using a comma operator:

$ node -pe "(0, -42)"
-42

Activity

  1. bnoordhuis commented on Jun 13, 2022

    @bnoordhuis
    Member

    It seems that the CLI is not properly parsing its arguments?

    It's rather doing it too well! It parses -42 as a flag, not as a positional argument.

    I agree it's a bug but I pity whoever goes in to grapple with node's option parser. You're a braver person than I am.

  2. added
    cliIssues and PRs related to the Node.js command-line interface.
    on Jun 13, 2022
  3. LiviaMedeiros commented on Jun 13, 2022

    @LiviaMedeiros
    Member

    Before any brave soul goes on fixing this: we probably don't want node -pe "-something" to be interpreted as anything but node -pesomthing or node -p -e -s -o -m -e -t -h -i -n -g.

    I think, the proper command should look more like node -pe -- -42, where -- argument will mean that all further arguments are NOT options.

  4. bnoordhuis commented on Jun 14, 2022

    @bnoordhuis
    Member

    Can you explain your line of thought? Why should it be node -pesomthing or node -p -e -s -o -m -e -t -h -i -n -g?

  5. LiviaMedeiros commented on Jun 14, 2022

    @LiviaMedeiros
    Member

    My line of thought is based on:

    1. Obviously, we can't solve the issue "literally" by detecting numeric expressions
    2. Commonly, short options should allow stacking together (-ab == -a -b)
    3. Commonly, if short option requires argument, it should allow it without delimeter (-afoo == -a foo)
      Otherwise, short options should allow arbitrary order (-b -a == -a -b)
    4. Commonly, any argument starting with dash should be parsed as option (-a -foo -b == -a -f -o -o -b). If we need a positional argument starting (or potentially starting) with dash, we can use double dash separator (-a -b -- -foo).

    Thus said, this is how I'd like to expect parsing to work:

    • node -e42 should work the same as node -e 42, not "bad option"
      Otherwise, node -ep 42 might work the same as node -pe 42 as long as it's unambiguous
    • node -e --throw-deprecation [...] should never attempt to evaluate --throw-deprecation as js code

    node --help does mention -- which should indicate that following arguments are positional. However, neither node -e -- 42 or node -- "-dashfile.js" are available.

    For users who prefer setting mandatory option arguments rather than positional arguments, node --print --eval=-42 already works. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    cliIssues and PRs related to the Node.js command-line interface.confirmed-bugIssues and PRs for confirmed bugs.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions