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

arg!(--long-arg "foo") doesn't behave in expected way #3586

Open
2 tasks done
petrochenkov opened this issue Mar 28, 2022 · 7 comments
Open
2 tasks done

arg!(--long-arg "foo") doesn't behave in expected way #3586

petrochenkov opened this issue Mar 28, 2022 · 7 comments
Labels
A-builder Area: Builder API C-bug Category: Updating dependencies S-waiting-on-design Status: Waiting on user-facing design to be resolved before implementing

Comments

@petrochenkov
Copy link

Please complete the following tasks

Rust Version

rustc 1.54.0

Clap Version

3.1.6

Minimal reproducible code

fn main() {
    let matches = Command::new("my_command").args(&[arg!(--long-option "Description")]).get_matches();
}

Steps to reproduce the bug with the above code

cargo run

Actual Behaviour

thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `Some("long")`,
 right: `None`: Short flags should precede long flags

Expected Behaviour

The code either builds an argument with long name --long-option, or errors at compile time.

Additional Context

The issue was found when migrating code from clap 2.

This is a footgun affecting naively ported code that cannot be detected until runtime.

Debug Output

No response

@petrochenkov petrochenkov added the C-bug Category: Updating dependencies label Mar 28, 2022
@epage epage added A-builder Area: Builder API S-waiting-on-design Status: Waiting on user-facing design to be resolved before implementing labels Mar 28, 2022
@epage
Copy link
Member

epage commented Mar 28, 2022

This seems to be a limitation of macro-rules that I couldn't find a way around. You need to quote the long option

fn main() {
    let matches = Command::new("my_command").args(&[arg!(--"long-option" "Description")]).get_matches();
}

@petrochenkov
Copy link
Author

I found the --"long-option" form later, but the fact that the --long-option form is silently accepted while being incorrect is still a problem.

@epage
Copy link
Member

epage commented Mar 28, 2022

but the fact that the --long-option form is silently accepted while being incorrect is still a problem.

which is why this issue is open but I'm not aware of any good solution.

Also, we have resigned ourselves in general to not being able to turn every error into a compile error but backstop with debug asserts. We encourage people to add a test that calls Command::debug_asserrt() to help catch issues earlier in the development process.

@evgeniy-terekhin
Copy link
Contributor

evgeniy-terekhin commented May 7, 2022

@epage I guess one solution could be to allow defining short and long flags only in one exact order (-f --flag)
But I guess this might and probably will break someone's code

@epage
Copy link
Member

epage commented May 8, 2022

@evgeniy-terekhin I think I'm missing something with your suggestion. We do only allow one order the problem is I didn't see a way to enforce that in macro rules without blowing up the number of cases we define and I didn't see a way for that to allow --foo-bar without quotes.

@evgeniy-terekhin
Copy link
Contributor

@epage well I duess I made this suggestion without giving it a proper thought.
Maybe converting this macro into a proc macro will enable better compile time errors.
I'll have to experiment on this a bit.

@epage
Copy link
Member

epage commented May 9, 2022

Maybe converting this macro into a proc macro will enable better compile time errors.
I'll have to experiment on this a bit.

Yes, my guess is that will be the only way forward for improving this macro. While that might seem counter to one of the reasons to use the builder API over the derive (macros hurt build times),. this macro could possibly have no dependencies like xflags

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-builder Area: Builder API C-bug Category: Updating dependencies S-waiting-on-design Status: Waiting on user-facing design to be resolved before implementing
Projects
None yet
Development

No branches or pull requests

3 participants