diff --git a/src/main/java/picocli/CommandLine.java b/src/main/java/picocli/CommandLine.java index 4371bcc05..5740b83f7 100644 --- a/src/main/java/picocli/CommandLine.java +++ b/src/main/java/picocli/CommandLine.java @@ -498,6 +498,34 @@ public static T populateCommand(T command, String... args) { return command; } + /** + *

+ * Convenience method that derives the command specification from the specified interface class, and returns an + * instance of the specified interface. The interface is expected to have annotated getter methods. Picocli will + * instantiate the interface and the getter methods will return the option and positional parameter values matched on the command line. + *

+ * This is equivalent to + *

+     * CommandLine cli = new CommandLine(spec);
+     * cli.parse(args);
+     * return cli.getCommand();
+     * 
+ * + * @param spec the interface that defines the command specification. This object contains getter methods annotated with + * {@code @Option} or {@code @Parameters}. + * @param args the command line arguments to parse + * @param the type of the annotated object + * @return an instance of the specified annotated interface + * @throws InitializationException if the specified command object does not have a {@link Command}, {@link Option} or {@link Parameters} annotation + * @throws ParameterException if the specified command line arguments are invalid + * @since 3.1 + */ + public static T populateSpec(Class spec, String... args) { + CommandLine cli = toCommandLine(spec, new DefaultFactory()); + cli.parse(args); + return cli.getCommand(); + } + /** Parses the specified command line arguments and returns a list of {@code CommandLine} objects representing the * top-level command and any subcommands (if any) that were recognized and initialized during the parsing process. *

diff --git a/src/test/java/picocli/CommandLineAnnotatedMethodImplTest.java b/src/test/java/picocli/CommandLineAnnotatedMethodImplTest.java index 879cd343b..8e48a88b6 100644 --- a/src/test/java/picocli/CommandLineAnnotatedMethodImplTest.java +++ b/src/test/java/picocli/CommandLineAnnotatedMethodImplTest.java @@ -83,10 +83,10 @@ static class Objects { @Option(names = "-string") void setString(String val) { aString = val; } @Option(names = "-list") void setList(List val) { aList = val; } - @Option(names = "-map", type = {Integer.class, Double.class}) + @Option(names = "-map") void setMap(Map val) { aMap = val; } - @Option(names = "-set", type = Short.class) + @Option(names = "-set") void setSortedSet(SortedSet val) { aSet = val; } } diff --git a/src/test/java/picocli/CommandLineAnnotatedMethodSpecTest.java b/src/test/java/picocli/CommandLineAnnotatedMethodSpecTest.java index 581ff5efc..fee84f7a0 100644 --- a/src/test/java/picocli/CommandLineAnnotatedMethodSpecTest.java +++ b/src/test/java/picocli/CommandLineAnnotatedMethodSpecTest.java @@ -107,10 +107,10 @@ interface Objects { @Option(names = "-list") List getList(); - @Option(names = "-map", type = {Integer.class, Double.class}) + @Option(names = "-map") Map getMap(); - @Option(names = "-set", type = Short.class) + @Option(names = "-set") SortedSet getSortedSet(); } @@ -189,4 +189,26 @@ public void testAnnotatedMutableFieldsOnInterfaceAreValid() { assertEquals("Invalid picocli annotation on interface field", ok.getMessage()); } } + + @Test + public void testPopulateSpec() { + Objects objects = CommandLine.populateSpec(Objects.class, "-b -y1 -s2 -i3 -l4 -f5 -d6 -bigint=7 -string abc -list a -list b -map 1=2.0 -set 33 -set 22".split(" ")); + assertTrue(objects.aBoolean()); + assertEquals(Byte.valueOf((byte) 1), objects.aByte()); + assertEquals(Short.valueOf((short) 2), objects.aShort()); + assertEquals(Integer.valueOf(3), objects.anInt()); + assertEquals(Long.valueOf(4), objects.aLong()); + assertEquals(5f, objects.aFloat(), 0.0001); + assertEquals(6d, objects.aDouble(), 0.0001); + assertEquals(BigInteger.valueOf(7), objects.aBigInteger()); + assertEquals("abc", objects.aString()); + assertEquals(Arrays.asList("a", "b"), objects.getList()); + Map map = new HashMap(); + map.put(1, 2.0); + assertEquals(map, objects.getMap()); + Set set = new TreeSet(); + set.add((short) 22); + set.add((short) 33); + assertEquals(set, objects.getSortedSet()); + } }