Merge branch 'stable-3.2'
* stable-3.2: Upgrade auto-value to 1.7.4 Respect container.replica option in gerrit.sh script Fix plugin builds on OSX Upgrade metrics-core to 4.1.10.1 Add guidelines on choosing a branch for contributions For errors on `refs/publish/...`, warn about too old git-review Fix an outdated test Fix selection on diff with range comments Restore keyboard shortcut for expand all diff context Fix the position of the hovercard In plugin list, add placeholders for missing versions Add Api version to plugin list in PolyGerrit UI Add Api version to `plugin ls` Ssh command text format Expose Api version through PluginInfo When writing temporary plugin files, ensure the directory exists Update git submodules Update git submodules Change-Id: Id20934171f5fb8051858824758c50953f20948ef
This commit is contained in:
@@ -10,6 +10,37 @@ problems are often highlighted and we find it hard to look
|
||||
beyond simple spacing issues. Blame it on our short attention
|
||||
spans, we really do want your code.
|
||||
|
||||
|
||||
[[branch]]
|
||||
== Branch
|
||||
|
||||
Gerrit provides support for more than one version, which naturally
|
||||
raises the question of which branch you should start your contribution
|
||||
on. There are no hard and fast rules, but below we try to outline some
|
||||
guidelines:
|
||||
|
||||
* Genuinely new and/or disruptive features, should generally start on
|
||||
`master`. Also consider submitting a
|
||||
link:dev-design-docs.html[design doc] beforehand to allow discussion
|
||||
by the ESC and the community.
|
||||
* Improvements of existing features should also generally go into
|
||||
`master`. But we understand that if you cannot run `master`, it
|
||||
might take a while until you could benefit from it. In that case,
|
||||
start on the newest `stable-*` branch that you can run.
|
||||
* Bug-fixes should generally at least cover the oldest affected and
|
||||
still supported version. If you're affected and run an even older
|
||||
version, you're welcome to upload to that older version, even if
|
||||
it is no longer officially supported, bearing in mind that
|
||||
verification and release may happen only once merged upstream.
|
||||
|
||||
Regardless of the above, changes might get moved to a different branch
|
||||
before being submitted or might get cherry-picked/re-merged to a
|
||||
different branch even after they've landed.
|
||||
|
||||
For each of the above items, you'll find ad-hoc exceptions. The point
|
||||
is: We'd much rather see your code and fixes than not see them.
|
||||
|
||||
|
||||
[[commit-message]]
|
||||
== Commit Message
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@ by plugin ID.
|
||||
"id": "delete-project",
|
||||
"index_url": "plugins/delete-project/",
|
||||
"filename": "delete-project.jar",
|
||||
"api_version": "2.9.3-SNAPSHOT",
|
||||
"version": "2.9-SNAPSHOT"
|
||||
}
|
||||
}
|
||||
@@ -455,12 +456,13 @@ The `PluginInfo` entity describes a plugin.
|
||||
|
||||
[options="header",cols="1,^2,4"]
|
||||
|=======================
|
||||
|Field Name ||Description
|
||||
|`id` ||The ID of the plugin.
|
||||
|`version` ||The version of the plugin.
|
||||
|`index_url`|optional|URL of the plugin's default page.
|
||||
|`filename` |optional|The plugin's filename.
|
||||
|`disabled` |not set if `false`|Whether the plugin is disabled.
|
||||
|Field Name ||Description
|
||||
|`id` ||The ID of the plugin.
|
||||
|`version` ||The version of the plugin.
|
||||
|`api_version`|optional|The version of the Gerrit Api used by the plugin.
|
||||
|`index_url` |optional|URL of the plugin's default page.
|
||||
|`filename` |optional|The plugin's filename.
|
||||
|`disabled` |not set if `false`|Whether the plugin is disabled.
|
||||
|=======================
|
||||
|
||||
[[plugin-input]]
|
||||
|
||||
@@ -626,18 +626,18 @@ maven_jar(
|
||||
sha1 = "a3ae34e57fa8a4040e28247291d0cc3d6b8c7bcf",
|
||||
)
|
||||
|
||||
AUTO_VALUE_VERSION = "1.7.3"
|
||||
AUTO_VALUE_VERSION = "1.7.4"
|
||||
|
||||
maven_jar(
|
||||
name = "auto-value",
|
||||
artifact = "com.google.auto.value:auto-value:" + AUTO_VALUE_VERSION,
|
||||
sha1 = "cbd30873f839545c7c9264bed61d500bf85bd33e",
|
||||
sha1 = "6b126cb218af768339e4d6e95a9b0ae41f74e73d",
|
||||
)
|
||||
|
||||
maven_jar(
|
||||
name = "auto-value-annotations",
|
||||
artifact = "com.google.auto.value:auto-value-annotations:" + AUTO_VALUE_VERSION,
|
||||
sha1 = "59ce5ee6aea918f674229f1147da95fdf7f31ce6",
|
||||
sha1 = "eff48ed53995db2dadf0456426cc1f8700136f86",
|
||||
)
|
||||
|
||||
declare_nongoogle_deps()
|
||||
|
||||
@@ -17,13 +17,21 @@ package com.google.gerrit.extensions.common;
|
||||
public class PluginInfo {
|
||||
public final String id;
|
||||
public final String version;
|
||||
public final String apiVersion;
|
||||
public final String indexUrl;
|
||||
public final String filename;
|
||||
public final Boolean disabled;
|
||||
|
||||
public PluginInfo(String id, String version, String indexUrl, String filename, Boolean disabled) {
|
||||
public PluginInfo(
|
||||
String id,
|
||||
String version,
|
||||
String apiVersion,
|
||||
String indexUrl,
|
||||
String filename,
|
||||
Boolean disabled) {
|
||||
this.id = id;
|
||||
this.version = version;
|
||||
this.apiVersion = apiVersion;
|
||||
this.indexUrl = indexUrl;
|
||||
this.filename = filename;
|
||||
this.disabled = disabled;
|
||||
|
||||
@@ -1005,7 +1005,15 @@ class ReceiveCommits {
|
||||
private String buildError(String error, List<String> branches) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (branches.size() == 1) {
|
||||
sb.append("branch ").append(branches.get(0)).append(":\n");
|
||||
String branch = branches.get(0);
|
||||
sb.append("branch ").append(branch).append(":\n");
|
||||
// As of 2020, there are still many git-review <1.27 installations in the wild.
|
||||
// These users will see failures as their old git-review assumes that
|
||||
// `refs/publish/...` is still magic, which it isn't. As Gerrit's default error messages are
|
||||
// misleading for these users, we hint them at upgrading their git-review.
|
||||
if (branch.startsWith("refs/publish/")) {
|
||||
sb.append("If you are using git-review, update to at least git-review 1.27. Otherwise:\n");
|
||||
}
|
||||
sb.append(error);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@@ -146,12 +146,14 @@ public class ListPlugins implements RestReadView<TopLevelResource> {
|
||||
public static PluginInfo toPluginInfo(Plugin p) {
|
||||
String id;
|
||||
String version;
|
||||
String apiVersion;
|
||||
String indexUrl;
|
||||
String filename;
|
||||
Boolean disabled;
|
||||
|
||||
id = Url.encode(p.getName());
|
||||
version = p.getVersion();
|
||||
apiVersion = p.getApiVersion();
|
||||
disabled = p.isDisabled() ? true : null;
|
||||
if (p.getSrcFile() != null) {
|
||||
indexUrl = String.format("plugins/%s/", p.getName());
|
||||
@@ -161,6 +163,6 @@ public class ListPlugins implements RestReadView<TopLevelResource> {
|
||||
filename = null;
|
||||
}
|
||||
|
||||
return new PluginInfo(id, version, indexUrl, filename, disabled);
|
||||
return new PluginInfo(id, version, apiVersion, indexUrl, filename, disabled);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,6 +116,11 @@ public abstract class Plugin {
|
||||
return apiType;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getApiVersion() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Plugin.CacheKey getCacheKey() {
|
||||
return cacheKey;
|
||||
}
|
||||
|
||||
@@ -53,7 +53,9 @@ public class PluginUtil {
|
||||
}
|
||||
|
||||
static Path asTemp(InputStream in, String prefix, String suffix, Path dir) throws IOException {
|
||||
Files.createDirectories(dir);
|
||||
if (!Files.exists(dir)) {
|
||||
Files.createDirectories(dir);
|
||||
}
|
||||
Path tmp = Files.createTempFile(dir, prefix, suffix);
|
||||
boolean keep = false;
|
||||
try (OutputStream out = Files.newOutputStream(tmp)) {
|
||||
|
||||
@@ -153,6 +153,13 @@ public class ServerPlugin extends Plugin {
|
||||
return main.getValue(Attributes.Name.IMPLEMENTATION_VERSION);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public String getApiVersion() {
|
||||
Attributes main = manifest.getMainAttributes();
|
||||
return main.getValue("Gerrit-ApiVersion");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canReload() {
|
||||
Attributes main = manifest.getMainAttributes();
|
||||
|
||||
@@ -49,15 +49,17 @@ public class PluginLsCommand extends SshCommand {
|
||||
.toJson(output, new TypeToken<Map<String, PluginInfo>>() {}.getType(), stdout);
|
||||
stdout.print('\n');
|
||||
} else {
|
||||
stdout.format("%-30s %-10s %-8s %s\n", "Name", "Version", "Status", "File");
|
||||
String template = "%-30s %-10s %-16s %-8s %s\n";
|
||||
stdout.format(template, "Name", "Version", "Api-Version", "Status", "File");
|
||||
stdout.print(
|
||||
"-------------------------------------------------------------------------------\n");
|
||||
for (Map.Entry<String, PluginInfo> p : output.entrySet()) {
|
||||
PluginInfo info = p.getValue();
|
||||
stdout.format(
|
||||
"%-30s %-10s %-8s %s\n",
|
||||
template,
|
||||
p.getKey(),
|
||||
Strings.nullToEmpty(info.version),
|
||||
Strings.nullToEmpty(info.apiVersion),
|
||||
status(info.disabled),
|
||||
Strings.nullToEmpty(info.filename));
|
||||
}
|
||||
|
||||
@@ -37,7 +37,12 @@ import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
|
||||
import com.google.gerrit.extensions.restapi.RestApiException;
|
||||
import com.google.gerrit.server.plugins.MandatoryPluginsCollection;
|
||||
import com.google.inject.Inject;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.jar.Attributes;
|
||||
import java.util.jar.JarOutputStream;
|
||||
import java.util.jar.Manifest;
|
||||
import org.junit.Test;
|
||||
|
||||
@NoHttpd
|
||||
@@ -51,7 +56,14 @@ public class PluginIT extends AbstractDaemonTest {
|
||||
|
||||
private static final ImmutableList<String> PLUGINS =
|
||||
ImmutableList.of(
|
||||
"plugin-a.js", "plugin-b.html", "plugin-c.js", "plugin-d.html", "plugin_e.js");
|
||||
"plugin-a.js",
|
||||
"plugin-b.html",
|
||||
"plugin-c.js",
|
||||
"plugin-d.html",
|
||||
"plugin-normal.jar",
|
||||
"plugin-empty.jar",
|
||||
"plugin-unset.jar",
|
||||
"plugin_e.js");
|
||||
|
||||
@Inject private RequestScopeOperations requestScopeOperations;
|
||||
@Inject private MandatoryPluginsCollection mandatoryPluginsCollection;
|
||||
@@ -67,13 +79,14 @@ public class PluginIT extends AbstractDaemonTest {
|
||||
// Install all the plugins
|
||||
InstallPluginInput input = new InstallPluginInput();
|
||||
for (String plugin : PLUGINS) {
|
||||
input.raw = plugin.endsWith(".js") ? JS_PLUGIN_CONTENT : HTML_PLUGIN_CONTENT;
|
||||
input.raw = pluginContent(plugin);
|
||||
api = gApi.plugins().install(plugin, input);
|
||||
assertThat(api).isNotNull();
|
||||
PluginInfo info = api.get();
|
||||
String name = pluginName(plugin);
|
||||
assertThat(info.id).isEqualTo(name);
|
||||
assertThat(info.version).isEqualTo(pluginVersion(plugin));
|
||||
assertThat(info.apiVersion).isEqualTo(pluginApiVersion(plugin));
|
||||
assertThat(info.indexUrl).isEqualTo(String.format("plugins/%s/", name));
|
||||
assertThat(info.filename).isEqualTo(plugin);
|
||||
assertThat(info.disabled).isNull();
|
||||
@@ -168,12 +181,52 @@ public class PluginIT extends AbstractDaemonTest {
|
||||
return plugin.substring(0, dot);
|
||||
}
|
||||
|
||||
private RawInput pluginJarContent(String plugin) throws IOException {
|
||||
ByteArrayOutputStream arrayStream = new ByteArrayOutputStream();
|
||||
Manifest manifest = new Manifest();
|
||||
Attributes attributes = manifest.getMainAttributes();
|
||||
attributes.put(Attributes.Name.MANIFEST_VERSION, "1.0");
|
||||
if (!plugin.endsWith("-unset.jar")) {
|
||||
attributes.put(Attributes.Name.IMPLEMENTATION_VERSION, pluginVersion(plugin));
|
||||
attributes.put(new Attributes.Name("Gerrit-ApiVersion"), pluginApiVersion(plugin));
|
||||
}
|
||||
try (JarOutputStream jarStream = new JarOutputStream(arrayStream, manifest)) {}
|
||||
return RawInputUtil.create(arrayStream.toByteArray());
|
||||
}
|
||||
|
||||
private RawInput pluginContent(String plugin) throws IOException {
|
||||
if (plugin.endsWith(".js")) {
|
||||
return JS_PLUGIN_CONTENT;
|
||||
}
|
||||
if (plugin.endsWith(".html")) {
|
||||
return HTML_PLUGIN_CONTENT;
|
||||
}
|
||||
assertThat(plugin).endsWith(".jar");
|
||||
return pluginJarContent(plugin);
|
||||
}
|
||||
|
||||
private String pluginVersion(String plugin) {
|
||||
String name = pluginName(plugin);
|
||||
if (name.endsWith("empty")) {
|
||||
return "";
|
||||
}
|
||||
if (name.endsWith("unset")) {
|
||||
return null;
|
||||
}
|
||||
int dash = name.lastIndexOf("-");
|
||||
return dash > 0 ? name.substring(dash + 1) : "";
|
||||
}
|
||||
|
||||
private String pluginApiVersion(String plugin) {
|
||||
if (plugin.endsWith("normal.jar")) {
|
||||
return "2.16.19-SNAPSHOT";
|
||||
}
|
||||
if (plugin.endsWith("empty.jar")) {
|
||||
return "";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void assertBadRequest(ListRequest req) throws Exception {
|
||||
assertThrows(BadRequestException.class, () -> req.get());
|
||||
}
|
||||
|
||||
@@ -21,7 +21,9 @@ export const htmlTemplate = html`
|
||||
/* Workaround for empty style block - see https://github.com/Polymer/tools/issues/408 */
|
||||
</style>
|
||||
<style include="gr-table-styles">
|
||||
/* Workaround for empty style block - see https://github.com/Polymer/tools/issues/408 */
|
||||
.placeholder {
|
||||
color: var(--deemphasized-text-color);
|
||||
}
|
||||
</style>
|
||||
<gr-list-view
|
||||
filter="[[_filter]]"
|
||||
@@ -36,6 +38,7 @@ export const htmlTemplate = html`
|
||||
<tr class="headerRow">
|
||||
<th class="name topHeader">Plugin Name</th>
|
||||
<th class="version topHeader">Version</th>
|
||||
<th class="apiVersion topHeader">API Version</th>
|
||||
<th class="status topHeader">Status</th>
|
||||
</tr>
|
||||
<tr id="loading" class$="loadingMsg [[computeLoadingClass(_loading)]]">
|
||||
@@ -53,7 +56,22 @@ export const htmlTemplate = html`
|
||||
[[item.id]]
|
||||
</template>
|
||||
</td>
|
||||
<td class="version">[[item.version]]</td>
|
||||
<td class="version">
|
||||
<template is="dom-if" if="[[item.version]]">
|
||||
[[item.version]]
|
||||
</template>
|
||||
<template is="dom-if" if="[[!item.version]]">
|
||||
<span class="placeholder">--</span>
|
||||
</template>
|
||||
</td>
|
||||
<td class="apiVersion">
|
||||
<template is="dom-if" if="[[item.api_version]]">
|
||||
[[item.api_version]]
|
||||
</template>
|
||||
<template is="dom-if" if="[[!item.api_version]]">
|
||||
<span class="placeholder">--</span>
|
||||
</template>
|
||||
</td>
|
||||
<td class="status">[[_status(item)]]</td>
|
||||
</tr>
|
||||
</template>
|
||||
|
||||
@@ -25,13 +25,18 @@ let counter;
|
||||
const pluginGenerator = () => {
|
||||
const plugin = {
|
||||
id: `test${++counter}`,
|
||||
version: '3.0-SNAPSHOT',
|
||||
disabled: false,
|
||||
};
|
||||
|
||||
if (counter !== 2) {
|
||||
plugin.index_url = `plugins/test${counter}/`;
|
||||
}
|
||||
if (counter !== 3) {
|
||||
plugin.version = `version-${counter}`;
|
||||
}
|
||||
if (counter !== 4) {
|
||||
plugin.api_version = `api-version-${counter}`;
|
||||
}
|
||||
return plugin;
|
||||
};
|
||||
|
||||
@@ -61,10 +66,11 @@ suite('gr-plugin-list tests', () => {
|
||||
|
||||
test('plugin in the list is formatted correctly', done => {
|
||||
flush(() => {
|
||||
assert.equal(element._plugins[2].id, 'test3');
|
||||
assert.equal(element._plugins[2].index_url, 'plugins/test3/');
|
||||
assert.equal(element._plugins[2].version, '3.0-SNAPSHOT');
|
||||
assert.equal(element._plugins[2].disabled, false);
|
||||
assert.equal(element._plugins[4].id, 'test5');
|
||||
assert.equal(element._plugins[4].index_url, 'plugins/test5/');
|
||||
assert.equal(element._plugins[4].version, 'version-5');
|
||||
assert.equal(element._plugins[4].api_version, 'api-version-5');
|
||||
assert.equal(element._plugins[4].disabled, false);
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -80,6 +86,25 @@ suite('gr-plugin-list tests', () => {
|
||||
});
|
||||
});
|
||||
|
||||
test('versions', done => {
|
||||
flush(() => {
|
||||
const versions = Polymer.dom(element.root).querySelectorAll('.version');
|
||||
assert.equal(versions[2].innerText, 'version-2');
|
||||
assert.equal(versions[3].innerText, '--');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('api versions', done => {
|
||||
flush(() => {
|
||||
const apiVersions = Polymer.dom(element.root).querySelectorAll(
|
||||
'.apiVersion');
|
||||
assert.equal(apiVersions[3].innerText, 'api-version-3');
|
||||
assert.equal(apiVersions[4].innerText, '--');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('_shownPlugins', () => {
|
||||
assert.equal(element._shownPlugins.length, 25);
|
||||
});
|
||||
|
||||
@@ -345,7 +345,8 @@ fi
|
||||
|
||||
test -z "$GERRIT_USER" && GERRIT_USER=`whoami`
|
||||
RUN_ARGS="-jar $GERRIT_WAR daemon -d $GERRIT_SITE"
|
||||
if test "`get_config --bool container.slave`" = "true" ; then
|
||||
if test "`get_config --bool container.slave`" = "true" || \
|
||||
test "`get_config --bool container.replica`" = "true"; then
|
||||
RUN_ARGS="$RUN_ARGS --replica --enable-httpd --headless"
|
||||
fi
|
||||
DAEMON_OPTS=`get_config --get-all container.daemonOpt`
|
||||
|
||||
@@ -68,7 +68,7 @@ def gerrit_plugin(
|
||||
"export TZ",
|
||||
"GEN_VERSION=$$(cat bazel-out/stable-status.txt | grep -w STABLE_BUILD_%s_LABEL | cut -d ' ' -f 2)" % dir_name.upper(),
|
||||
"cd $$TMP",
|
||||
"unzip -q $$ROOT/$<",
|
||||
"unzip -qo $$ROOT/$<",
|
||||
"echo \"Implementation-Version: $$GEN_VERSION\n$$(cat META-INF/MANIFEST.MF)\" > META-INF/MANIFEST.MF",
|
||||
"find . -exec touch '{}' ';'",
|
||||
"zip -Xqr $$ROOT/$@ .",
|
||||
|
||||
@@ -23,8 +23,8 @@ def declare_nongoogle_deps():
|
||||
|
||||
maven_jar(
|
||||
name = "dropwizard-core",
|
||||
artifact = "io.dropwizard.metrics:metrics-core:4.1.9",
|
||||
sha1 = "dd76a62b007ffea9e6aba10f64c04173ef65f895",
|
||||
artifact = "io.dropwizard.metrics:metrics-core:4.1.10.1",
|
||||
sha1 = "e55d1e4de0ccec6f404dbf775c62626d8b9f79a4",
|
||||
)
|
||||
|
||||
SSHD_VERS = "2.4.0"
|
||||
|
||||
Reference in New Issue
Block a user