ls-projects: Add --type to filter by project type
`gerrit ls-projects --type code` (the default) now skips permissions
only projects, restoring the output to what appears from Gerrit
2.1.7 and earlier.
`gerrit ls-projects --type permissions` will invert that output and
display only the special permissions-only projects.
`gerrit ls-projects --type all` will display everything.
Change-Id: If04bda437e45e51b5b071dac6edeb2a8ef730eb7
diff --git a/Documentation/cmd-ls-projects.txt b/Documentation/cmd-ls-projects.txt
index 2134df8..de8d5b5 100644
--- a/Documentation/cmd-ls-projects.txt
+++ b/Documentation/cmd-ls-projects.txt
@@ -8,7 +8,10 @@
SYNOPSIS
--------
[verse]
-'ssh' -p <port> <host> 'gerrit ls-projects' [\--show-branch <BRANCH1> ...]
+ 'ssh' -p <port> <host> 'gerrit ls-projects'
+ [--show-branch <BRANCH1> ...]
+ [--tree]
+ [--type {code | permissions | all}]
DESCRIPTION
-----------
@@ -43,6 +46,13 @@
Displays project inheritance in a tree-like format.
This option does not work together with the show-branch option.
+--type::
+ Display only projects of the specified type. Supported
+ types are `code` (any project likely to contain user files),
+ `permissions` (projects created with the --permissions-only
+ flag), `all` (any type of project). If not specified,
+ defaults to `code`.
+
EXAMPLES
--------
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ListProjects.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ListProjects.java
index a17fc0d..ab57713 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ListProjects.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ListProjects.java
@@ -24,9 +24,13 @@
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;
import org.eclipse.jgit.lib.Repository;
import org.kohsuke.args4j.Option;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.PrintWriter;
@@ -36,11 +40,39 @@
import java.util.TreeMap;
final class ListProjects extends BaseCommand {
+ private static final Logger log = LoggerFactory.getLogger(ListProjects.class);
+
private static final String NODE_PREFIX = "|-- ";
private static final String LAST_NODE_PREFIX = "`-- ";
private static final String DEFAULT_TAB_SEPARATOR = "|";
private static final String NOT_VISIBLE_PROJECT = "(x)";
+ static enum FilterType {
+ CODE {
+ @Override
+ boolean matches(Repository git) throws IOException {
+ return !PERMISSIONS.matches(git);
+ }
+ },
+ PERMISSIONS {
+ @Override
+ boolean matches(Repository git) throws IOException {
+ Ref head = git.getRef(Constants.HEAD);
+ return head != null
+ && head.isSymbolic()
+ && GitRepositoryManager.REF_CONFIG.equals(head.getLeaf().getName());
+ }
+ },
+ ALL {
+ @Override
+ boolean matches(Repository git) {
+ return true;
+ }
+ };
+
+ abstract boolean matches(Repository git) throws IOException;
+ }
+
@Inject
private IdentifiedUser currentUser;
@@ -58,6 +90,9 @@
"this option does not work together with the show-branch option")
private boolean showTree;
+ @Option(name = "--type", usage = "type of project")
+ private FilterType type = FilterType.CODE;
+
private String currentTabSeparator = DEFAULT_TAB_SEPARATOR;
@Override
@@ -100,21 +135,49 @@
continue;
}
- if (showBranch != null) {
- List<Ref> refs = getBranchRefs(projectName, pctl);
- if (!hasValidRef(refs)) {
- continue;
+ try {
+ if (showBranch != null) {
+ Repository git = repoManager.openRepository(projectName);
+ try {
+ if (!type.matches(git)) {
+ continue;
+ }
+
+ List<Ref> refs = getBranchRefs(projectName, pctl);
+ if (!hasValidRef(refs)) {
+ continue;
+ }
+
+ for (Ref ref : refs) {
+ if (ref == null) {
+ // Print stub (forty '-' symbols)
+ stdout.print("----------------------------------------");
+ } else {
+ stdout.print(ref.getObjectId().name());
+ }
+ stdout.print(' ');
+ }
+ } finally {
+ git.close();
+ }
+
+ } else if (type != FilterType.ALL) {
+ Repository git = repoManager.openRepository(projectName);
+ try {
+ if (!type.matches(git)) {
+ continue;
+ }
+ } finally {
+ git.close();
+ }
}
- for (Ref ref : refs) {
- if (ref == null) {
- // Print stub (forty '-' symbols)
- stdout.print("----------------------------------------");
- } else {
- stdout.print(ref.getObjectId().name());
- }
- stdout.print(' ');
- }
+ } catch (RepositoryNotFoundException err) {
+ // If the Git repository is gone, the project doesn't actually exist anymore.
+ continue;
+ } catch (IOException err) {
+ log.warn("Unexpected error reading " + projectName, err);
+ continue;
}
stdout.print(projectName.get() + "\n");