Merge changes from topic 'ssh-keys-in-git'
* changes:
Don't add the same SSH key several times
Store SSH keys in git
Support deletion of SSH keys in extension API
diff --git a/Documentation/rest-api-accounts.txt b/Documentation/rest-api-accounts.txt
index 0fae667..ae42477 100644
--- a/Documentation/rest-api-accounts.txt
+++ b/Documentation/rest-api-accounts.txt
@@ -1108,11 +1108,13 @@
"changes_per_page": 25,
"show_site_header": true,
"use_flash_clipboard": true,
+ "download_command": "CHECKOUT",
"date_format": "STD",
"time_format": "HHMM_12",
+ "diff_view": "SIDE_BY_SIDE",
"size_bar_in_change_table": true,
"review_category_strategy": "ABBREV",
- "diff_view": "SIDE_BY_SIDE",
+ "mute_common_path_prefixes": true,
"my": [
{
"url": "#/dashboard/self",
@@ -1162,11 +1164,13 @@
"changes_per_page": 50,
"show_site_header": true,
"use_flash_clipboard": true,
+ "download_command": "CHECKOUT",
"date_format": "STD",
"time_format": "HHMM_12",
"size_bar_in_change_table": true,
"review_category_strategy": "NAME",
"diff_view": "SIDE_BY_SIDE",
+ "mute_common_path_prefixes": true,
"my": [
{
"url": "#/dashboard/self",
@@ -1210,11 +1214,13 @@
"changes_per_page": 50,
"show_site_header": true,
"use_flash_clipboard": true,
+ "download_command": "CHECKOUT",
"date_format": "STD",
"time_format": "HHMM_12",
"size_bar_in_change_table": true,
"review_category_strategy": "NAME",
"diff_view": "SIDE_BY_SIDE",
+ "mute_common_path_prefixes": true,
"my": [
{
"url": "#/dashboard/self",
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/SetPreferences.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/SetPreferences.java
index b70cabd..eb32e5a 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/account/SetPreferences.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/SetPreferences.java
@@ -140,7 +140,7 @@
}
}
- public static void storeUrlAliases(VersionedAccountPreferences prefs,
+ private static void storeUrlAliases(VersionedAccountPreferences prefs,
Map<String, String> urlAliases) {
if (urlAliases != null) {
Config cfg = prefs.getConfig();
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/config/SetPreferences.java b/gerrit-server/src/main/java/com/google/gerrit/server/config/SetPreferences.java
index 4c5ab65..bbf2299 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/config/SetPreferences.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/config/SetPreferences.java
@@ -60,6 +60,8 @@
|| i.legacycidInChangeTable != null
|| i.muteCommonPathPrefixes != null
|| i.reviewCategoryStrategy != null
+ || i.signedOffBy != null
+ || i.urlAliases != null
|| i.emailStrategy != null) {
throw new BadRequestException("unsupported option");
}
diff --git a/lib/asciidoctor/java/AsciiDoctor.java b/lib/asciidoctor/java/AsciiDoctor.java
index 667f274..8e18feb1 100644
--- a/lib/asciidoctor/java/AsciiDoctor.java
+++ b/lib/asciidoctor/java/AsciiDoctor.java
@@ -151,6 +151,7 @@
}
File[] cssFiles = tmpdir.listFiles(new FilenameFilter() {
+ @Override
public boolean accept(File dir, String name) {
return name.endsWith(".css");
}
diff --git a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.html b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.html
index d94a828..1066625 100644
--- a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.html
+++ b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.html
@@ -16,7 +16,6 @@
<link rel="import" href="../../../bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/keyboard-shortcut-behavior.html">
-<link rel="import" href="../../shared/gr-request/gr-request.html">
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
<dom-module id="gr-file-list">
diff --git a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.html b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.html
index ad2b925..71fee37 100644
--- a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.html
+++ b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.html
@@ -19,7 +19,6 @@
<link rel="import" href="../../../bower_components/iron-selector/iron-selector.html">
<link rel="import" href="../../../behaviors/rest-client-behavior.html">
<link rel="import" href="../../shared/gr-button/gr-button.html">
-<link rel="import" href="../../shared/gr-request/gr-request.html">
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
<dom-module id="gr-reply-dialog">
diff --git a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.js b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.js
index 1cd0ce2..47324ba 100644
--- a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.js
+++ b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.js
@@ -46,7 +46,6 @@
permittedLabels: Object,
_account: Object,
- _xhrPromise: Object, // Used for testing.
},
behaviors: [
@@ -140,26 +139,24 @@
obj.message = this.draft;
}
this.disabled = true;
- this._send(obj).then(function(req) {
- this.fire('send', null, {bubbles: false});
- this.draft = '';
+ this._saveReview(obj).then(function(response) {
this.disabled = false;
- }.bind(this)).catch(function(err) {
- alert('Oops. Something went wrong. Check the console and bug the ' +
- 'PolyGerrit team for assistance.');
- throw err;
+ if (!response.ok) {
+ alert('Oops. Something went wrong. Check the console and bug the ' +
+ 'PolyGerrit team for assistance.');
+ return response.text().then(function(text) {
+ console.error(text);
+ });
+ }
+
+ this.draft = '';
+ this.fire('send', null, {bubbles: false});
}.bind(this));
},
- _send: function(payload) {
- var xhr = document.createElement('gr-request');
- this._xhrPromise = xhr.send({
- method: 'POST',
- url: this.changeBaseURL(this.changeNum, this.patchNum) + '/review',
- body: payload,
- });
-
- return this._xhrPromise;
+ _saveReview: function(review) {
+ return this.$.restAPI.saveChangeReview(this.changeNum, this.patchNum,
+ review);
},
});
})();
diff --git a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_test.html b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_test.html
index fb2de6a..bc850e3 100644
--- a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_test.html
+++ b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_test.html
@@ -34,11 +34,10 @@
<script>
suite('gr-reply-dialog tests', function() {
var element;
- var server;
setup(function() {
- stub('gr-reply-dialog', {
- _getAccount: function() { return Promise.resolve({}); },
+ stub('gr-rest-api-interface', {
+ getAccount: function() { return Promise.resolve({}); },
});
element = fixture('basic');
element.changeNum = 42;
@@ -76,31 +75,10 @@
]
};
- server = sinon.fakeServer.create();
- server.respondWith(
- 'POST',
- '/changes/42/revisions/1/review',
- [
- 200,
- {'Content-Type': 'application/json'},
- ')]}\'\n' +
- '{' +
- '"labels": {' +
- '"Code-Review": -1,' +
- '"Verified": -1' +
- '}' +
- '}'
- ]
- );
-
// Allow the elements created by dom-repeat to be stamped.
flushAsynchronousOperations();
});
- teardown(function() {
- server.restore();
- });
-
test('cancel event', function(done) {
element.addEventListener('cancel', function() { done(); });
MockInteractions.tap(element.$$('.cancel'));
@@ -122,32 +100,32 @@
'iron-selector[data-label="Verified"] > ' +
'gr-button[data-value="-1"]'));
+ var saveReviewStub = sinon.stub(element, '_saveReview',
+ function(review) {
+ assert.deepEqual(review, {
+ drafts: 'PUBLISH_ALL_REVISIONS',
+ labels: {
+ 'Code-Review': -1,
+ 'Verified': -1
+ },
+ message: 'I wholeheartedly disapprove'
+ });
+ return Promise.resolve({ok: true});
+ });
+
+ element.addEventListener('send', function() {
+ assert.isFalse(element.disabled,
+ 'Element should be enabled when done sending reply.');
+ assert.equal(element.draft.length, 0);
+ saveReviewStub.restore();
+ done();
+ });
+
// This is needed on non-Blink engines most likely due to the ways in
// which the dom-repeat elements are stamped.
flush(function() {
MockInteractions.tap(element.$$('.send'));
assert.isTrue(element.disabled);
-
- server.respond();
-
- element._xhrPromise.then(function(req) {
- assert.isFalse(element.disabled,
- 'Element should be enabled when done sending reply.');
- assert.equal(req.status, 200);
- assert.equal(req.url, '/changes/42/revisions/1/review');
- var reqObj = JSON.parse(req.xhr.requestBody);
- assert.deepEqual(reqObj, {
- drafts: 'PUBLISH_ALL_REVISIONS',
- labels: {
- 'Code-Review': -1,
- 'Verified': -1
- },
- message: 'I wholeheartedly disapprove'
- });
- assert.equal(req.response.labels['Code-Review'], -1);
- assert.equal(req.response.labels.Verified, -1);
- done();
- });
});
});
});
diff --git a/polygerrit-ui/app/elements/shared/gr-alert/gr-alert.html b/polygerrit-ui/app/elements/shared/gr-alert/gr-alert.html
new file mode 100644
index 0000000..28e45a4
--- /dev/null
+++ b/polygerrit-ui/app/elements/shared/gr-alert/gr-alert.html
@@ -0,0 +1,58 @@
+<!--
+Copyright (C) 2016 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.
+-->
+
+<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="../gr-button/gr-button.html">
+
+<dom-module id="gr-alert">
+ <template>
+ <style>
+ /**
+ * ALERT: DO NOT ADD TRANSITION PROPERTIES WITHOUT PROPERLY UNDERSTANDING
+ * HOW THEY ARE USED IN THE CODE.
+ */
+ :host([toast]) {
+ background-color: #333;
+ bottom: 1.25rem;
+ border-radius: 3px;
+ box-shadow: 0 1px 3px rgba(0, 0, 0, .3);
+ color: #fff;
+ left: 1.25rem;
+ padding: 1em 1.5em;
+ position: fixed;
+ transform: translateY(5rem);
+ transition: transform var(--gr-alert-transition-duration, 80ms) ease-out;
+ }
+ :host([shown]) {
+ transform: translateY(0);
+ }
+ .action {
+ color: #a1c2fa;
+ font-weight: bold;
+ margin-left: 1em;
+ text-decoration: none;
+ }
+ </style>
+ [[text]]
+ <gr-button
+ link
+ class="action"
+ hidden$="[[!actionText]]"
+ on-tap="_handleActionTap">[[actionText]]</gr-button>
+ </template>
+ <script src="gr-alert.js"></script>
+</dom-module>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-alert/gr-alert.js b/polygerrit-ui/app/elements/shared/gr-alert/gr-alert.js
new file mode 100644
index 0000000..ba481ec
--- /dev/null
+++ b/polygerrit-ui/app/elements/shared/gr-alert/gr-alert.js
@@ -0,0 +1,88 @@
+// Copyright (C) 2016 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.
+(function() {
+ 'use strict';
+
+ Polymer({
+ is: 'gr-alert',
+
+ /**
+ * Fired when the action button is pressed.
+ *
+ * @event action
+ */
+
+ properties: {
+ text: String,
+ actionText: String,
+ shown: {
+ type: Boolean,
+ value: true,
+ readOnly: true,
+ reflectToAttribute: true,
+ },
+ toast: {
+ type: Boolean,
+ value: true,
+ reflectToAttribute: true,
+ },
+
+ _boundTransitionEndHandler: {
+ type: Function,
+ value: function() { return this._handleTransitionEnd.bind(this); },
+ },
+ },
+
+ attached: function() {
+ this.addEventListener('transitionend', this._boundTransitionEndHandler);
+ },
+
+ detached: function() {
+ this.removeEventListener('transitionend',
+ this._boundTransitionEndHandler);
+ },
+
+ show: function(text, opt_actionText) {
+ this.text = text;
+ this.actionText = opt_actionText;
+ document.body.appendChild(this);
+ this._setShown(true);
+ },
+
+ hide: function() {
+ this._setShown(false);
+ if (this._hasZeroTransitionDuration()) {
+ document.body.removeChild(this);
+ }
+ },
+
+ _hasZeroTransitionDuration: function() {
+ var style = window.getComputedStyle(this);
+ // transitionDuration is always given in seconds.
+ var duration = Math.round(parseFloat(style.transitionDuration) * 100);
+ return duration === 0;
+ },
+
+ _handleTransitionEnd: function(e) {
+ if (this.shown) { return; }
+
+ document.body.removeChild(this);
+ },
+
+ _handleActionTap: function(e) {
+ e.preventDefault();
+ this.fire('action', null, {bubbles: false});
+ },
+ });
+})();
diff --git a/polygerrit-ui/app/elements/shared/gr-alert/gr-alert_test.html b/polygerrit-ui/app/elements/shared/gr-alert/gr-alert_test.html
new file mode 100644
index 0000000..067ac5b
--- /dev/null
+++ b/polygerrit-ui/app/elements/shared/gr-alert/gr-alert_test.html
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<!--
+Copyright (C) 2015 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.
+-->
+
+<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
+<title>gr-alert</title>
+
+<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
+<script src="../../../bower_components/web-component-tester/browser.js"></script>
+
+<link rel="import" href="../../../bower_components/iron-test-helpers/iron-test-helpers.html">
+<link rel="import" href="gr-alert.html">
+
+<script>
+ suite('gr-alert tests', function() {
+ var element;
+
+ setup(function() {
+ element = document.createElement('gr-alert');
+ });
+
+ teardown(function() {
+ if (element.parentNode) {
+ element.parentNode.removeChild(element);
+ }
+ });
+
+ test('show/hide', function() {
+ assert.isNull(element.parentNode);
+ element.show();
+ assert.equal(element.parentNode, document.body);
+ element.customStyle['--gr-alert-transition-duration'] = '0ms';
+ element.updateStyles();
+ element.hide();
+ assert.isNull(element.parentNode);
+ });
+
+ test('action event', function(done) {
+ element.show();
+ element.addEventListener('action', function() {
+ done();
+ });
+ MockInteractions.tap(element.$$('.action'));
+ });
+
+ });
+</script>
diff --git a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js
index f23d50b..54ce15c 100644
--- a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js
+++ b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js
@@ -325,6 +325,12 @@
return this.send(method, url, null, opt_errFn, opt_ctx);
},
+ saveChangeReview: function(changeNum, patchNum, review, opt_errFn,
+ opt_ctx) {
+ var url = this.getChangeActionURL(changeNum, patchNum, '/review');
+ return this.send('POST', url, review, opt_errFn, opt_ctx);
+ },
+
send: function(method, url, opt_body, opt_errFn, opt_ctx) {
var headers = new Headers({
'X-Gerrit-Auth': this._getCookie('XSRF_TOKEN'),
diff --git a/polygerrit-ui/app/test/index.html b/polygerrit-ui/app/test/index.html
index 4238f9a..dc12bf9 100644
--- a/polygerrit-ui/app/test/index.html
+++ b/polygerrit-ui/app/test/index.html
@@ -48,6 +48,7 @@
'../elements/diff/gr-diff-preferences/gr-diff-preferences_test.html',
'../elements/diff/gr-diff-view/gr-diff-view_test.html',
'../elements/diff/gr-patch-range-select/gr-patch-range-select_test.html',
+ '../elements/shared/gr-alert/gr-alert_test.html',
'../elements/shared/gr-account-label/gr-account-label_test.html',
'../elements/shared/gr-account-link/gr-account-link_test.html',
'../elements/shared/gr-avatar/gr-avatar_test.html',