diff --git a/gerrit-server/pom.xml b/gerrit-server/pom.xml
index b0c2125dd0..674d3b64c8 100644
--- a/gerrit-server/pom.xml
+++ b/gerrit-server/pom.xml
@@ -121,6 +121,12 @@ limitations under the License.
${project.version}
+
+ com.google.gerrit
+ gerrit-util-cli
+ ${project.version}
+
+
com.google.gerrit
gerrit-util-ssl
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/config/GerritGlobalModule.java b/gerrit-server/src/main/java/com/google/gerrit/server/config/GerritGlobalModule.java
index 90a0890d94..99dd54a6a9 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/config/GerritGlobalModule.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/config/GerritGlobalModule.java
@@ -57,6 +57,7 @@ import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.project.PermissionCollection;
import com.google.gerrit.server.project.ProjectCacheImpl;
import com.google.gerrit.server.project.ProjectControl;
+import com.google.gerrit.server.project.ProjectNode;
import com.google.gerrit.server.project.ProjectState;
import com.google.gerrit.server.project.SectionSortCache;
import com.google.gerrit.server.tools.ToolsCatalog;
@@ -118,6 +119,7 @@ public class GerritGlobalModule extends FactoryModule {
factory(AccountInfoCacheFactory.Factory.class);
factory(CapabilityControl.Factory.class);
factory(GroupInfoCacheFactory.Factory.class);
+ factory(ProjectNode.Factory.class);
factory(ProjectState.Factory.class);
factory(MaterializedGroupMembership.Factory.class);
bind(PermissionCollection.Factory.class);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/config/GerritRequestModule.java b/gerrit-server/src/main/java/com/google/gerrit/server/config/GerritRequestModule.java
index 00562b0bd5..71bcc6cce7 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/config/GerritRequestModule.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/config/GerritRequestModule.java
@@ -53,6 +53,7 @@ import com.google.gerrit.server.patch.PublishComments;
import com.google.gerrit.server.patch.RemoveReviewer;
import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.project.CreateProject;
+import com.google.gerrit.server.project.ListProjects;
import com.google.gerrit.server.project.PerRequestProjectControlCache;
import com.google.gerrit.server.project.ProjectControl;
import com.google.gerrit.server.project.SuggestParentCandidates;
@@ -71,6 +72,7 @@ public class GerritRequestModule extends FactoryModule {
bind(MetaDataUpdate.User.class).in(RequestScoped.class);
bind(AccountResolver.class);
bind(ChangeQueryRewriter.class);
+ bind(ListProjects.class);
bind(AnonymousUser.class).in(RequestScoped.class);
bind(PerRequestProjectControlCache.class).in(RequestScoped.class);
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ListProjects.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/ListProjects.java
similarity index 80%
rename from gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ListProjects.java
rename to gerrit-server/src/main/java/com/google/gerrit/server/project/ListProjects.java
index 3eb9f52695..95a8b775e1 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ListProjects.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/ListProjects.java
@@ -12,18 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package com.google.gerrit.sshd.commands;
+package com.google.gerrit.server.project;
import com.google.gerrit.reviewdb.client.Project;
-import com.google.gerrit.server.IdentifiedUser;
+import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.git.GitRepositoryManager;
-import com.google.gerrit.server.project.ProjectCache;
-import com.google.gerrit.server.project.ProjectControl;
-import com.google.gerrit.server.project.ProjectState;
-import com.google.gerrit.sshd.BaseCommand;
+import com.google.gerrit.server.util.TreeFormatter;
import com.google.inject.Inject;
-import org.apache.sshd.server.Environment;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.Ref;
@@ -32,18 +28,23 @@ import org.kohsuke.args4j.Option;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.io.BufferedWriter;
import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
import java.io.PrintWriter;
+import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
-final class ListProjects extends BaseCommand {
+/** List projects visible to the calling user. */
+public class ListProjects {
private static final Logger log = LoggerFactory.getLogger(ListProjects.class);
- static enum FilterType {
+ public static enum FilterType {
CODE {
@Override
boolean matches(Repository git) throws IOException {
@@ -69,24 +70,18 @@ final class ListProjects extends BaseCommand {
abstract boolean matches(Repository git) throws IOException;
}
- @Inject
- private IdentifiedUser currentUser;
-
- @Inject
- private ProjectCache projectCache;
-
- @Inject
- private GitRepositoryManager repoManager;
-
- @Inject
- private ProjectNode.Factory projectNodeFactory;
+ private final CurrentUser currentUser;
+ private final ProjectCache projectCache;
+ private final GitRepositoryManager repoManager;
+ private final ProjectNode.Factory projectNodeFactory;
@Option(name = "--show-branch", aliases = {"-b"}, multiValued = true,
usage = "displays the sha of each project in the specified branch")
private List showBranch;
- @Option(name = "--tree", aliases = {"-t"}, usage = "displays project inheritance in a tree-like format\n" +
- "this option does not work together with the show-branch option")
+ @Option(name = "--tree", aliases = {"-t"}, usage =
+ "displays project inheritance in a tree-like format\n"
+ + "this option does not work together with the show-branch option")
private boolean showTree;
@Option(name = "--type", usage = "type of project")
@@ -98,27 +93,37 @@ final class ListProjects extends BaseCommand {
@Option(name = "--all", usage = "display all projects that are accessible by the calling user")
private boolean all;
- @Override
- public void start(final Environment env) {
- startThread(new CommandRunnable() {
- @Override
- public void run() throws Exception {
- parseCommandLine();
- ListProjects.this.display();
- }
- });
+ @Inject
+ protected ListProjects(CurrentUser currentUser, ProjectCache projectCache,
+ GitRepositoryManager repoManager,
+ ProjectNode.Factory projectNodeFactory) {
+ this.currentUser = currentUser;
+ this.projectCache = projectCache;
+ this.repoManager = repoManager;
+ this.projectNodeFactory = projectNodeFactory;
}
- private void display() throws Failure {
- if (showTree && (showBranch != null)) {
- throw new UnloggedFailure(1, "fatal: --tree and --show-branch options are not compatible.");
+ public List getShowBranch() {
+ return showBranch;
+ }
+
+ public boolean isShowTree() {
+ return showTree;
+ }
+
+ public boolean isShowDescription() {
+ return showDescription;
+ }
+
+ public void display(OutputStream out) {
+ final PrintWriter stdout;
+ try {
+ stdout = new PrintWriter(new BufferedWriter(new OutputStreamWriter(out, "UTF-8")));
+ } catch (UnsupportedEncodingException e) {
+ // Our encoding is required by the specifications for the runtime.
+ throw new RuntimeException("JVM lacks UTF-8 encoding", e);
}
- if (showTree && showDescription) {
- throw new UnloggedFailure(1, "fatal: --tree and --description options are not compatible.");
- }
-
- final PrintWriter stdout = toPrintWriter(out);
final TreeMap treeMap =
new TreeMap();
try {
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ProjectNode.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectNode.java
similarity index 90%
rename from gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ProjectNode.java
rename to gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectNode.java
index 64a310b197..1c4d7c4f76 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ProjectNode.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectNode.java
@@ -12,32 +12,31 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package com.google.gerrit.sshd.commands;
+package com.google.gerrit.server.project;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.config.AllProjectsName;
-import com.google.gerrit.sshd.commands.TreeFormatter.TreeNode;
+import com.google.gerrit.server.util.TreeFormatter.TreeNode;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import java.util.SortedSet;
import java.util.TreeSet;
+/** Node of a Project in a tree formatted by {@link ListProjects}. */
public class ProjectNode implements TreeNode, Comparable {
-
public interface Factory {
ProjectNode create(final Project project, final boolean isVisible);
}
private final AllProjectsName allProjectsName;
-
private final Project project;
private final boolean isVisible;
private final SortedSet children = new TreeSet();
@Inject
- public ProjectNode(final AllProjectsName allProjectsName,
+ protected ProjectNode(final AllProjectsName allProjectsName,
@Assisted final Project project, @Assisted final boolean isVisible) {
this.allProjectsName = allProjectsName;
this.project = project;
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/TreeFormatter.java b/gerrit-server/src/main/java/com/google/gerrit/server/util/TreeFormatter.java
similarity index 98%
rename from gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/TreeFormatter.java
rename to gerrit-server/src/main/java/com/google/gerrit/server/util/TreeFormatter.java
index 3aa83c3ad4..1c68a75797 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/TreeFormatter.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/util/TreeFormatter.java
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package com.google.gerrit.sshd.commands;
+package com.google.gerrit.server.util;
import java.io.PrintWriter;
import java.util.SortedSet;
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshModule.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshModule.java
index 00281b848f..54b0bb5ab4 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshModule.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshModule.java
@@ -40,7 +40,6 @@ import com.google.gerrit.sshd.args4j.PatchSetIdHandler;
import com.google.gerrit.sshd.args4j.ProjectControlHandler;
import com.google.gerrit.sshd.args4j.SocketAddressHandler;
import com.google.gerrit.sshd.commands.DefaultCommandModule;
-import com.google.gerrit.sshd.commands.ProjectNode;
import com.google.gerrit.sshd.commands.QueryShell;
import com.google.gerrit.util.cli.CmdLineParser;
import com.google.gerrit.util.cli.OptionHandlerUtil;
@@ -79,7 +78,6 @@ public class SshModule extends FactoryModule {
bind(QueueProvider.class).to(CommandExecutorQueueProvider.class).in(SINGLETON);
bind(AccountManager.class);
factory(ChangeUserName.Factory.class);
- factory(ProjectNode.Factory.class);
bind(PublickeyAuthenticator.class).to(DatabasePubKeyAuth.class);
bind(KeyPairProvider.class).toProvider(HostKeyProvider.class).in(SINGLETON);
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/DefaultCommandModule.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/DefaultCommandModule.java
index 5cee06ee96..16461b6b06 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/DefaultCommandModule.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/DefaultCommandModule.java
@@ -36,7 +36,7 @@ public class DefaultCommandModule extends CommandModule {
command(gerrit).toProvider(new DispatchCommandProvider(gerrit));
command(gerrit, "flush-caches").to(FlushCaches.class);
- command(gerrit, "ls-projects").to(ListProjects.class);
+ command(gerrit, "ls-projects").to(ListProjectsCommand.class);
command(gerrit, "ls-groups").to(ListGroupsCommand.class);
command(gerrit, "query").to(Query.class);
command(gerrit, "show-caches").to(ShowCaches.class);
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ListProjectsCommand.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ListProjectsCommand.java
new file mode 100644
index 0000000000..d0bbc72079
--- /dev/null
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ListProjectsCommand.java
@@ -0,0 +1,43 @@
+// Copyright (C) 2009 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.sshd.commands;
+
+import com.google.gerrit.server.project.ListProjects;
+import com.google.gerrit.sshd.BaseCommand;
+import com.google.inject.Inject;
+
+import org.apache.sshd.server.Environment;
+
+final class ListProjectsCommand extends BaseCommand {
+ @Inject
+ private ListProjects impl;
+
+ @Override
+ public void start(final Environment env) {
+ startThread(new CommandRunnable() {
+ @Override
+ public void run() throws Exception {
+ parseCommandLine(impl);
+ if (impl.isShowTree() && (impl.getShowBranch() != null)) {
+ throw new UnloggedFailure(1, "fatal: --tree and --show-branch options are not compatible.");
+ }
+ if (impl.isShowTree() && impl.isShowDescription()) {
+ throw new UnloggedFailure(1, "fatal: --tree and --description options are not compatible.");
+ }
+ impl.display(out);
+ }
+ });
+ }
+}