Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"Error Expected one or zero arguments." when passing program arguments via "dub --single" without -- #2980

Open
VPanteleev-S7 opened this issue Dec 20, 2024 · 6 comments

Comments

@VPanteleev-S7
Copy link

VPanteleev-S7 commented Dec 20, 2024

System information

  • dub version: DUB version 1.33.0, built on Jan 1 1980
  • OS Platform and distribution: Nix
  • compiler version N/A

Bug Description

Dub seems to require -- to pass arguments to programs when invoked via --single. I.e., this works:

$ dub --single program.d -- my-argument

and this doesn't:

$ dub --single program.d my-argument

We should use Config.stopOnFirstNonOption or equivalent and pass everything after the program name to the program, without parsing it ourselves.

This will align Dub with most other tools that need to run other programs, such as GNU env, rdmd, dmd -run, and docker run (which uses containers instead of programs).

It will also allow using dub --single in shebang lines. Because the -- must come after the program name, it is not possible to specify it in the shebang line.

The only reason why we would want to require -- is for situations where the name of the program itself (!) could be parsed as an option, e.g. to run a file called -program.d. This also aligns with how many other programs (such as GNU coreutils) use the -- argument.

@s-ludwig
Copy link
Member

Note that there is already a special mode for shebang lines where you just run dub program.d my-argument (which also suppresses non-error build output). I'm not quite sure I like the conflation of dub and non-dub arguments that would arise here. You can easily run into ambiguities, for example what does dub --single program.d -v do?

@VPanteleev-S7
Copy link
Author

Note that there is already a special mode for shebang lines where you just run dub program.d my-argument (which also suppresses non-error build output).

Unfortunately that way of running programs via Dub is slightly more buggy: #2672

You can easily run into ambiguities, for example what does dub --single program.d -v do?

There are no ambiguities. -v comes after the program name, so it should be passed to the program.

I don't mean to be disrespectful, but that's what pretty much every other program out there is doing, while Dub is doing something else. I think you should have some of the above enumerated programs on your computer already and can verify that they all behave consistently with each other and inconsistently with Dub?

@s-ludwig
Copy link
Member

Unfortunately that way of running programs via Dub is slightly more buggy: #2672

Doesn't the bug affect the --single way of running the program?

There are no ambiguities. -v comes after the program name, so it should be passed to the program.

Right now it does the opposite, hence the ambiguity ;)

But seriously, this can easily break existing scripts in non-trivial ways (and I'm pretty sure I personally have some that will be broken, because I have something like -a $ARCH at the end of the command line).

I'd have to do some research, but I've definitely seen the -- approach more than once, too (nodejs and cargo should be among them if I remember right).

@VPanteleev-S7
Copy link
Author

Doesn't the bug affect the --single way of running the program?

Oops, you're right!

Right now it does the opposite, hence the ambiguity ;)

Yes, it would be a breaking change. I'm hoping we could still do this with a deprecation cycle...

I'd have to do some research, but I've definitely seen the -- approach more than once, too (nodejs and cargo should be among them if I remember right).

npx seems to do it like the above-mentioned tools.

Not sure about cargo for running arbitrary files or packages, but the -- does come into play when the program to run is implicit (i.e. it is the current package). I think that's a valid way to look at it (something like a placeholder for a package name).

@s-ludwig
Copy link
Member

This is what I mean: https://nodejs.org/api/cli.html#command-line-api
Doesn't npx work in yet another way? https://docs.npmjs.com/cli/v9/commands/npx?v=true
Cargo should be the same for running specific packages (--package): https://doc.rust-lang.org/cargo/commands/cargo-run.html

I don't know, there are clearly different ways in which this has been implemented in popular tools and the current way is clearly not that unusual.

@VPanteleev-S7
Copy link
Author

This is what I mean: https://nodejs.org/api/cli.html#command-line-api

$ cat test.js        
console.log(process.argv);

$ node test.js -v
[
  '/usr/bin/node',
  '/home/vladimir/tmp/2024-12-21-scratch/14:33:03/test.js',
  '-v'
]

It behaves like the tools I mentioned above.

Doesn't npx work in yet another way? https://docs.npmjs.com/cli/v9/commands/npx?v=true

No:

$ npx http-server -v  
v14.1.1

$ npx -v http-server     
10.9.0

Cargo should be the same for running specific packages (--package): https://doc.rust-lang.org/cargo/commands/cargo-run.html

I think Cargo's --package would be more of an equivalent to Dub's way of specifying subpackages.

Syntax-wise, for Cargo, the package name is an argument to the --package option. Dub doesn't even recognize the --single=package-name-here syntax. --single is a flag, and the program name is positional.

I don't know, there are clearly different ways in which this has been implemented in popular tools and the current way is clearly not that unusual.

Sorry, but I need to push back on this. I believe that you haven't looked at this closely enough.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants