Skip to content

Commit 7999357

Browse files
committed
Added detection of missing args to aggregated option support
1 parent 4aa5c28 commit 7999357

2 files changed

Lines changed: 37 additions & 19 deletions

File tree

de.tototec.cmdoption/src/main/java/de/tototec/cmdoption/CmdlineParser.java

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -345,13 +345,13 @@ public List<String> apply(final String arg) {
345345
validateOptions();
346346
}
347347

348-
// Should be set to false, if an stopOption was found and parsing of
349-
// options is no longer allowed
348+
// parseOptions - will be set to false, if an stopOption was found
349+
// when false, it means: parsing of options is no longer allowed
350350
boolean parseOptions = true;
351351
final String stopOption = "--";
352352

353-
// optionCount counts the occurrence for each option handle in the
354-
// cmdline
353+
// optionCount - counts the occurrence for each option handle in the
354+
// cmdline for later validation
355355
final Map<OptionHandle, Integer> optionCount = new LinkedHashMap<OptionHandle, Integer>();
356356
for (final OptionHandle option : options) {
357357
optionCount.put(option, 0);
@@ -360,6 +360,8 @@ public List<String> apply(final String arg) {
360360
optionCount.put(parameter, 0);
361361
}
362362

363+
// helpDetected - will be set to true, if we detect a help option while
364+
// parsing
363365
boolean helpDetected = false;
364366

365367
final String aggregatePrefix = aggregateShortOptionsWithPrefix.getOrElse(new F0<String>() {
@@ -411,7 +413,7 @@ public String apply() {
411413

412414
if (rest.length <= index + optionHandle.getArgsCount()) {
413415
final PreparedI18n msg = i18n.preparetr(
414-
"Missing arguments(s): {0}. Option \"{1}\" requires {2} arguments, but you gave {3}.",
416+
"Missing argument(s): {0}. Option \"{1}\" requires {2} arguments, but you gave {3}.",
415417
FList.mkString(
416418
Arrays.asList(optionHandle.getArgs()).subList(rest.length - index - 1,
417419
optionHandle.getArgsCount()),
@@ -473,8 +475,17 @@ public String apply() {
473475
if (oh == null) {
474476
// FIXME: unsupported aggregation found
475477
}
476-
if(rest.length < procCount + oh.getArgsCount()) {
478+
if (rest.length < procCount + oh.getArgsCount()) {
477479
// FIXME: missing args detected
480+
final PreparedI18n msg = i18n.preparetr(
481+
"Missing argument(s): {0}. Option \"{1}\" requires {2} arguments, but you gave {3}.",
482+
FList.mkString(
483+
Arrays.asList(oh.getArgs()).subList(rest.length - procCount,
484+
oh.getArgsCount()),
485+
", "),
486+
aggregatePrefix + c, oh.getArgsCount(),
487+
rest.length - procCount);
488+
throw new CmdlineParserException(msg.notr(), msg.tr());
478489
}
479490
// add as standalone short option
480491
rewritten.add(aggregatePrefix + c);
@@ -485,6 +496,7 @@ public String apply() {
485496
}
486497
}
487498
// re-interate parsing with the modified command line
499+
// (backtracking)
488500
final String[] newRest = Arrays.copyOfRange(rest, procCount, rest.length);
489501
rewritten.addAll(Arrays.asList(newRest));
490502
rest = rewritten.toArray(new String[0]);
@@ -592,7 +604,7 @@ public String apply() {
592604
if (optionC.getValue() > 0) {
593605
final OptionHandle calledOption = optionC.getKey();
594606
for (final String required : calledOption.getRequires()) {
595-
// check, of an option was called with that name, if
607+
// check, if an option was called with that name, if
596608
// not, this is an error
597609
final OptionHandle reqOptionHandle = quickOptionMap.get(required);
598610
if (reqOptionHandle == null) {
@@ -764,7 +776,8 @@ protected void validateOptions() {
764776
}
765777
}
766778
}
767-
// TODO: Ensure, there are no long options, starting with the aggregated short
779+
// TODO: Ensure, there are no long options, starting with the aggregated
780+
// short
768781
// option prefix, and when, disable this feature
769782
}
770783

@@ -936,16 +949,12 @@ protected List<OptionHandle> inspectElements(final Object object, final Set<Acce
936949
parameter.getElement(), element);
937950
throw new CmdlineParserException(msg.notr(), msg.tr());
938951
}
939-
// TODO: should we ignore the help parameter?
940-
final OptionHandle paramHandle = new OptionHandle(new String[] {}, anno.description(), handler,
941-
object, element, anno.args(), anno.minCount(), anno.maxCount(), false /*
942-
* cannot
943-
* be
944-
* a
945-
* help
946-
* option
947-
*/, anno.hidden(),
948-
anno.requires(), anno.conflictsWith());
952+
// TODO: should we ignore the help parameter? Currently we do!
953+
final OptionHandle paramHandle = new OptionHandle(
954+
new String[] {}, anno.description(), handler,
955+
object, element, anno.args(), anno.minCount(), anno.maxCount(),
956+
false /* cannot be a help option */,
957+
anno.hidden(), anno.requires(), anno.conflictsWith());
949958

950959
if (paramHandle.getArgsCount() <= 0) {
951960
final PreparedI18n msg = i18n.preparetr("Parameter definition must support at least on argument.");

de.tototec.cmdoption/src/test/java/de/tototec/cmdoption/AggregateShortOptionsTest.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public AggregateShortOptionsTest() {
3535
final Config config = new Config();
3636
final CmdlineParser cp = new CmdlineParser(config);
3737
cp.setAggregateShortOptionsWithPrefix(null);
38-
intercept(CmdlineParserException.class, "Unsupported option or parameter found: -ls", () -> {
38+
intercept(CmdlineParserException.class, "\\QUnsupported option or parameter found: -ls\\E", () -> {
3939
cp.parse(new String[] { "-ls" });
4040
});
4141
});
@@ -70,6 +70,15 @@ public AggregateShortOptionsTest() {
7070
expectEquals(config.file, "file.txt");
7171
});
7272

73+
test("Comnbining short options with missing args should fail", () -> {
74+
final Config config = new Config();
75+
final CmdlineParser cp = new CmdlineParser(config);
76+
cp.setAggregateShortOptionsWithPrefix("-");
77+
intercept(CmdlineParserException.class, "\\QMissing argument(s): FILE. Option \"-f\" requires 1 arguments, but you gave 0.\\E", () -> {
78+
cp.parse(new String[] { "-lfs" });
79+
});
80+
});
81+
7382

7483
}
7584

0 commit comments

Comments
 (0)