jcommander icon indicating copy to clipboard operation
jcommander copied to clipboard

Impossible to pass values containing spaces using an @file

Open rschmitt opened this issue 6 months ago • 4 comments

Since https://github.com/cbeust/jcommander/pull/533, it has apparently been impossible to use an @file to pass a single string value argument that contains spaces. I tried four different ways of doing it, and none of them work:

-groups
a b c
-groups a b c
-groups
"a b c"
-groups "a b c"

Looking at the @file parsing code, which unconditionally splits each line on \s+, it seems like this is impossible now. What's especially strange is that this seems to break TestNG's own Ant integration, which uses Ant suite and Ant test as the default suite and test names, respectively.

rschmitt avatar May 31 '25 02:05 rschmitt

Related to this discussion: https://github.com/cbeust/jcommander/pull/533#issuecomment-1020184616.

Feel confident to provide a PR?

mkarg avatar May 31 '25 10:05 mkarg

My preferred solution would be to revert https://github.com/cbeust/jcommander/issues/532 altogether. The simplest way for at-files to work is for line n to map to argv[n-1], and the whole "split lines on whitespace" thing seems like a hole that I don't care to dig any deeper.

rschmitt avatar May 31 '25 17:05 rschmitt

We will definitively not remove existing features, as in particular the intuitive readability introduced by #532 is intended. If you want to pass in whitespace, you need to come up with a solution proposal which does that but keeps the possibility to have parameter name and value on the same line.

mkarg avatar Jun 01 '25 11:06 mkarg

We will definitively not remove existing features,

But you've already removed an existing feature: you've removed the ability to pass argument values containing spaces in an argfile. I'm reporting a regression, not requesting a new feature.

the intuitive readability introduced by https://github.com/cbeust/jcommander/issues/532 is intended.

The point of this feature is not human readability, it's to provide support for command line invocations that exceed the ARG_MAX limit. This is probably why TestNG's Ant integration uses it: classpaths frequently blow the ARG_MAX limit, which is why javac and java have both added argfile support.

If you want to pass in whitespace, you need to come up with a solution proposal which does that but keeps the possibility to have parameter name and value on the same line.

That's still a breaking change. The way the code is written today, it's possible to pass the entire invocation in a single line:

    @Test
    public void atFileCanContainTheEntireInvocation() throws IOException {
        File f = File.createTempFile("JCommander", null);
        f.deleteOnExit();
        FileWriter fw = new FileWriter(f);
        fw.write("-verbose 2 -groups g\n");
        fw.close();
        Args1 args1 = new Args1();
        JCommander.newBuilder().addObject(args1).build().parse("@" + f.getAbsolutePath());
        Assert.assertEquals(args1.verbose.intValue(), 2);
        Assert.assertEquals(args1.groups, "g");
    }

Now what?

rschmitt avatar Jun 01 '25 18:06 rschmitt

You still are very welcome to provide a fix, as long as it does not remove the support for #532.

mkarg avatar Jun 05 '25 10:06 mkarg