Merge changes I1a7e024c,Ia2bfd2cf * changes: Add comments about decoding fields from change index ElasticChangeIndex: Decode hashtags and stars
diff --git a/.gitignore b/.gitignore index 5e9b659..d75067d 100644 --- a/.gitignore +++ b/.gitignore
@@ -1,5 +1,4 @@ # Keep following lines sorted according to `LC_COLLATE=C sort` -*.asc *.eml *.iml *.pyc
diff --git a/java/com/google/gerrit/common/BUILD b/java/com/google/gerrit/common/BUILD index ceb060a..5f3c1ec 100644 --- a/java/com/google/gerrit/common/BUILD +++ b/java/com/google/gerrit/common/BUILD
@@ -35,6 +35,7 @@ ["**/*.java"], exclude = ANNOTATIONS, ), + resources = [":Version"], visibility = ["//visibility:public"], deps = [ ":annotations", @@ -51,20 +52,9 @@ ], ) -java_import( - name = "version", - jars = [":gen_version"], - visibility = ["//visibility:public"], -) - -genrule2( +genrule( name = "gen_version", - outs = ["gen_version.jar"], - cmd = " && ".join([ - "cd $$TMP", - "mkdir -p com/google/gerrit/common", - "cat $$ROOT/$(location //:version.txt) >com/google/gerrit/common/Version", - "zip -9Dqr $$ROOT/$@ .", - ]), - tools = ["//:version.txt"], + srcs = ["//:version.txt"], + outs = ["Version"], + cmd = "cat $< > $@", )
diff --git a/java/com/google/gerrit/common/Version.java b/java/com/google/gerrit/common/Version.java index 8d902a7..1777c3c 100644 --- a/java/com/google/gerrit/common/Version.java +++ b/java/com/google/gerrit/common/Version.java
@@ -17,6 +17,7 @@ import static java.nio.charset.StandardCharsets.UTF_8; import com.google.common.annotations.GwtIncompatible; +import com.google.common.annotations.VisibleForTesting; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; @@ -27,20 +28,23 @@ @GwtIncompatible("Unemulated com.google.gerrit.common.Version") public class Version { private static final Logger log = LoggerFactory.getLogger(Version.class); - private static final String version; + + @VisibleForTesting static final String DEV = "(dev)"; + + private static final String VERSION; public static String getVersion() { - return version; + return VERSION; } static { - version = loadVersion(); + VERSION = loadVersion(); } private static String loadVersion() { try (InputStream in = Version.class.getResourceAsStream("Version")) { if (in == null) { - return "(dev)"; + return DEV; } try (BufferedReader r = new BufferedReader(new InputStreamReader(in, UTF_8))) { String vs = r.readLine();
diff --git a/java/com/google/gerrit/launcher/GerritLauncher.java b/java/com/google/gerrit/launcher/GerritLauncher.java index 0e1b91a..618d754 100644 --- a/java/com/google/gerrit/launcher/GerritLauncher.java +++ b/java/com/google/gerrit/launcher/GerritLauncher.java
@@ -38,6 +38,7 @@ import java.nio.file.Paths; import java.security.CodeSource; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; @@ -595,8 +596,27 @@ } /** + * Check whether the process is running in Eclipse. + * + * <p>Unlike {@link #getDeveloperEclipseOut()}, this method checks the actual runtime stack, not + * the classpath. + * + * @return true if any thread has a stack frame in {@code org.eclipse.jdt}. + */ + public static boolean isRunningInEclipse() { + return Thread.getAllStackTraces() + .values() + .stream() + .flatMap(Arrays::stream) + .anyMatch(e -> e.getClassName().startsWith("org.eclipse.jdt.")); + } + + /** * Locate the path of the {@code eclipse-out} directory in a source tree. * + * <p>Unlike {@link #isRunningInEclipse()}, this method only inspects files relative to the + * classpath, not the runtime stack. + * * @return local path of the {@code eclipse-out} directory in a source tree. * @throws FileNotFoundException if the directory cannot be found. */ @@ -669,7 +689,7 @@ } private static ClassLoader useDevClasspath() throws MalformedURLException, FileNotFoundException { - Path out = resolveInSourceRoot("eclipse-out"); + Path out = getDeveloperEclipseOut(); List<URL> dirs = new ArrayList<>(); dirs.add(out.resolve("classes").toUri().toURL()); ClassLoader cl = GerritLauncher.class.getClassLoader();
diff --git a/javatests/com/google/gerrit/common/BUILD b/javatests/com/google/gerrit/common/BUILD index 64a2a46..ca04a4a 100644 --- a/javatests/com/google/gerrit/common/BUILD +++ b/javatests/com/google/gerrit/common/BUILD
@@ -1,12 +1,15 @@ load("//tools/bzl:junit.bzl", "junit_tests") -AUTO_VALUE_TEST_SRCS = ["AutoValueTest.java"] +SERVER_TEST_SRCS = [ + "AutoValueTest.java", + "VersionTest.java", +] junit_tests( name = "client_tests", srcs = glob( ["**/*.java"], - exclude = AUTO_VALUE_TEST_SRCS, + exclude = SERVER_TEST_SRCS, ), deps = [ "//java/com/google/gerrit/common:client", @@ -17,9 +20,12 @@ ) junit_tests( - name = "auto_value_tests", - srcs = AUTO_VALUE_TEST_SRCS, + name = "server_tests", + srcs = SERVER_TEST_SRCS, deps = [ + "//java/com/google/gerrit/common:server", + "//java/com/google/gerrit/launcher", + "//lib:guava", "//lib:truth", "//lib/auto:auto-value", ],
diff --git a/javatests/com/google/gerrit/common/VersionTest.java b/javatests/com/google/gerrit/common/VersionTest.java new file mode 100644 index 0000000..bceb203 --- /dev/null +++ b/javatests/com/google/gerrit/common/VersionTest.java
@@ -0,0 +1,63 @@ +// Copyright (C) 2017 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.common; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.collect.ImmutableList; +import com.google.gerrit.launcher.GerritLauncher; +import java.util.regex.Pattern; +import org.junit.Test; + +public final class VersionTest { + private static final Pattern DEV_PATTERN = + Pattern.compile("^" + Pattern.quote(Version.DEV) + "$"); + + private static final Pattern GIT_DESCRIBE_PATTERN = + Pattern.compile( + "^[1-9]+\\.[0-9]+(\\.[0-9]+)*(-rc[0-9]+)?(-[0-9]+" + "-g[0-9a-f]{7,})?(-dirty)?$"); + + @Test + public void version() { + Pattern expected = + GerritLauncher.isRunningInEclipse() + ? DEV_PATTERN // Different source line so it shows up in coverage. + : GIT_DESCRIBE_PATTERN; + assertThat(Version.getVersion()).matches(expected); + // Try again in case of caching issues. + assertThat(Version.getVersion()).matches(expected); + } + + @Test + public void gitDescribePattern() { + for (String suffix : ImmutableList.of("", "-dirty")) { + assertThat("2.15-rc0" + suffix).matches(GIT_DESCRIBE_PATTERN); + assertThat("2.15-rc0" + suffix).matches(GIT_DESCRIBE_PATTERN); + assertThat("2.15-rc1" + suffix).matches(GIT_DESCRIBE_PATTERN); + assertThat("2.15" + suffix).matches(GIT_DESCRIBE_PATTERN); + assertThat("2.15.1" + suffix).matches(GIT_DESCRIBE_PATTERN); + assertThat("2.15.1.2" + suffix).matches(GIT_DESCRIBE_PATTERN); + assertThat("2.15.1.2.3" + suffix).matches(GIT_DESCRIBE_PATTERN); + assertThat("2.15.1-rc1" + suffix).matches(GIT_DESCRIBE_PATTERN); + assertThat("2.15-rc2-123-gabcd123" + suffix).matches(GIT_DESCRIBE_PATTERN); + assertThat("2.15-123-gabcd123" + suffix).matches(GIT_DESCRIBE_PATTERN); + } + + assertThat("2.15-ugly").doesNotMatch(GIT_DESCRIBE_PATTERN); + assertThat("(dev)").doesNotMatch(GIT_DESCRIBE_PATTERN); + assertThat("1").doesNotMatch(GIT_DESCRIBE_PATTERN); + assertThat("v2.15").doesNotMatch(GIT_DESCRIBE_PATTERN); + } +}
diff --git a/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view.html b/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view.html index 86b1ae4..3850894 100644 --- a/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view.html +++ b/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view.html
@@ -23,7 +23,6 @@ <link rel="import" href="../../../styles/shared-styles.html"> <link rel="import" href="../../core/gr-navigation/gr-navigation.html"> <link rel="import" href="../../shared/gr-page-nav/gr-page-nav.html"> -<link rel="import" href="../../shared/gr-placeholder/gr-placeholder.html"> <link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html"> <link rel="import" href="../gr-admin-group-list/gr-admin-group-list.html"> <link rel="import" href="../gr-group/gr-group.html"> @@ -133,9 +132,6 @@ project="[[params.project]]"></gr-project-access> </main> </template> - <template is="dom-if" if="[[params.placeholder]]" restamp="true"> - <gr-placeholder title="Admin" path="[[path]]"></gr-placeholder> - </template> <gr-rest-api-interface id="restAPI"></gr-rest-api-interface> </template> <script src="gr-admin-view.js"></script>
diff --git a/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item.js b/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item.js index 79f06fe..aa40a6e 100644 --- a/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item.js +++ b/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item.js
@@ -104,7 +104,7 @@ }, _computeProjectURL(project) { - return Gerrit.Nav.getUrlForProject(project, true); + return Gerrit.Nav.getUrlForProjectChanges(project, true); }, _computeProjectBranchURL(change) {
diff --git a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.js b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.js index e95c494..32fa7a6 100644 --- a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.js +++ b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.js
@@ -314,7 +314,7 @@ }, _computeProjectURL(project) { - return Gerrit.Nav.getUrlForProject(project); + return Gerrit.Nav.getUrlForProjectChanges(project); }, _computeBranchURL(project, branch) {
diff --git a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js index 21cd100..02a0514 100644 --- a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js +++ b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js
@@ -39,6 +39,8 @@ const REPLY_REFIT_DEBOUNCE_INTERVAL_MS = 500; + const TRAILING_WHITESPACE_REGEX = /[ \t]+$/gm; + Polymer({ is: 'gr-change-view', @@ -298,7 +300,8 @@ }, _handleCommitMessageSave(e) { - const message = e.detail.content; + // Trim trailing whitespace from each line. + const message = e.detail.content.replace(TRAILING_WHITESPACE_REGEX, ''); this.$.jsAPI.handleCommitMessage(this._change, message);
diff --git a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.html b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.html index 6c95046..d0f3d90 100644 --- a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.html +++ b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.html
@@ -638,6 +638,22 @@ _change)); }); + test('_handleCommitMessageSave trims trailing whitespace', () => { + const putStub = sandbox.stub(element.$.restAPI, 'putChangeCommitMessage') + .returns(Promise.resolve({})); + + const mockEvent = content => { return {detail: {content}}; }; + + element._handleCommitMessageSave(mockEvent('test \n test ')); + assert.equal(putStub.lastCall.args[1], 'test\n test'); + + element._handleCommitMessageSave(mockEvent(' test\ntest')); + assert.equal(putStub.lastCall.args[1], ' test\ntest'); + + element._handleCommitMessageSave(mockEvent('\n\n\n\n\n\n\n\n')); + assert.equal(putStub.lastCall.args[1], '\n\n\n\n\n\n\n\n'); + }); + test('_computeChangeIdCommitMessageError', () => { let commitMessage = 'Change-Id: I4ce18b2395bca69d7a9aa48bf4554faa56282483';
diff --git a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.js b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.js index 054f0f1..ac15882 100644 --- a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.js +++ b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.js
@@ -430,6 +430,10 @@ }, _getFiles() { + if (this.editLoaded) { + return this.$.restAPI.getChangeEditFilesAsSpeciallySortedArray( + this.changeNum, this.patchRange); + } return this.$.restAPI.getChangeFilesAsSpeciallySortedArray( this.changeNum, this.patchRange); },
diff --git a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_test.html b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_test.html index be03e38..7e9f843 100644 --- a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_test.html +++ b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_test.html
@@ -116,6 +116,48 @@ }); }); + test('get file list with change edit', done => { + element.editLoaded = true; + + sandbox.stub(element.$.restAPI, + 'getChangeEditFiles', () => { + return Promise.resolve({ + commit: {}, + files: { + '/COMMIT_MSG': { + lines_inserted: 9, + }, + 'tags.html': { + lines_deleted: 123, + }, + 'about.txt': {}, + }, + }); + }); + + element._getFiles().then(files => { + const filenames = files.map(f => { return f.__path; }); + assert.deepEqual(filenames, ['/COMMIT_MSG', 'about.txt', 'tags.html']); + assert.deepEqual(files[0], { + lines_inserted: 9, + lines_deleted: 0, + __path: '/COMMIT_MSG', + }); + assert.deepEqual(files[1], { + lines_inserted: 0, + lines_deleted: 0, + __path: 'about.txt', + }); + assert.deepEqual(files[2], { + lines_inserted: 0, + lines_deleted: 123, + __path: 'tags.html', + }); + + done(); + }); + }); + test('calculate totals for patch number', () => { element._files = [ {__path: '/COMMIT_MSG', lines_inserted: 9},
diff --git a/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.html b/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.html index 6ff78d8..afb3585 100644 --- a/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.html +++ b/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.html
@@ -130,7 +130,7 @@ * the project. * @return {string} */ - getUrlForProject(project, opt_openOnly) { + getUrlForProjectChanges(project, opt_openOnly) { return this._getUrlFor({ view: Gerrit.Nav.View.SEARCH, project,
diff --git a/polygerrit-ui/app/elements/core/gr-router/gr-router.js b/polygerrit-ui/app/elements/core/gr-router/gr-router.js index e76fecb..aefc3b9 100644 --- a/polygerrit-ui/app/elements/core/gr-router/gr-router.js +++ b/polygerrit-ui/app/elements/core/gr-router/gr-router.js
@@ -20,7 +20,6 @@ DASHBOARD: /^\/dashboard\/(.+)$/, CUSTOM_DASHBOARD: /^\/dashboard\/?$/, - ADMIN_PLACEHOLDER: '/admin/(.*)', AGREEMENTS: /^\/settings\/(agreements|new-agreement)/, REGISTER: /^\/register(\/.*)?$/, @@ -600,9 +599,6 @@ this._mapRoute(RoutePattern.PLUGIN_LIST, '_handlePluginListRoute', true); - this._mapRoute(RoutePattern.ADMIN_PLACEHOLDER, - '_handleAdminPlaceholderRoute', true); - this._mapRoute(RoutePattern.QUERY, '_handleQueryRoute'); this._mapRoute(RoutePattern.CHANGE_NUMBER_LEGACY, @@ -1003,12 +999,6 @@ }); }, - _handleAdminPlaceholderRoute(data) { - data.params.view = Gerrit.Nav.View.ADMIN; - data.params.placeholder = true; - this._setParams(data.params); - }, - _handleQueryRoute(data) { this._setParams({ view: Gerrit.Nav.View.SEARCH,
diff --git a/polygerrit-ui/app/elements/core/gr-router/gr-router_test.html b/polygerrit-ui/app/elements/core/gr-router/gr-router_test.html index b6ee5b5..c2b46f8 100644 --- a/polygerrit-ui/app/elements/core/gr-router/gr-router_test.html +++ b/polygerrit-ui/app/elements/core/gr-router/gr-router_test.html
@@ -123,7 +123,6 @@ actualDoesNotRequireAuth.sort(); const shouldRequireAutoAuth = [ - '_handleAdminPlaceholderRoute', '_handleAgreementsRoute', '_handleCreateGroupRoute', '_handleCreateProjectRoute', @@ -522,13 +521,6 @@ setParamsStub = sandbox.stub(element, '_setParams'); }); - test('_handleAdminPlaceholderRoute', () => { - element._handleAdminPlaceholderRoute({params: {}}); - assert.equal(setParamsStub.lastCall.args[0].view, - Gerrit.Nav.View.ADMIN); - assert.isTrue(setParamsStub.lastCall.args[0].placeholder); - }); - test('_handleAgreementsRoute', () => { element._handleAgreementsRoute({params: {}}); assert.isTrue(setParamsStub.calledOnce);
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder.html b/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder.html index dd18b65..1cfab26 100644 --- a/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder.html +++ b/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder.html
@@ -24,7 +24,7 @@ <dom-module id="gr-diff-builder"> <template> <div class="contentWrapper"> - <content></content> + <slot></slot> </div> <gr-ranged-comment-layer id="rangeLayer"
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-comment/gr-diff-comment.html b/polygerrit-ui/app/elements/diff/gr-diff-comment/gr-diff-comment.html index 335ed36..dc75073 100644 --- a/polygerrit-ui/app/elements/diff/gr-diff-comment/gr-diff-comment.html +++ b/polygerrit-ui/app/elements/diff/gr-diff-comment/gr-diff-comment.html
@@ -46,7 +46,8 @@ :host([disabled]) { pointer-events: none; } - :host([disabled]) .container { + :host([disabled]) .body, + :host([disabled]) .date { opacity: .5; } :host([is-robot-comment]) { @@ -210,6 +211,12 @@ #deleteBtn.showDeleteButtons { display: block; } + #savingMessage { + display: none; + } + :host([disabled]) #savingMessage { + display: inline; + } </style> <div id="container" class="container" @@ -224,6 +231,7 @@ title="This draft is only visible to you. To publish drafts, click the red 'Reply' button at the top of the change or press the 'A' key." max-width="20em" show-icon></gr-tooltip-content> + <span id="savingMessage">[[_savingMessage]]</span> </div> <div class="headerMiddle"> <span class="collapsedContent">[[comment.message]]</span> @@ -249,64 +257,66 @@ </label> </div> </div> - <template is="dom-if" if="[[comment.robot_id]]"> - <div class="robotId" hidden$="[[collapsed]]"> - [[comment.robot_id]] + <div class="body"> + <template is="dom-if" if="[[comment.robot_id]]"> + <div class="robotId" hidden$="[[collapsed]]"> + [[comment.robot_id]] + </div> + </template> + <gr-textarea + id="editTextarea" + class="editMessage" + autocomplete="on" + monospace + disabled="{{disabled}}" + rows="4" + text="{{_messageText}}"></gr-textarea> + <gr-formatted-text class="message" + content="[[comment.message]]" + no-trailing-margin="[[!comment.__draft]]" + collapsed="[[collapsed]]" + config="[[projectConfig.commentlinks]]"></gr-formatted-text> + <div hidden$="[[!comment.robot_run_id]]"> + <div class="runIdInformation" hidden$="[[collapsed]]"> + Run ID: + <a class="robotRunLink" href$="[[comment.url]]"> + <span class="robotRun">[[comment.robot_run_id]]</span> + </a> + </div> </div> - </template> - <gr-textarea - id="editTextarea" - class="editMessage" - autocomplete="on" - monospace - disabled="{{disabled}}" - rows="4" - text="{{_messageText}}"></gr-textarea> - <gr-formatted-text class="message" - content="[[comment.message]]" - no-trailing-margin="[[!comment.__draft]]" - collapsed="[[collapsed]]" - config="[[projectConfig.commentlinks]]"></gr-formatted-text> - <div hidden$="[[!comment.robot_run_id]]"> - <div class="runIdInformation" hidden$="[[collapsed]]"> - Run ID: - <a class="robotRunLink" href$="[[comment.url]]"> - <span class="robotRun">[[comment.robot_run_id]]</span> - </a> + <div class="actions humanActions" hidden$="[[!_showHumanActions]]"> + <div class="action resolve hideOnPublished"> + <label> + <input type="checkbox" + checked$="[[resolved]]" + on-change="_handleToggleResolved"> + Resolved + </label> + </div> + <div class="action unresolved hideOnPublished" hidden$="[[resolved]]"> + Unresolved + </div> + <div class="rightActions"> + <gr-button link class="action cancel hideOnPublished" + on-tap="_handleCancel" hidden>Cancel</gr-button> + <gr-button link class="action discard hideOnPublished" + on-tap="_handleDiscard">Discard</gr-button> + <gr-button link class="action edit hideOnPublished" + on-tap="_handleEdit">Edit</gr-button> + <gr-button link class="action save hideOnPublished" + on-tap="_handleSave" + disabled$="[[_computeSaveDisabled(_messageText)]]">Save + </gr-button> + </div> </div> - </div> - <div class="actions humanActions" hidden$="[[!_showHumanActions]]"> - <div class="action resolve hideOnPublished"> - <label> - <input type="checkbox" - checked$="[[resolved]]" - on-change="_handleToggleResolved"> - Resolved - </label> - </div> - <div class="action unresolved hideOnPublished" hidden$="[[resolved]]"> - Unresolved - </div> - <div class="rightActions"> - <gr-button link class="action cancel hideOnPublished" - on-tap="_handleCancel" hidden>Cancel</gr-button> - <gr-button link class="action discard hideOnPublished" - on-tap="_handleDiscard">Discard</gr-button> - <gr-button link class="action edit hideOnPublished" - on-tap="_handleEdit">Edit</gr-button> - <gr-button link class="action save hideOnPublished" - on-tap="_handleSave" - disabled$="[[_computeSaveDisabled(_messageText)]]">Save + <div class="actions robotActions" hidden$="[[!_showRobotActions]]"> + <gr-button link class="action fix" + on-tap="_handleFix" + disabled="[[robotButtonDisabled]]"> + Please Fix </gr-button> </div> </div> - <div class="actions robotActions" hidden$="[[!_showRobotActions]]"> - <gr-button link class="action fix" - on-tap="_handleFix" - disabled="[[robotButtonDisabled]]"> - Please Fix - </gr-button> - </div> </div> <gr-overlay id="confirmDeleteOverlay" with-backdrop> <gr-confirm-delete-comment-dialog id="confirmDeleteComment"
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-comment/gr-diff-comment.js b/polygerrit-ui/app/elements/diff/gr-diff-comment/gr-diff-comment.js index e8717b5..c5dd524 100644 --- a/polygerrit-ui/app/elements/diff/gr-diff-comment/gr-diff-comment.js +++ b/polygerrit-ui/app/elements/diff/gr-diff-comment/gr-diff-comment.js
@@ -21,6 +21,8 @@ const DRAFT_SINGULAR = 'draft...'; const DRAFT_PLURAL = 'drafts...'; const SAVED_MESSAGE = 'All changes saved'; + const SAVING_PROGRESS_MESSAGE = 'Saving draft...'; + const DiSCARDING_PROGRESS_MESSAGE = 'Discarding draft...'; Polymer({ is: 'gr-diff-comment', @@ -120,6 +122,8 @@ type: Object, value: {number: 0}, // Intentional to share the object across instances. }, + + _savingMessage: String, }, observers: [ @@ -433,6 +437,7 @@ if (!this.comment.__draft) { throw Error('Cannot discard a non-draft comment.'); } + this._savingMessage = DiSCARDING_PROGRESS_MESSAGE; this.editing = false; this.disabled = true; this._eraseDraftComment(); @@ -497,6 +502,7 @@ }, _saveDraft(draft) { + this._savingMessage = SAVING_PROGRESS_MESSAGE; this._showStartRequest(); return this.$.restAPI.saveDiffDraft(this.changeNum, this.patchNum, draft) .then(result => {
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-comment/gr-diff-comment_test.html b/polygerrit-ui/app/elements/diff/gr-diff-comment/gr-diff-comment_test.html index 1dc6c45..0d0b90e 100644 --- a/polygerrit-ui/app/elements/diff/gr-diff-comment/gr-diff-comment_test.html +++ b/polygerrit-ui/app/elements/diff/gr-diff-comment/gr-diff-comment_test.html
@@ -698,5 +698,22 @@ assert.equal(element._numPendingDraftRequests.number, 0); }); }); + + suite('saving progress indicators', () => { + setup(() => { + sandbox.stub(element, '_deleteDraft').returns(Promise.resolve()); + element._savingMessage = ''; + }); + + test('saving', () => { + element._saveDraft(); + assert.equal(element._savingMessage, 'Saving draft...'); + }); + + test('discarding', () => { + element._discardDraft(); + assert.equal(element._savingMessage, 'Discarding draft...'); + }); + }); }); </script>
diff --git a/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view.html b/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view.html index b6a2ad2..c6cf7ce 100644 --- a/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view.html +++ b/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view.html
@@ -99,6 +99,8 @@ <gr-endpoint-decorator name="editor"> <gr-endpoint-param name="fileContent" value="[[_newContent]]"> </gr-endpoint-param> + <gr-endpoint-param name="prefs" value="[[_prefs]]"> + </gr-endpoint-param> <textarea value="{{_newContent::input}}" id="file"></textarea> </gr-endpoint-decorator> </div>
diff --git a/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view.js b/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view.js index 5652793..52ce943 100644 --- a/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view.js +++ b/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view.js
@@ -35,7 +35,6 @@ _change: Object, _changeEditDetail: Object, _changeNum: String, - _loggedIn: Boolean, _path: String, _content: String, _newContent: String, @@ -44,6 +43,7 @@ value: true, computed: '_computeSaveDisabled(_content, _newContent)', }, + _prefs: Object, }, behaviors: [ @@ -53,13 +53,17 @@ ], attached() { - this._getLoggedIn().then(loggedIn => { this._loggedIn = loggedIn; }); + this._getEditPrefs().then(prefs => { this._prefs = prefs; }); }, _getLoggedIn() { return this.$.restAPI.getLoggedIn(); }, + _getEditPrefs() { + return this.$.restAPI.getEditPrefs(); + }, + _paramsChanged(value) { if (value.view !== Gerrit.Nav.View.EDIT) { return; }
diff --git a/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view_test.html b/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view_test.html index e3e6474..b3bcb22 100644 --- a/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view_test.html +++ b/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view_test.html
@@ -46,7 +46,7 @@ setup(() => { stub('gr-rest-api-interface', { - getLoggedIn() { return Promise.resolve(true); }, + getEditPrefs() { return Promise.resolve({}); }, }); sandbox = sinon.sandbox.create(); element = fixture('basic');
diff --git a/polygerrit-ui/app/elements/shared/gr-avatar/gr-avatar.js b/polygerrit-ui/app/elements/shared/gr-avatar/gr-avatar.js index 5fca577..1252f7d 100644 --- a/polygerrit-ui/app/elements/shared/gr-avatar/gr-avatar.js +++ b/polygerrit-ui/app/elements/shared/gr-avatar/gr-avatar.js
@@ -60,6 +60,11 @@ } }, + _getAccounts(account) { + return account._account_id || account.email || account.username || + account.name; + }, + _buildAvatarURL(account) { if (!account) { return ''; } const avatars = account.avatars || []; @@ -69,7 +74,8 @@ } } return this.getBaseUrl() + '/accounts/' + - account._account_id + '/avatar?s=' + this.imageSize; + encodeURIComponent(this._getAccounts(account)) + + '/avatar?s=' + this.imageSize; }, }); })();
diff --git a/polygerrit-ui/app/elements/shared/gr-avatar/gr-avatar_test.html b/polygerrit-ui/app/elements/shared/gr-avatar/gr-avatar_test.html index 4a51142..8187471 100644 --- a/polygerrit-ui/app/elements/shared/gr-avatar/gr-avatar_test.html +++ b/polygerrit-ui/app/elements/shared/gr-avatar/gr-avatar_test.html
@@ -50,6 +50,21 @@ '/accounts/123/avatar?s=16'); assert.equal(element._buildAvatarURL( { + email: 'test@example.com', + }), + '/accounts/test%40example.com/avatar?s=16'); + assert.equal(element._buildAvatarURL( + { + name: 'John Doe', + }), + '/accounts/John%20Doe/avatar?s=16'); + assert.equal(element._buildAvatarURL( + { + username: 'John_Doe', + }), + '/accounts/John_Doe/avatar?s=16'); + assert.equal(element._buildAvatarURL( + { _account_id: 123, avatars: [ {
diff --git a/polygerrit-ui/app/elements/shared/gr-button/gr-button.html b/polygerrit-ui/app/elements/shared/gr-button/gr-button.html index 9be55cf..483882f 100644 --- a/polygerrit-ui/app/elements/shared/gr-button/gr-button.html +++ b/polygerrit-ui/app/elements/shared/gr-button/gr-button.html
@@ -24,6 +24,7 @@ <dom-module id="gr-button"> <template strip-whitespace> <style include="shared-styles"> + /* general styles for all buttons */ :host { display: inline-block; font-family: var(--font-family-bold); @@ -33,56 +34,14 @@ :host([hidden]) { display: none; } - :host([link]) { - background-color: transparent; - border: none; - color: var(--color-link); - font-size: inherit; - font-family: var(--font-family-bold); - text-transform: none; - } - :host([link][tertiary]) { - color: var(--color-link-tertiary); - } - :host([link]) paper-button { - margin: 0; - padding: 0; - @apply --gr-button; - } - paper-button[raised] { - background-color: var(--gr-button-background, #fff); - color: var(--gr-button-color, var(--color-link)); - } :host([no-uppercase]) paper-button { text-transform: none; } - /* todo (beckysiegel) switch all secondary to primary as there is no color - distinction anymore. */ - :host([primary]) paper-button[raised], - :host([secondary]) paper-button[raised] { - background-color: var(--color-link); - color: #fff; - } - :host([primary][disabled]) paper-button[raised], - :host([disabled]) paper-button { - opacity: .5; - } - :host([link]) paper-button:hover, - :host([link]) paper-button:focus, - paper-button[raised]:hover, - paper-button[raised]:focus { - color: var(--gr-button-hover-color, var(--color-button-hover)); - } - :host([primary]) paper-button[raised]:hover, - :host([primary]) paper-button[raised]:focus, - :host([secondary]) paper-button[raised]:hover, - :host([secondary]) paper-button[raised]:focus { - background-color: var(--gr-button-hover-background-color, var(--color-button-hover)); - color: var(--gr-button-color, #fff); - } - paper-button, - paper-button[raised], - paper-button[link] { + paper-button { + /* Some of these are overridden for link style buttons since buttons + without the link attribute are raised */ + background-color: var(--gr-button-background, #fff); + color: var(--gr-button-color, var(--color-link)); display: flex; align-items: center; justify-content: center; @@ -91,11 +50,15 @@ padding: .4em .85em; @apply --gr-button; } - :host([link]) paper-button { - --paper-button: { - padding: 0; - } + paper-button:hover, + paper-button:focus { + color: var(--gr-button-hover-color, var(--color-button-hover)); } + :host([disabled]) paper-button { + color: #a8a8a8; + cursor: wait; + } + /* styles for the optional down arrow */ :host:not([down-arrow]) .downArrow {display: none; } :host([down-arrow]) .downArrow { border-top: .36em solid var(--gr-button-arrow-color, #ccc); @@ -108,20 +71,56 @@ :host([down-arrow]) paper-button:hover .downArrow { border-top-color: var(--gr-button-arrow-hover-color, #666); } - :host([loading]) paper-button, - :host([disabled]) paper-button { - color: #aaa; + + /* styles for raised buttons specifically*/ + :host([primary]) paper-button[raised], + :host([secondary]) paper-button[raised] { + background-color: var(--color-link); + color: #fff; } - :host([loading]) paper-button, - :host([loading][disabled]) paper-button { - cursor: wait; - background-color: #efefef; - color: #aaa; + :host([primary]) paper-button[raised]:hover, + :host([primary]) paper-button[raised]:focus, + :host([secondary]) paper-button[raised]:hover, + :host([secondary]) paper-button[raised]:focus { + background-color: var(--gr-button-hover-background-color, var(--color-button-hover)); + color: var(--gr-button-color, #fff); + } + :host([disabled]) paper-button[raised] { + background-color: #eaeaea; + color: #a8a8a8; + } + /* styles for link buttons specifically */ + :host([link]) { + background-color: transparent; + border: none; + color: var(--color-link); + font-size: inherit; + font-family: var(--font-family-bold); + text-transform: none; + } + :host([link][tertiary]) { + color: var(--color-link-tertiary); + } + :host([link]) paper-button { + background-color: transparent; + margin: 0; + padding: 0; + --paper-button: { + padding: 0; + } + @apply --gr-button; + } + :host([disabled][link]) paper-button { + background-color: transparent; + } + :host([link]) paper-button:hover, + :host([link]) paper-button:focus { + color: var(--gr-button-hover-color, var(--color-button-hover)); } </style> <paper-button raised="[[!link]]" - disabled="[[disabled]]" + disabled="[[_computeDisabled(disabled, loading)]]" tabindex="-1"> <content></content> <i class="downArrow"></i>
diff --git a/polygerrit-ui/app/elements/shared/gr-button/gr-button.js b/polygerrit-ui/app/elements/shared/gr-button/gr-button.js index 8e66e11..f368c8e 100644 --- a/polygerrit-ui/app/elements/shared/gr-button/gr-button.js +++ b/polygerrit-ui/app/elements/shared/gr-button/gr-button.js
@@ -28,6 +28,11 @@ value: false, reflectToAttribute: true, }, + loading: { + type: Boolean, + value: false, + reflectToAttribute: true, + }, tertiary: { type: Boolean, value: false, @@ -54,6 +59,10 @@ keydown: '_handleKeydown', }, + observers: [ + '_computeDisabled(disabled, loading)', + ], + behaviors: [ Gerrit.KeyboardShortcutBehavior, Gerrit.TooltipBehavior, @@ -78,6 +87,10 @@ this.setAttribute('tabindex', disabled ? '-1' : this._enabledTabindex); }, + _computeDisabled(disabled, loading) { + return disabled || loading; + }, + _handleKeydown(e) { if (this.modifierPressed(e)) { return; } e = this.getKeyboardEvent(e);
diff --git a/polygerrit-ui/app/elements/shared/gr-button/gr-button_test.html b/polygerrit-ui/app/elements/shared/gr-button/gr-button_test.html index d78427b..c0ceb33 100644 --- a/polygerrit-ui/app/elements/shared/gr-button/gr-button_test.html +++ b/polygerrit-ui/app/elements/shared/gr-button/gr-button_test.html
@@ -51,6 +51,16 @@ sandbox.restore(); }); + test('disabled is set by disabled or loading', () => { + assert.isFalse(element.$$('paper-button').disabled); + element.disabled = true; + assert.isTrue(element.$$('paper-button').disabled); + element.disabled = false; + assert.isFalse(element.$$('paper-button').disabled); + element.loading = true; + assert.isTrue(element.$$('paper-button').disabled); + }); + for (const eventName of ['tap', 'click']) { test('dispatches ' + eventName + ' event', () => { const spy = addSpyOn(eventName);
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 9a7a59e..3bb0178 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
@@ -915,6 +915,18 @@ /** * @param {number|string} changeNum + * @param {!Promise<?Object>} patchRange + */ + getChangeEditFiles(changeNum, patchRange) { + let endpoint = '/edit?list'; + if (patchRange.basePatchNum !== 'PARENT') { + endpoint += '&base=' + encodeURIComponent(patchRange.basePatchNum); + } + return this._getChangeURLAndFetch(changeNum, endpoint); + }, + + /** + * @param {number|string} changeNum * @param {number|string} patchNum * @param {string} query * @return {!Promise<!Object>} @@ -929,6 +941,11 @@ this._normalizeChangeFilesResponse.bind(this)); }, + getChangeEditFilesAsSpeciallySortedArray(changeNum, patchRange) { + return this.getChangeEditFiles(changeNum, patchRange).then(files => + this._normalizeChangeFilesResponse(files.files)); + }, + /** * The closure compiler doesn't realize this.specialFilePathCompare is * valid. @@ -1330,6 +1347,10 @@ '/edit:publish'); }, + getEditPrefs() { + return this._fetchSharedCacheURL('/accounts/self/preferences.edit'); + }, + putChangeCommitMessage(changeNum, message) { const p = {message}; return this.getChangeURLAndSend(changeNum, 'PUT', null, '/message', p);
diff --git a/tools/bzl/js.bzl b/tools/bzl/js.bzl index d5d2193..c42bc81 100644 --- a/tools/bzl/js.bzl +++ b/tools/bzl/js.bzl
@@ -257,6 +257,7 @@ "version_json": "%{name}-versions.json", }, ) + """Groups a set of bower components together in a zip file. Outputs:
diff --git a/tools/bzl/pkg_war.bzl b/tools/bzl/pkg_war.bzl index c9cd5d7..12e4b5f 100644 --- a/tools/bzl/pkg_war.bzl +++ b/tools/bzl/pkg_war.bzl
@@ -17,7 +17,6 @@ jar_filetype = FileType([".jar"]) LIBS = [ - "//java/com/google/gerrit/common:version", "//java/com/google/gerrit/httpd/init", "//lib:postgresql", "//lib/bouncycastle:bcpkix", @@ -28,7 +27,7 @@ ] PGMLIBS = [ - "//java/com/google/gerrit/pgm" + "//java/com/google/gerrit/pgm", ] def _add_context(in_file, output):
diff --git a/tools/bzl/plugin.bzl b/tools/bzl/plugin.bzl index e2de4ed..f43ff91 100644 --- a/tools/bzl/plugin.bzl +++ b/tools/bzl/plugin.bzl
@@ -10,6 +10,7 @@ ) PLUGIN_DEPS = ["//plugins:plugin-lib"] + PLUGIN_DEPS_NEVERLINK = ["//plugins:plugin-lib-neverlink"] PLUGIN_TEST_DEPS = [