diff --git a/src/main/java/com/google/gerrit/server/ssh/DispatchCommand.java b/src/main/java/com/google/gerrit/server/ssh/DispatchCommand.java index 15711a75fa..e02df52193 100644 --- a/src/main/java/com/google/gerrit/server/ssh/DispatchCommand.java +++ b/src/main/java/com/google/gerrit/server/ssh/DispatchCommand.java @@ -20,6 +20,7 @@ import com.google.inject.Provider; import org.apache.sshd.server.CommandFactory.Command; import java.io.IOException; +import java.io.UnsupportedEncodingException; import java.util.Map; /** @@ -37,8 +38,13 @@ public class DispatchCommand extends BaseCommand { @Override public void start() throws IOException { - int sp = commandLine.indexOf(' '); + if (commandLine.isEmpty()) { + usage(); + return; + } + final String name, args; + int sp = commandLine.indexOf(' '); if (0 < sp) { name = commandLine.substring(0, sp); while (Character.isWhitespace(commandLine.charAt(sp))) { @@ -78,4 +84,20 @@ public class DispatchCommand extends BaseCommand { exit.onExit(127); } } + + private void usage() throws IOException, UnsupportedEncodingException { + final StringBuilder usage = new StringBuilder(); + usage.append("usage: " + prefix + " COMMAND [ARGS]\n"); + usage.append("\n"); + usage.append("Available commands of " + prefix + " are:\n"); + for (Map.Entry> e : commands.entrySet()) { + usage.append(" "); + usage.append(e.getKey()); + usage.append("\n"); + } + usage.append("\n"); + err.write(usage.toString().getBytes("UTF-8")); + err.flush(); + exit.onExit(1); + } } diff --git a/src/main/java/com/google/gerrit/server/ssh/DispatchCommandProvider.java b/src/main/java/com/google/gerrit/server/ssh/DispatchCommandProvider.java index aae3d611c3..c822e9cdc2 100644 --- a/src/main/java/com/google/gerrit/server/ssh/DispatchCommandProvider.java +++ b/src/main/java/com/google/gerrit/server/ssh/DispatchCommandProvider.java @@ -24,9 +24,10 @@ import org.apache.sshd.server.CommandFactory.Command; import java.lang.annotation.Annotation; import java.util.Collections; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.TreeMap; /** * Creates DispatchCommand using commands registered by {@link CommandModule}. @@ -76,7 +77,7 @@ public class DispatchCommandProvider implements Provider { @SuppressWarnings("unchecked") private Map> createMap() { final Map> m = - new HashMap>(); + new TreeMap>(); for (final Binding b : allCommands()) { final Annotation annotation = b.getKey().getAnnotation(); @@ -88,7 +89,7 @@ public class DispatchCommandProvider implements Provider { } } - return Collections.unmodifiableMap(m); + return Collections.unmodifiableMap(new LinkedHashMap(m)); } private static final TypeLiteral type =