Move parsing of --help/-h to CmdLineParser

Make the handling of --help common across all uses of CmdLineParser.
This will eventually make it easier to support more complex parsing
cases that need to span objects.

Change-Id: I38b153035cfc5cce80ca631be66c8b4d4683590d
This commit is contained in:
Shawn O. Pearce
2012-04-04 15:11:42 -07:00
parent 7b825b3871
commit 2a9ced1f9e
3 changed files with 95 additions and 14 deletions

View File

@@ -34,9 +34,6 @@ public abstract class AbstractProgram {
@Option(name = "--show-stack-trace", usage = "display stack trace on failure")
protected boolean showStackTrace;
@Option(name = "--help", usage = "display this help text", aliases = {"-h"})
private boolean help;
private String getName() {
String n = getClass().getName();
int dot = n.lastIndexOf('.');
@@ -52,13 +49,13 @@ public abstract class AbstractProgram {
try {
clp.parseArgument(argv);
} catch (CmdLineException err) {
if (!help) {
if (!clp.wasHelpRequestedByOption()) {
System.err.println("fatal: " + err.getMessage());
return 1;
}
}
if (help) {
if (clp.wasHelpRequestedByOption()) {
final StringWriter msg = new StringWriter();
msg.write(getName());
clp.printSingleLineUsage(msg, null);

View File

@@ -60,9 +60,6 @@ public abstract class BaseCommand implements Command {
static final int STATUS_NOT_FOUND = PRIVATE_STATUS | 2;
public static final int STATUS_NOT_ADMIN = PRIVATE_STATUS | 3;
@Option(name = "--help", usage = "display this help text", aliases = {"-h"})
private boolean help;
@SuppressWarnings("unused")
@Option(name = "--", usage = "end of options", handler = EndOfOptionsHandler.class)
private boolean endOfOptions;
@@ -159,16 +156,16 @@ public abstract class BaseCommand implements Command {
try {
clp.parseArgument(argv);
} catch (IllegalArgumentException err) {
if (!help) {
if (!clp.wasHelpRequestedByOption()) {
throw new UnloggedFailure(1, "fatal: " + err.getMessage());
}
} catch (CmdLineException err) {
if (!help) {
if (!clp.wasHelpRequestedByOption()) {
throw new UnloggedFailure(1, "fatal: " + err.getMessage());
}
}
if (help) {
if (clp.wasHelpRequestedByOption()) {
final StringWriter msg = new StringWriter();
msg.write(commandName);
clp.printSingleLineUsage(msg, null);

View File

@@ -44,11 +44,14 @@ import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.IllegalAnnotationError;
import org.kohsuke.args4j.Option;
import org.kohsuke.args4j.OptionDef;
import org.kohsuke.args4j.spi.BooleanOptionHandler;
import org.kohsuke.args4j.spi.OptionHandler;
import org.kohsuke.args4j.spi.Setter;
import java.io.Writer;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;
/**
@@ -102,6 +105,10 @@ public class CmdLineParser {
parser.printUsage(out, rb);
}
public boolean wasHelpRequestedByOption() {
return parser.help.value;
}
public void parseArgument(final String... args) throws CmdLineException {
final ArrayList<String> tmp = new ArrayList<String>(args.length);
for (int argi = 0; argi < args.length; argi++) {
@@ -128,8 +135,13 @@ public class CmdLineParser {
}
private class MyParser extends org.kohsuke.args4j.CmdLineParser {
@SuppressWarnings("rawtypes")
private List<OptionHandler> options;
private HelpOption help;
MyParser(final Object bean) {
super(bean);
ensureOptionsInitialized();
}
@SuppressWarnings({"unchecked", "rawtypes"})
@@ -137,7 +149,7 @@ public class CmdLineParser {
protected OptionHandler createOptionHandler(final OptionDef option,
final Setter setter) {
if (isHandlerSpecified(option) || isEnum(setter) || isPrimitive(setter)) {
return super.createOptionHandler(option, setter);
return add(super.createOptionHandler(option, setter));
}
final Key<OptionHandlerFactory<?>> key =
@@ -145,12 +157,28 @@ public class CmdLineParser {
Injector i = injector;
while (i != null) {
if (i.getBindings().containsKey(key)) {
return i.getInstance(key).create(this, option, setter);
return add(i.getInstance(key).create(this, option, setter));
}
i = i.getParent();
}
return super.createOptionHandler(option, setter);
return add(super.createOptionHandler(option, setter));
}
@SuppressWarnings("rawtypes")
private OptionHandler add(OptionHandler handler) {
ensureOptionsInitialized();
options.add(handler);
return handler;
}
@SuppressWarnings("rawtypes")
private void ensureOptionsInitialized() {
if (options == null) {
help = new HelpOption();
options = new ArrayList<OptionHandler>();
addOption(help, help);
}
}
private boolean isHandlerSpecified(final OptionDef option) {
@@ -165,4 +193,63 @@ public class CmdLineParser {
return setter.getType().isPrimitive();
}
}
private static class HelpOption implements Option, Setter<Boolean> {
private boolean value;
@Override
public String name() {
return "--help";
}
@Override
public String[] aliases() {
return new String[] {"-h"};
}
@Override
public String usage() {
return "display this help text";
}
@Override
public void addValue(Boolean val) {
value = val;
}
@Override
public Class<? extends OptionHandler<Boolean>> handler() {
return BooleanOptionHandler.class;
}
@Override
public String metaVar() {
return "";
}
@Override
public boolean multiValued() {
return false;
}
@Override
public boolean required() {
return false;
}
@Override
public Class<? extends Annotation> annotationType() {
return Option.class;
}
@Override
public Class<Boolean> getType() {
return Boolean.class;
}
@Override
public boolean isMultiValued() {
return multiValued();
}
}
}