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

picocli removes opening and closing quotes that are explicitly passed as an argument #514

Closed
mshatalov opened this issue Oct 12, 2018 · 3 comments
Labels
theme: parser An issue or change related to the parser type: API 🔌 type: enhancement ✨
Milestone

Comments

@mshatalov
Copy link

Looks like picocli always trims leading and trailing quotes of the arguments, even if they were passed explicitly.

Consider this sample class:

public class Options implements Runnable {
    @Parameters(description = "Search query")
    public String[] query;

    public static void main(String[] args) {
        System.out.println("Raw arguments");
        for (var a : args) {
            System.out.println(a);
        }
        CommandLine.run(new Options(), args);
    }

    @Override
    public void run() {
        System.out.println("\nParsed arguments");
        for (var q : query) {
            System.out.println(q);
        }
    }
}

Look at these sample arguments and actual result:

$ <cmd> "Exact query string" "\"Exact query string\"" '"Exact query string"' " \"Exact query string\""
Raw arguments
Exact query string
"Exact query string"
"Exact query string"
 "Exact query string"

Parsed arguments
Exact query string
Exact query string
Exact query string
 "Exact query string"

Expected result is that with such configuration raw arguments will all match the parsed arguments.

This becomes important when an app expects parameters where quotes are important, such as search query or search criteria. The workaround for me now is to include a space in the beginning or at the end of the argument, as illustrated in the last argument above.

This looks to be caused by trim() / unquote() implementation:

        private String trim(String value) {
            return unquote(value);
        }

        private String unquote(String value) {
            return value == null
                    ? null
                    : (value.length() > 1 && value.startsWith("\"") && value.endsWith("\""))
                        ? value.substring(1, value.length() - 1)
                        : value;
        }

Is there any historical context why the quotes are removed? Should we consider changing this behavior to pass through any quotes passed by the shell? If this is not desirable for certain reasons, how about an alternative solution with adding boolean raw() default false to Parameters and Option annotations and taking raw into account before trimming?

@remkop
Copy link
Owner

remkop commented Oct 12, 2018

I will make this configurable in the parser.
The default should probably be to leave the quotes alone, like you requested.

@remkop remkop added this to the 3.7 milestone Oct 12, 2018
remkop added a commit that referenced this issue Oct 20, 2018
…guments (configurable with `CommandLine::setTrimQuotes`)
@remkop
Copy link
Owner

remkop commented Oct 21, 2018

Fixed in master.
This will be in the upcoming 3.7 release.

@remkop remkop closed this as completed Oct 21, 2018
@remkop
Copy link
Owner

remkop commented Oct 23, 2018

Picocli 3.7 fixes this issue (and related issue #379 - quoted strings are no longer split by the split regex).

JCommander users may also be interested since apparently this is still an issue in the latest version of JCommander, based on cbeust/jcommander#458
(Related: cbeust/jcommander#153 )

@remkop remkop added the theme: parser An issue or change related to the parser label Apr 2, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
theme: parser An issue or change related to the parser type: API 🔌 type: enhancement ✨
Projects
None yet
Development

No branches or pull requests

2 participants