I have an @Option
with an enum java.util.List
and picocli just does not accept candidates that the ${COMPLETION-CANDIDATES}
shows.
The way how picocli
shows and accepts values does not align with each other.
Code:
@CommandLine.Option(
names = {"-c", "--columns-to-hide"},
description = "Comma separated list of column names that won't be displayed"
+ "%nCandidates: ${COMPLETION-CANDIDATES}",
split = ",")
final List<Header> columnsToHide = new ArrayList<>();
Rendered help:
-c, --columns-to-hide Comma separated list of column names that won't be displayed
Candidates: PORTFOLIO, TICKER, TYPE, CREATED, VOLUME, PRICE, FEE, TRANSFER_ID
The following error appears when I try to use multiply candidates as it was shown in the help:
Command:
java -jar my.jar ... -i "PORTFOLIO, TICKER, TYPE"
Error:
Invalid value for option '--columns-to-hide' (<columnsToHide>): expected one of [PORTFOLIO, TICKER, TYPE, CREATED, VOLUME, PRICE, FEE, TRANSFER_ID] (case-sensitive) but was ' TICKER'
The issue is that the rendered help shows a comma + space
separated list but the picocli parser only accepts a comma separated list without space.
This is accepted:
-i "PORTFOLIO,TICKER,TYPE"
This one shows an error:
-i "PORTFOLIO, TICKER, TYPE"
My requirement is to accept candidate list with AND without space as well and this bug confuses my users.
As a workaround, I can use a String as a type instead of List and split + trim
the provided String but this makes my code not as elegant as it can be without this bug. Plus I need to check whether or not the provided list contains only valid enum values.
Have you ever faced this bug?
Can I instruct picocli somehow to use the value from thesplit
when it renders the options?
Solution: Custom Type Converters
public class HeaderConverter implements CommandLine.ITypeConverter<List<Header>> {
@Override
public List<Header> convert(String s) throws Exception {
List<Header> headers = new ArrayList<>();
var params = s.split(",");
Arrays.stream(params).forEach(x -> headers.add(Header.valueOf(x.trim())));
return headers;
}
}
This works fine, but that would be great if picocli could show candidates properly, based on the split
parameter.