diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index 59073c60..42632ff9 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -355,11 +355,26 @@ private void validateOptions() { } if (mainParameterDescription != null) { + // Make sure we have a main parameter if it was required if (mainParameterDescription.getParameter().required() && !mainParameterDescription.isAssigned()) { throw new ParameterException("Main parameters are required (\"" + mainParameterDescription.getDescription() + "\")"); } + + // If the main parameter has an arity, make sure the correct number of parameters was passed + int arity = mainParameterDescription.getParameter().arity(); + if (arity != Parameter.DEFAULT_ARITY) { + Object value = mainParameterDescription.getParameterized().get(mainParameterObject); + if (List.class.isAssignableFrom(value.getClass())) { + int size = ((List) value).size(); + if (size != arity) { + throw new ParameterException("There should be exactly " + arity + " main parameters but " + + size + " were found"); + } + } + + } } } diff --git a/src/main/java/com/beust/jcommander/Parameter.java b/src/main/java/com/beust/jcommander/Parameter.java index 2fc00c5c..5944d92f 100644 --- a/src/main/java/com/beust/jcommander/Parameter.java +++ b/src/main/java/com/beust/jcommander/Parameter.java @@ -60,7 +60,8 @@ * How many parameter values this parameter will consume. For example, * an arity of 2 will allow "-pair value1 value2". */ - int arity() default -1; + public static int DEFAULT_ARITY = -1; + int arity() default DEFAULT_ARITY; /** * If true, this parameter is a password and it will be prompted on the console diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index e967ef7b..1b981763 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -33,6 +33,9 @@ import java.io.*; import java.math.BigDecimal; import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; @@ -1518,16 +1521,58 @@ class Args { Assert.assertEquals(args.f, false); } + @Test + public void mainParameterWithCorrectArity() { + class Args { + @Parameter(arity = 2) + private List main; + } + + Args args = new Args(); + JCommander.newBuilder() + .addObject(args) + .args(new String[]{"a", "b"}) + .build(); + Assert.assertEquals(args.main.size(), 2); + Assert.assertEquals(args.main.get(0), "a"); + Assert.assertEquals(args.main.get(1), "b"); + } + + @Test(expectedExceptions = ParameterException.class) + public void mainParameterWithWrongArity() { + class Args { + @Parameter(arity = 2) + private List main; + } + + Args args = new Args(); + JCommander.newBuilder() + .addObject(args) + .args(new String[]{"a"}) + .build(); + } + @Test(enabled = false) public static void main(String[] args) { - CommandTemplate template = new CommandTemplate(); - JCommander jcommander = new JCommander(template); - jcommander.setProgramName("prog"); - jcommander.parse("help"); + class FileValidator implements IParameterValidator { + @Override + public void validate(String name, String value) throws ParameterException { + if (!Files.exists(Paths.get(value))) { + throw new ParameterException("FILE_DOES_NOT_EXIST"); + } + } + } - if (template.help) { - jcommander.usage(); + class Args { + @Parameter(names = "--file", validateWith = FileValidator.class, required = true, + description = "The properties file containing setup information.") + private Path propertiesFile = Paths.get(""); } + + JCommander.newBuilder() + .addObject(new Args()) + .build() + .parse("--file", "README.markdown"); } }