Skip to content

Commit

Permalink
Add showHelpIfErrors() to HelpOption (#53)
Browse files Browse the repository at this point in the history
Adds the showHelpIfErrors() method to HelpOption so a parsed command
with errors can access its HelpOption and call showHelpIfErrors().  If
there were errors then it goes ahead and shows the help (and optionally
the errors).
  • Loading branch information
rvesse committed Dec 1, 2016
1 parent 4ba810e commit e9e816c
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
import com.github.rvesse.airline.model.CommandGroupMetadata;
import com.github.rvesse.airline.model.CommandMetadata;
import com.github.rvesse.airline.model.GlobalMetadata;
import com.github.rvesse.airline.parser.ParseResult;
import com.github.rvesse.airline.parser.errors.ParseException;

/**
* An option that provides a simple way for the user to request help with a
Expand Down Expand Up @@ -74,6 +76,67 @@ public boolean showHelpIfRequested(CommandUsageGenerator generator) {
return help;
}

/**
* Shows help if any parsing errors were detected. If errors were detected
* the error messages are printed prior to the help
*
* @param result
* Parsing result, if {@code null} then this method does nothing
*/
public <T> boolean showHelpIfErrors(ParseResult<T> result) {
return showHelpIfErrors(result, true);
}

/**
* Shows help if any parsing errors were detected
*
* @param result
* Parsing result, if {@code null} then this method does nothing
* @param printErrors
* Whether to print error messages prior to the help, set to
* {@code false} if your code has already done that
*/
public <T> boolean showHelpIfErrors(ParseResult<T> result, boolean printErrors) {
return showHelpIfErrors(result, printErrors, new CliCommandUsageGenerator());
}

/**
* Shows help if any parsing errors were detected
*
* @param result
* Parsing result, if {@code null} then this method does nothing
* @param printErrors
* Whether to print error messages prior to the help, set to
* {@code false} if your code has already done that
* @param generator
* Command generator for printing the help
* @return True if help was shown, false otherwise
*/
public <T> boolean showHelpIfErrors(ParseResult<T> result, boolean printErrors, CommandUsageGenerator generator) {
// Ignore if no parsing result to check
if (result == null)
return false;

if (!result.wasSuccessful()) {
// Some errors
if (printErrors) {
// Print the errors if requested
System.err.println(String.format("%d parse errors were encountered:", result.getErrors().size()));
for (ParseException e : result.getErrors()) {
System.err.print(" -");
System.err.println(e.getMessage());
}
}

showHelp(generator);
shown = true;
return true;
}

// No errors so no need to show help
return false;
}

/**
* Shows help using the default {@link CliCommandUsageGenerator}
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,12 @@ public Collection<ParseException> getErrors() {

/**
* Gets the command if one was successfully parsed
* <p>
* Note that a command may have been parsed even when errors have been
* detected and handled by the error handler. Therefore you should check
* {@link #wasSuccessful()} and act accordingly before assuming that it is
* safe to run the parsed command.
* </p>
*
* @return Command, or {@code null} if no command was parsed
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,17 @@ public class FailAll extends AbstractCollectingHandler {
public <T> ParseResult<T> finished(ParseState<T> state) {
Collection<ParseException> errors = getCollection();
if (errors.size() == 1) {
// Single error handled, throw as-is
throw errors.iterator().next();
} else if (errors.size() > 1) {
ParseException aggEx = new ParseException("Parsing encountered %d error(s)", errors.size());
// Multiple errors handled, throw aggregation noting suppressed errors
ParseException aggEx = new ParseException("Parsing encountered %d errors, see suppressed errors for details", errors.size());
for (ParseException e : errors) {
aggEx.addSuppressed(e);
}
throw aggEx;
} else {
// Can only reach here if there were no errors handled i.e. no errors!
return new ParseResult<>(state, null);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public void handleError(ParseException e) {

@Override
public <T> ParseResult<T> finished(ParseState<T> state) {
// Can only reach here if no errors handled so there were no errors
return new ParseResult<T>(state, null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,40 @@ public void errorHandlerCollectAll() {
.parseWithResult();
Assert.assertFalse(result.wasSuccessful());
Assert.assertEquals(result.getErrors().size(), 1);
Assert.assertNotNull(result.getCommand());
}

@Test
public void errorHandlerFailAll() {
try {
ParseResult<Strings> result = SingleCommand
.<Strings> singleCommand(Strings.class, this.<Strings> prepareParser(new FailAll()))
SingleCommand.<Strings> singleCommand(Strings.class, this.<Strings> prepareParser(new FailAll()))
.parseWithResult("--not-empty", "", "--not-blank", " ");
} catch (ParseException e) {
Assert.assertEquals(e.getSuppressed().length, 2);
}
}

@Test
public void errorHandlerCollectAllHelp01() {
ParseResult<Strings> result = SingleCommand.<Strings> singleCommand(Strings.class, this.<Strings> prepareParser(new CollectAll()))
.parseWithResult("--not-empty", "", "--not-blank", " ");
Assert.assertFalse(result.wasSuccessful());
Assert.assertEquals(result.getErrors().size(), 2);
Assert.assertNotNull(result.getCommand());

Strings cmd = result.getCommand();
Assert.assertTrue(cmd.helpOption.showHelpIfErrors(result));
}

@Test
public void errorHandlerCollectAllHelp02() {
ParseResult<Strings> result = SingleCommand.<Strings> singleCommand(Strings.class, this.<Strings> prepareParser(new CollectAll()))
.parseWithResult("--not-empty", "foo", "--not-blank", "non-blank");
Assert.assertTrue(result.wasSuccessful());
Assert.assertEquals(result.getErrors().size(), 0);
Assert.assertNotNull(result.getCommand());

Strings cmd = result.getCommand();
Assert.assertFalse(cmd.helpOption.showHelpIfErrors(result));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
*/
package com.github.rvesse.airline.restrictions;

import javax.inject.Inject;

import com.github.rvesse.airline.HelpOption;
import com.github.rvesse.airline.annotations.Command;
import com.github.rvesse.airline.annotations.Option;
import com.github.rvesse.airline.annotations.restrictions.MaxLength;
Expand Down Expand Up @@ -46,4 +49,7 @@ public class Strings {
@Pattern(pattern = "(\\+1-)?\\d{3}-\\d{3}-\\d{4}", description = "Must provide a telephone number in standard US format e.g. +1-800-123-4567")
public String tel;

@Inject
public HelpOption<Strings> helpOption = new HelpOption<>();

}

0 comments on commit e9e816c

Please sign in to comment.