ListPlugins: Add support for pagination with start/limit options

Feature: Issue 6499
Change-Id: I8b6e080abbe3bd7401d505f89e71271365629c6a
This commit is contained in:
David Pursehouse
2017-07-27 17:32:28 +01:00
parent 9172702803
commit 7f577a908c
5 changed files with 127 additions and 27 deletions

View File

@@ -84,6 +84,61 @@ List all plugins including those that are disabled.
} }
---- ----
Limit(n)::
Limit the number of plugins to be included in the results.
+
Query the first plugin in the plugin list:
+
.Request
----
GET /plugins/?n=1 HTTP/1.0
----
+
.Response
----
HTTP/1.1 200 OK
Content-Disposition: attachment
Content-Type: application/json; charset=UTF-8
)]}'
{
"delete-project": {
"id": "delete-project",
"index_url": "plugins/delete-project/",
"version": "2.9-SNAPSHOT"
}
}
----
Skip(S)::
Skip the given number of plugins from the beginning of the list.
+
Query the second plugin in the plugin list:
+
.Request
----
GET /plugins/?all&n=1&S=1 HTTP/1.0
----
+
.Response
----
HTTP/1.1 200 OK
Content-Disposition: attachment
Content-Type: application/json; charset=UTF-8
)]}'
{
"reviewers-by-blame": {
"id": "reviewers-by-blame",
"index_url": "plugins/reviewers-by-blame/",
"version": "2.9-SNAPSHOT",
"disabled": true
}
}
----
[[install-plugin]] [[install-plugin]]
=== Install Plugin === Install Plugin
-- --

View File

@@ -47,35 +47,34 @@ public class PluginIT extends AbstractDaemonTest {
assertThat(list().get()).isEmpty(); assertThat(list().get()).isEmpty();
assertThat(list().all().get()).isEmpty(); assertThat(list().all().get()).isEmpty();
PluginApi test; PluginApi api;
PluginInfo info;
// Install all the plugins // Install all the plugins
InstallPluginInput input = new InstallPluginInput(); InstallPluginInput input = new InstallPluginInput();
input.raw = RawInputUtil.create(JS_PLUGIN_CONTENT); input.raw = RawInputUtil.create(JS_PLUGIN_CONTENT);
for (String plugin : PLUGINS) { for (String plugin : PLUGINS) {
test = gApi.plugins().install(plugin + ".js", input); api = gApi.plugins().install(plugin + ".js", input);
assertThat(test).isNotNull(); assertThat(api).isNotNull();
info = test.get(); PluginInfo info = api.get();
assertThat(info.id).isEqualTo(plugin); assertThat(info.id).isEqualTo(plugin);
assertThat(info.disabled).isNull(); assertThat(info.disabled).isNull();
} }
assertPlugins(list().get(), PLUGINS); assertPlugins(list().get(), PLUGINS);
// With pagination
assertPlugins(list().start(1).limit(2).get(), PLUGINS.subList(1, 3));
// Disable // Disable
test = gApi.plugins().name("plugin-a"); api = gApi.plugins().name("plugin-a");
test.disable(); api.disable();
test = gApi.plugins().name("plugin-a"); api = gApi.plugins().name("plugin-a");
info = test.get(); assertThat(api.get().disabled).isTrue();
assertThat(info.disabled).isTrue();
assertPlugins(list().get(), PLUGINS.subList(1, PLUGINS.size())); assertPlugins(list().get(), PLUGINS.subList(1, PLUGINS.size()));
assertPlugins(list().all().get(), PLUGINS); assertPlugins(list().all().get(), PLUGINS);
// Enable // Enable
test.enable(); api.enable();
test = gApi.plugins().name("plugin-a"); api = gApi.plugins().name("plugin-a");
info = test.get(); assertThat(api.get().disabled).isNull();
assertThat(info.disabled).isNull();
assertPlugins(list().get(), PLUGINS); assertPlugins(list().get(), PLUGINS);
} }

View File

@@ -33,6 +33,8 @@ public interface Plugins {
abstract class ListRequest { abstract class ListRequest {
private boolean all; private boolean all;
private int limit;
private int start;
public List<PluginInfo> get() throws RestApiException { public List<PluginInfo> get() throws RestApiException {
Map<String, PluginInfo> map = getAsMap(); Map<String, PluginInfo> map = getAsMap();
@@ -53,6 +55,24 @@ public interface Plugins {
public boolean getAll() { public boolean getAll() {
return all; return all;
} }
public ListRequest limit(int limit) {
this.limit = limit;
return this;
}
public int getLimit() {
return limit;
}
public ListRequest start(int start) {
this.start = start;
return this;
}
public int getStart() {
return start;
}
} }
/** /**

View File

@@ -61,6 +61,8 @@ public class PluginsImpl implements Plugins {
public SortedMap<String, PluginInfo> getAsMap() throws RestApiException { public SortedMap<String, PluginInfo> getAsMap() throws RestApiException {
ListPlugins list = listProvider.get(); ListPlugins list = listProvider.get();
list.setAll(this.getAll()); list.setAll(this.getAll());
list.setStart(this.getStart());
list.setLimit(this.getLimit());
return list.apply(); return list.apply();
} }
}; };

View File

@@ -14,8 +14,11 @@
package com.google.gerrit.server.plugins; package com.google.gerrit.server.plugins;
import static java.util.Comparator.comparing;
import static java.util.stream.Collectors.toList;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.google.common.collect.Lists; import com.google.common.collect.Streams;
import com.google.gerrit.common.Nullable; import com.google.gerrit.common.Nullable;
import com.google.gerrit.common.data.GlobalCapability; import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.extensions.annotations.RequiresCapability; import com.google.gerrit.extensions.annotations.RequiresCapability;
@@ -27,12 +30,11 @@ import com.google.gerrit.server.OutputFormat;
import com.google.gson.reflect.TypeToken; import com.google.gson.reflect.TypeToken;
import com.google.inject.Inject; import com.google.inject.Inject;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.util.Collections;
import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.SortedMap; import java.util.SortedMap;
import java.util.TreeMap; import java.util.TreeMap;
import java.util.stream.Stream;
import org.kohsuke.args4j.Option; import org.kohsuke.args4j.Option;
/** List the installed plugins. */ /** List the installed plugins. */
@@ -41,6 +43,8 @@ public class ListPlugins implements RestReadView<TopLevelResource> {
private final PluginLoader pluginLoader; private final PluginLoader pluginLoader;
private boolean all; private boolean all;
private int limit;
private int start;
@Deprecated @Deprecated
@Option(name = "--format", usage = "(deprecated) output format") @Option(name = "--format", usage = "(deprecated) output format")
@@ -55,6 +59,26 @@ public class ListPlugins implements RestReadView<TopLevelResource> {
this.all = all; this.all = all;
} }
@Option(
name = "--limit",
aliases = {"-n"},
metaVar = "CNT",
usage = "maximum number of plugins to list"
)
public void setLimit(int limit) {
this.limit = limit;
}
@Option(
name = "--start",
aliases = {"-S"},
metaVar = "CNT",
usage = "number of plugins to skip"
)
public void setStart(int start) {
this.start = start;
}
@Inject @Inject
protected ListPlugins(PluginLoader pluginLoader) { protected ListPlugins(PluginLoader pluginLoader) {
this.pluginLoader = pluginLoader; this.pluginLoader = pluginLoader;
@@ -82,15 +106,15 @@ public class ListPlugins implements RestReadView<TopLevelResource> {
public SortedMap<String, PluginInfo> display(@Nullable PrintWriter stdout) { public SortedMap<String, PluginInfo> display(@Nullable PrintWriter stdout) {
SortedMap<String, PluginInfo> output = new TreeMap<>(); SortedMap<String, PluginInfo> output = new TreeMap<>();
List<Plugin> plugins = Lists.newArrayList(pluginLoader.getPlugins(all)); Stream<Plugin> s =
Collections.sort( Streams.stream(pluginLoader.getPlugins(all)).sorted(comparing(Plugin::getName));
plugins, if (start > 0) {
new Comparator<Plugin>() { s = s.skip(start);
@Override }
public int compare(Plugin a, Plugin b) { if (limit > 0) {
return a.getName().compareTo(b.getName()); s = s.limit(limit);
} }
}); List<Plugin> plugins = s.collect(toList());
if (!format.isJson()) { if (!format.isJson()) {
stdout.format("%-30s %-10s %-8s %s\n", "Name", "Version", "Status", "File"); stdout.format("%-30s %-10s %-8s %s\n", "Name", "Version", "Status", "File");