Move command line parsing to BaseCommand
The parsing is optional, and must be explicitly invoked by the implementor in order to have the injection of values occur. Signed-off-by: Shawn O. Pearce <sop@google.com>
This commit is contained in:
@@ -20,7 +20,6 @@ import com.google.gerrit.client.reviewdb.AccountGroup;
|
|||||||
import com.google.gerrit.client.reviewdb.ApprovalCategory;
|
import com.google.gerrit.client.reviewdb.ApprovalCategory;
|
||||||
import com.google.gerrit.client.reviewdb.ReviewDb;
|
import com.google.gerrit.client.reviewdb.ReviewDb;
|
||||||
import com.google.gerrit.client.rpc.Common;
|
import com.google.gerrit.client.rpc.Common;
|
||||||
import com.google.gerrit.pgm.CmdLineParser;
|
|
||||||
import com.google.gerrit.server.BaseServiceImplementation;
|
import com.google.gerrit.server.BaseServiceImplementation;
|
||||||
import com.google.gerrit.server.GerritServer;
|
import com.google.gerrit.server.GerritServer;
|
||||||
import com.google.gerrit.server.IdentifiedUser;
|
import com.google.gerrit.server.IdentifiedUser;
|
||||||
@@ -29,20 +28,12 @@ import com.google.gwtorm.client.OrmException;
|
|||||||
import com.google.gwtorm.client.SchemaFactory;
|
import com.google.gwtorm.client.SchemaFactory;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
|
|
||||||
import org.apache.sshd.common.SshException;
|
|
||||||
import org.kohsuke.args4j.CmdLineException;
|
|
||||||
import org.kohsuke.args4j.Option;
|
|
||||||
|
|
||||||
import java.io.BufferedWriter;
|
import java.io.BufferedWriter;
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.OutputStreamWriter;
|
import java.io.OutputStreamWriter;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.io.StringWriter;
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public abstract class AbstractCommand extends BaseCommand {
|
public abstract class AbstractCommand extends BaseCommand {
|
||||||
@@ -65,9 +56,6 @@ public abstract class AbstractCommand extends BaseCommand {
|
|||||||
|
|
||||||
private Set<AccountGroup.Id> userGroups;
|
private Set<AccountGroup.Id> userGroups;
|
||||||
|
|
||||||
@Option(name = "--help", usage = "display this help text", aliases = {"-h"})
|
|
||||||
private boolean help;
|
|
||||||
|
|
||||||
protected PrintWriter toPrintWriter(final OutputStream o)
|
protected PrintWriter toPrintWriter(final OutputStream o)
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
return new PrintWriter(new BufferedWriter(new OutputStreamWriter(o, ENC)));
|
return new PrintWriter(new BufferedWriter(new OutputStreamWriter(o, ENC)));
|
||||||
@@ -119,68 +107,12 @@ public abstract class AbstractCommand extends BaseCommand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseArguments() throws Failure {
|
|
||||||
final List<String> list = new ArrayList<String>();
|
|
||||||
boolean inquote = false;
|
|
||||||
StringBuilder r = new StringBuilder();
|
|
||||||
for (int ip = 0; ip < commandLine.length();) {
|
|
||||||
final char b = commandLine.charAt(ip++);
|
|
||||||
switch (b) {
|
|
||||||
case '\t':
|
|
||||||
case ' ':
|
|
||||||
if (inquote)
|
|
||||||
r.append(b);
|
|
||||||
else if (r.length() > 0) {
|
|
||||||
list.add(r.toString());
|
|
||||||
r = new StringBuilder();
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
case '\'':
|
|
||||||
inquote = !inquote;
|
|
||||||
continue;
|
|
||||||
case '\\':
|
|
||||||
if (inquote || ip == commandLine.length())
|
|
||||||
r.append(b); // literal within a quote
|
|
||||||
else
|
|
||||||
r.append(commandLine.charAt(ip++));
|
|
||||||
continue;
|
|
||||||
default:
|
|
||||||
r.append(b);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (r.length() > 0) {
|
|
||||||
list.add(r.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
final CmdLineParser clp = new CmdLineParser(this);
|
|
||||||
try {
|
|
||||||
clp.parseArgument(list.toArray(new String[list.size()]));
|
|
||||||
} catch (CmdLineException err) {
|
|
||||||
if (!help) {
|
|
||||||
throw new UnloggedFailure(1, "fatal: " + err.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (help) {
|
|
||||||
final StringWriter msg = new StringWriter();
|
|
||||||
msg.write(commandPrefix);
|
|
||||||
clp.printSingleLineUsage(msg, null);
|
|
||||||
msg.write('\n');
|
|
||||||
|
|
||||||
msg.write('\n');
|
|
||||||
clp.printUsage(msg, null);
|
|
||||||
msg.write('\n');
|
|
||||||
throw new UnloggedFailure(1, msg.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void start() {
|
public void start() {
|
||||||
startThread(new CommandRunnable() {
|
startThread(new CommandRunnable() {
|
||||||
public void run() throws Exception {
|
public void run() throws Exception {
|
||||||
try {
|
try {
|
||||||
preRun();
|
preRun();
|
||||||
parseArguments();
|
parseCommandLine();
|
||||||
AbstractCommand.this.run();
|
AbstractCommand.this.run();
|
||||||
} finally {
|
} finally {
|
||||||
postRun();
|
postRun();
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
package com.google.gerrit.server.ssh;
|
package com.google.gerrit.server.ssh;
|
||||||
|
|
||||||
import com.google.gerrit.client.reviewdb.Account;
|
import com.google.gerrit.client.reviewdb.Account;
|
||||||
|
import com.google.gerrit.pgm.CmdLineParser;
|
||||||
import com.google.gerrit.server.ssh.SshScopes.Context;
|
import com.google.gerrit.server.ssh.SshScopes.Context;
|
||||||
|
|
||||||
import org.apache.sshd.common.SshException;
|
import org.apache.sshd.common.SshException;
|
||||||
@@ -22,17 +23,25 @@ import org.apache.sshd.server.CommandFactory.Command;
|
|||||||
import org.apache.sshd.server.CommandFactory.ExitCallback;
|
import org.apache.sshd.server.CommandFactory.ExitCallback;
|
||||||
import org.apache.sshd.server.CommandFactory.SessionAware;
|
import org.apache.sshd.server.CommandFactory.SessionAware;
|
||||||
import org.apache.sshd.server.session.ServerSession;
|
import org.apache.sshd.server.session.ServerSession;
|
||||||
|
import org.kohsuke.args4j.Argument;
|
||||||
|
import org.kohsuke.args4j.CmdLineException;
|
||||||
|
import org.kohsuke.args4j.Option;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public abstract class BaseCommand implements Command, SessionAware {
|
public abstract class BaseCommand implements Command, SessionAware {
|
||||||
private static final Logger log = LoggerFactory.getLogger(BaseCommand.class);
|
private static final Logger log = LoggerFactory.getLogger(BaseCommand.class);
|
||||||
|
|
||||||
|
@Option(name = "--help", usage = "display this help text", aliases = {"-h"})
|
||||||
|
private boolean help;
|
||||||
|
|
||||||
protected InputStream in;
|
protected InputStream in;
|
||||||
protected OutputStream out;
|
protected OutputStream out;
|
||||||
protected OutputStream err;
|
protected OutputStream err;
|
||||||
@@ -101,6 +110,72 @@ public abstract class BaseCommand implements Command, SessionAware {
|
|||||||
cmd.setExitCallback(exit);
|
cmd.setExitCallback(exit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the command line argument, injecting parsed values into fields.
|
||||||
|
* <p>
|
||||||
|
* This method must be explicitly invoked to cause a parse. When parsing,
|
||||||
|
* arguments are split out of and read from the {@link #commandLine} field.
|
||||||
|
*
|
||||||
|
* @throws Failure if the command line arguments were invalid.
|
||||||
|
* @see Option
|
||||||
|
* @see Argument
|
||||||
|
*/
|
||||||
|
protected void parseCommandLine() throws Failure {
|
||||||
|
final List<String> list = new ArrayList<String>();
|
||||||
|
boolean inquote = false;
|
||||||
|
StringBuilder r = new StringBuilder();
|
||||||
|
for (int ip = 0; ip < commandLine.length();) {
|
||||||
|
final char b = commandLine.charAt(ip++);
|
||||||
|
switch (b) {
|
||||||
|
case '\t':
|
||||||
|
case ' ':
|
||||||
|
if (inquote)
|
||||||
|
r.append(b);
|
||||||
|
else if (r.length() > 0) {
|
||||||
|
list.add(r.toString());
|
||||||
|
r = new StringBuilder();
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
case '\'':
|
||||||
|
inquote = !inquote;
|
||||||
|
continue;
|
||||||
|
case '\\':
|
||||||
|
if (inquote || ip == commandLine.length())
|
||||||
|
r.append(b); // literal within a quote
|
||||||
|
else
|
||||||
|
r.append(commandLine.charAt(ip++));
|
||||||
|
continue;
|
||||||
|
default:
|
||||||
|
r.append(b);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (r.length() > 0) {
|
||||||
|
list.add(r.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
final CmdLineParser clp = new CmdLineParser(this);
|
||||||
|
try {
|
||||||
|
clp.parseArgument(list.toArray(new String[list.size()]));
|
||||||
|
} catch (CmdLineException err) {
|
||||||
|
if (!help) {
|
||||||
|
throw new UnloggedFailure(1, "fatal: " + err.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (help) {
|
||||||
|
final StringWriter msg = new StringWriter();
|
||||||
|
msg.write(commandPrefix);
|
||||||
|
clp.printSingleLineUsage(msg, null);
|
||||||
|
msg.write('\n');
|
||||||
|
|
||||||
|
msg.write('\n');
|
||||||
|
clp.printUsage(msg, null);
|
||||||
|
msg.write('\n');
|
||||||
|
throw new UnloggedFailure(1, msg.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Spawn a function into its own thread.
|
* Spawn a function into its own thread.
|
||||||
* <p>
|
* <p>
|
||||||
|
|||||||
Reference in New Issue
Block a user