picocli icon indicating copy to clipboard operation
picocli copied to clipboard

PropertiesDefaultProvider: defaults for multi-value options and positional parameters

Open deining opened this issue 5 years ago • 1 comments

Hi,

I played around with the new PropertiesDefaultProvider implementation, I ended up with some code like:

package test;

import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.Parameters;
import picocli.CommandLine.PropertiesDefaultProvider;

public class PropertiesDefaultProviderTest {

    static {
        System.setProperty("picocli.defaults.mycmd.path", "Prop.properties");
    }
        
    public static void main(String[] args) {
        CommandLine cmd = new CommandLine(new MyCmd());
        cmd.setDefaultValueProvider(new PropertiesDefaultProvider());
        cmd.execute(args);
    }
}

@Command(name="mycmd")
class MyCmd implements Runnable {

    @Parameters(descriptionKey = "files")
    String[] params = { "myFile1", "myFile2" };

    @Override
    public void run() {
      for (String s : params)
        System.out.println(s);
        System.out.println(String.format("Number of files: %s", params.length));
    }
}

If I run this with an empty properties file, I'm getting:

myFile1
myFile2
Number of files: 2

Now I'm putting a minimal properties file in place:

files=file1 file2

Once the parameters are retrieved rom the properties file, the output now is:

file1 file2
Number of files: 1

Of course I can split up the string programmatically, but this is somehow inconvenient. I remember that when localizing the app, there is a very elegant way to specify multiple lines, like:

usage.description.0 = first line
usage.description.1 = second line
usage.description.2 = third line

Having that in mind, I tried:

files.0=file1
files.1=file2

This didn't do the trick, however.

Is this something that can be implemented? The proposed addition would make the new PropertiesDefaultProvider even better and more helpful IMHO.

deining avatar Nov 24 '19 01:11 deining

Yes, this can be done; PropertiesDefaultProvider could be modified to use the same logic as used for resource bundles.

That said, for picocli-4.1 the workaround is to use split on the option/positional parameter definition:

@Option(names = "-x", split = ",") List<String> xList;
@Parameters(          split = ",") List<String> positionals;

That allows end users to specify multiple values as default in the properties file. Of course, it also allows end users to specify multiple values on the command line with the split-separator (-x=1,2,3) in addition to separately (-x=1 -x=2 -x=3), and this may not be desirable...

Since there is a workaround, it is not high priority for me and it may take me a while to get around to it. Meanwhile, people who want to speed things up are welcome to contribute a PR with tests and documentation. ;-)

remkop avatar Nov 25 '19 03:11 remkop