Merge changes I9bff4778,I43ff7bb6,Ia6baf723,I94b070ed,Id687d559, ... * changes: Test that the revision REST endpoints are correctly bound Test that the reviewer REST endpoints are correctly bound Test that the change REST endpoints are correctly bound (part 1) Test that the plugin REST endpoints are correctly bound Test that the group REST endpoints are correctly bound Test that the config REST endpoints are correctly bound Test that the project REST endpoints are correctly bound Test that the account REST endpoints are correctly bound Test that the root REST endpoints are correctly bound
diff --git a/BUILD b/BUILD index 91e2dec..4bba5a5 100644 --- a/BUILD +++ b/BUILD
@@ -3,6 +3,13 @@ load("//tools/bzl:genrule2.bzl", "genrule2") load("//tools/bzl:pkg_war.bzl", "pkg_war") +config_setting( + name = "java9", + values = { + "java_toolchain": "@bazel_tools//tools/jdk:toolchain_java9", + }, +) + genrule( name = "gen_version", outs = ["version.txt"],
diff --git a/Documentation/dev-bazel.txt b/Documentation/dev-bazel.txt index cf27f82..04f749d 100644 --- a/Documentation/dev-bazel.txt +++ b/Documentation/dev-bazel.txt
@@ -14,6 +14,28 @@ * zip, unzip * gcc +[[Java 9 support]] +Java 9 is supported through alternative java toolchain +link:https://docs.bazel.build/versions/master/toolchains.html[Bazel option]. +The Java 9 support is backwards compatible. Java 8 is still the default. +To build Gerrit with Java 9, specify JDK 9 java toolchain: + +``` + $ bazel build \ + --host_java_toolchain=@bazel_tools//tools/jdk:toolchain_java9 \ + --java_toolchain=@bazel_tools//tools/jdk:toolchain_java9 \ + :release +``` + +Note that the following option must be added to `container.javaOptions` +in `$gerrit_site/etc/gerrit.config` to run Gerrit with Java 9: + +``` +[container] + javaOptions = --add-modules java.activation \ + --add-opens=jdk.management/com.sun.management.internal=ALL-UNNAMED +``` + [[build]] == Building on the Command Line
diff --git a/java/com/google/gerrit/server/change/PureRevert.java b/java/com/google/gerrit/server/change/PureRevert.java index 850f33a..ee0e2cc 100644 --- a/java/com/google/gerrit/server/change/PureRevert.java +++ b/java/com/google/gerrit/server/change/PureRevert.java
@@ -108,8 +108,8 @@ .create(projectCache.checkedGet(notes.getProjectName())) .newThreeWayMerger(oi, repo.getConfig()); merger.setBase(claimedRevertCommit.getParent(0)); - merger.merge(claimedRevertCommit, claimedOriginalCommit); - if (merger.getResultTreeId() == null) { + boolean success = merger.merge(claimedRevertCommit, claimedOriginalCommit); + if (!success || merger.getResultTreeId() == null) { // Merge conflict during rebase return new PureRevertInfo(false); }
diff --git a/java/com/google/gerrit/server/change/RebaseChangeOp.java b/java/com/google/gerrit/server/change/RebaseChangeOp.java index 0bbaccd..909ea3a 100644 --- a/java/com/google/gerrit/server/change/RebaseChangeOp.java +++ b/java/com/google/gerrit/server/change/RebaseChangeOp.java
@@ -263,9 +263,9 @@ ThreeWayMerger merger = newMergeUtil().newThreeWayMerger(ctx.getInserter(), ctx.getRepoView().getConfig()); merger.setBase(parentCommit); - merger.merge(original, base); + boolean success = merger.merge(original, base); - if (merger.getResultTreeId() == null) { + if (!success || merger.getResultTreeId() == null) { throw new MergeConflictException( "The change could not be rebased due to a conflict during merge."); }
diff --git a/java/com/google/gerrit/server/restapi/change/ChangeEdits.java b/java/com/google/gerrit/server/restapi/change/ChangeEdits.java index 1e24a7f..ae77060 100644 --- a/java/com/google/gerrit/server/restapi/change/ChangeEdits.java +++ b/java/com/google/gerrit/server/restapi/change/ChangeEdits.java
@@ -152,7 +152,7 @@ public static class DeleteFile implements RestModifyView<ChangeResource, Input> { - interface Factory { + public interface Factory { DeleteFile create(String path); }
diff --git a/polygerrit-ui/app/elements/change/gr-download-dialog/gr-download-dialog.html b/polygerrit-ui/app/elements/change/gr-download-dialog/gr-download-dialog.html index 9085971..545d170 100644 --- a/polygerrit-ui/app/elements/change/gr-download-dialog/gr-download-dialog.html +++ b/polygerrit-ui/app/elements/change/gr-download-dialog/gr-download-dialog.html
@@ -28,21 +28,32 @@ :host { background-color: var(--dialog-background-color); display: block; - padding: 1em; } - header { + section { display: flex; + padding: .5em 1.5em; } - footer { + section:not(:first-of-type) { + border-top: 1px solid var(--border-color); + } + .flexContainer { display: flex; justify-content: space-between; padding-top: .75em; } + .footer { + justify-content: flex-end; + } .closeButtonContainer { + align-items: flex-end; display: flex; flex: 0; justify-content: flex-end; } + .patchFiles, + .archivesContainer { + padding-bottom: .5em; + } .patchFiles { margin-right: 2em; } @@ -56,26 +67,26 @@ margin-right: 0; } .title { - text-align: center; flex: 1; + font-family: var(--font-family-bold); + } + .hidden { + display: none; } </style> - <header> + <section> <span class="title"> Patch set [[patchNum]] of [[_computePatchSetQuantity(change.revisions)]] </span> - <span class="closeButtonContainer"> - <gr-button id="closeButton" - link - on-tap="_handleCloseTap">Close</gr-button> - </span> - </header> - <gr-download-commands + </section> + <section class$="[[_computeShowDownloadCommands(_schemes)]]"> + <gr-download-commands id="downloadCommands" commands="[[_computeDownloadCommands(change, patchNum, _selectedScheme)]]" schemes="[[_schemes]]" selected-scheme="{{_selectedScheme}}"></gr-download-commands> - <footer> + </section> + <section class="flexContainer"> <div class="patchFiles"> <label>Patch file</label> <div> @@ -104,7 +115,14 @@ </template> </div> </div> - </footer> + </section> + <section class="footer"> + <span class="closeButtonContainer"> + <gr-button id="closeButton" + link + on-tap="_handleCloseTap">Close</gr-button> + </span> + </section> </template> <script src="gr-download-dialog.js"></script> </dom-module>
diff --git a/polygerrit-ui/app/elements/change/gr-download-dialog/gr-download-dialog.js b/polygerrit-ui/app/elements/change/gr-download-dialog/gr-download-dialog.js index fa3e5c9..20449b0 100644 --- a/polygerrit-ui/app/elements/change/gr-download-dialog/gr-download-dialog.js +++ b/polygerrit-ui/app/elements/change/gr-download-dialog/gr-download-dialog.js
@@ -172,5 +172,9 @@ this._selectedScheme = schemes.sort()[0]; } }, + + _computeShowDownloadCommands(schemes) { + return schemes.length ? '' : 'hidden'; + }, }); })();
diff --git a/polygerrit-ui/app/elements/change/gr-download-dialog/gr-download-dialog_test.html b/polygerrit-ui/app/elements/change/gr-download-dialog/gr-download-dialog_test.html index 84fe8a9..19932c5 100644 --- a/polygerrit-ui/app/elements/change/gr-download-dialog/gr-download-dialog_test.html +++ b/polygerrit-ui/app/elements/change/gr-download-dialog/gr-download-dialog_test.html
@@ -183,5 +183,10 @@ MockInteractions.tap(element.$$('.closeButtonContainer gr-button')); }); }); + + test('_computeShowDownloadCommands', () => { + assert.equal(element._computeShowDownloadCommands([]), 'hidden'); + assert.equal(element._computeShowDownloadCommands(['test']), ''); + }); }); </script>
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 e27a8ea..cde4131 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
@@ -528,6 +528,9 @@ // link, defer to the native behavior. if (!path || this.descendedFromClass(e.target, 'pathLink')) { return; } + // Disregard the event if the click target is in the edit controls. + if (this.descendedFromClass(e.target, 'editFileControls')) { return; } + e.preventDefault(); this._togglePathExpanded(path); },
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 5833a9a..29a388e 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
@@ -838,6 +838,28 @@ assert.isTrue(reviewStub.calledOnce); }); + test('_handleFileListTap editMode', () => { + element._filesByPath = { + '/COMMIT_MSG': {}, + 'f1.txt': {}, + 'f2.txt': {}, + }; + element.changeNum = '42'; + element.patchRange = { + basePatchNum: 'PARENT', + patchNum: '2', + }; + element.editMode = true; + flushAsynchronousOperations(); + const tapSpy = sandbox.spy(element, '_handleFileListTap'); + const toggleExpandSpy = sandbox.spy(element, '_togglePathExpanded'); + + // Tap the edit controls. Should be ignored by _handleFileListTap. + MockInteractions.tap(element.$$('.editFileControls')); + assert.isTrue(tapSpy.calledOnce); + assert.isFalse(toggleExpandSpy.called); + }); + test('patch set from revisions', () => { const expected = [ {num: 4, desc: 'test'},
diff --git a/polygerrit-ui/app/elements/shared/gr-download-commands/gr-download-commands.html b/polygerrit-ui/app/elements/shared/gr-download-commands/gr-download-commands.html index 7570533..83e99be 100644 --- a/polygerrit-ui/app/elements/shared/gr-download-commands/gr-download-commands.html +++ b/polygerrit-ui/app/elements/shared/gr-download-commands/gr-download-commands.html
@@ -15,8 +15,11 @@ limitations under the License. --> -<link rel="import" href="../../../behaviors/rest-client-behavior/rest-client-behavior.html"> <link rel="import" href="../../../bower_components/polymer/polymer.html"> + + +<link rel="import" href="../../../behaviors/rest-client-behavior/rest-client-behavior.html"> +<link rel="import" href="../../../bower_components/paper-tabs/paper-tabs.html"> <link rel="import" href="../../shared/gr-copy-clipboard/gr-copy-clipboard.html"> <link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html"> <link rel="import" href="../../../styles/shared-styles.html"> @@ -24,17 +27,15 @@ <dom-module id="gr-download-commands"> <template> <style include="shared-styles"> - ul { - list-style: none; + paper-tabs { + height: 3rem; margin-bottom: .5em; + --paper-tabs-selection-bar-color: var(--link-color); } - li { - display: inline-block; - margin: 0; - padding: 0; - } - li gr-button { - margin-right: 1em; + paper-tab { + max-width: 15rem; + text-transform: uppercase; + --paper-tab-ink: var(--link-color); } label, input { @@ -43,11 +44,6 @@ label { font-family: var(--font-family-bold); } - li[selected] gr-button { - color: var(--primary-text-color); - font-family: var(--font-family-bold); - text-decoration: none; - } .schemes { display: flex; justify-content: space-between; @@ -55,25 +51,25 @@ .commands { display: flex; flex-direction: column; - border-bottom: 1px solid var(--border-color); - border-top: 1px solid var(--border-color); - padding: .5em; } gr-copy-clipboard { width: 60em; margin-bottom: .5em; } + .hidden { + display: none; + } </style> <div class="schemes"> - <ul hidden$="[[!schemes.length]]" hidden> + <paper-tabs + id="downloadTabs" + class$="[[_computeShowTabs(schemes)]]" + selected="[[_computeSelected(schemes, selectedScheme)]]" + on-selected-changed="_handleTabChange"> <template is="dom-repeat" items="[[schemes]]" as="scheme"> - <li selected$="[[_computeSelected(scheme, selectedScheme)]]"> - <gr-button link data-scheme$="[[scheme]]" on-tap="_handleSchemeTap"> - [[scheme]] - </gr-button> - </li> + <paper-tab data-scheme$="[[scheme]]">[[scheme]]</paper-tab> </template> - </ul> + </paper-tabs> </div> <div class="commands" hidden$="[[!schemes.length]]" hidden> <template is="dom-repeat"
diff --git a/polygerrit-ui/app/elements/shared/gr-download-commands/gr-download-commands.js b/polygerrit-ui/app/elements/shared/gr-download-commands/gr-download-commands.js index 8f513cb..319cd04 100644 --- a/polygerrit-ui/app/elements/shared/gr-download-commands/gr-download-commands.js +++ b/polygerrit-ui/app/elements/shared/gr-download-commands/gr-download-commands.js
@@ -61,17 +61,24 @@ }); }, - _computeSelected(item, selectedItem) { - return item === selectedItem; + _handleTabChange(e) { + const scheme = this.schemes[e.detail.value]; + if (scheme && scheme !== this.selectedScheme) { + this.set('selectedScheme', scheme); + if (this._loggedIn) { + this.$.restAPI.savePreferences( + {download_scheme: this.selectedScheme}); + } + } }, - _handleSchemeTap(e) { - e.preventDefault(); - const el = Polymer.dom(e).localTarget; - this.selectedScheme = el.getAttribute('data-scheme'); - if (this._loggedIn) { - this.$.restAPI.savePreferences({download_scheme: this.selectedScheme}); - } + _computeSelected(schemes, selectedScheme) { + return (schemes.findIndex(scheme => scheme === selectedScheme) || 0) + + ''; + }, + + _computeShowTabs(schemes) { + return schemes.length > 1 ? '' : 'hidden'; }, }); })();
diff --git a/polygerrit-ui/app/elements/shared/gr-download-commands/gr-download-commands_test.html b/polygerrit-ui/app/elements/shared/gr-download-commands/gr-download-commands_test.html index 4fe5569..47219a7 100644 --- a/polygerrit-ui/app/elements/shared/gr-download-commands/gr-download-commands_test.html +++ b/polygerrit-ui/app/elements/shared/gr-download-commands/gr-download-commands_test.html
@@ -81,30 +81,21 @@ }); test('element visibility', () => { - assert.isFalse(element.$$('ul').hasAttribute('hidden')); - assert.isFalse(element.$$('.commands').hasAttribute('hidden')); + assert.isFalse(isHidden(element.$$('paper-tabs'))); + assert.isFalse(isHidden(element.$$('.commands'))); element.schemes = []; - assert.isTrue(element.$$('ul').hasAttribute('hidden')); - assert.isTrue(element.$$('.commands').hasAttribute('hidden')); + assert.isTrue(isHidden(element.$$('paper-tabs'))); + assert.isTrue(isHidden(element.$$('.commands'))); }); test('tab selection', () => { - flushAsynchronousOperations(); - let el = element.$$('[data-scheme="http"]').parentElement; - assert.isTrue(el.hasAttribute('selected')); - for (const scheme of ['repo', 'ssh']) { - const el = element.$$('[data-scheme="' + scheme + '"]').parentElement; - assert.isFalse(el.hasAttribute('selected')); - } - + assert.equal(element.$.downloadTabs.selected, '0'); MockInteractions.tap(element.$$('[data-scheme="ssh"]')); - el = element.$$('[data-scheme="ssh"]').parentElement; - assert.isTrue(el.hasAttribute('selected')); - for (const scheme of ['http', 'repo']) { - const el = element.$$('[data-scheme="' + scheme + '"]').parentElement; - assert.isFalse(el.hasAttribute('selected')); - } + flushAsynchronousOperations(); + + assert.equal(element.selectedScheme, 'ssh'); + assert.equal(element.$.downloadTabs.selected, '2'); }); test('loads scheme from preferences', done => { @@ -136,18 +127,18 @@ test('saves scheme to preferences', () => { element._loggedIn = true; - const savePrefsStub = sinon.stub(element.$.restAPI, 'savePreferences', + const savePrefsStub = sandbox.stub(element.$.restAPI, 'savePreferences', () => { return Promise.resolve(); }); flushAsynchronousOperations(); - const firstSchemeButton = element.$$('li gr-button[data-scheme]'); + const repoTab = element.$$('paper-tab[data-scheme="repo"]'); - MockInteractions.tap(firstSchemeButton); + MockInteractions.tap(repoTab); assert.isTrue(savePrefsStub.called); assert.equal(savePrefsStub.lastCall.args[0].download_scheme, - firstSchemeButton.getAttribute('data-scheme')); + repoTab.getAttribute('data-scheme')); }); }); });
diff --git a/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown.js b/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown.js index 5da46ae..dcb428f 100644 --- a/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown.js +++ b/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown.js
@@ -78,10 +78,6 @@ }, }, - listeners: { - tap: '_handleTap', - }, - behaviors: [ Gerrit.BaseUrlBehavior, Gerrit.KeyboardShortcutBehavior, @@ -294,10 +290,5 @@ _computeIsDownload(link) { return !!link.download; }, - - _handleTap(e) { - e.preventDefault(); - e.stopImmediatePropagation(); - }, }); })();
diff --git a/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown_test.html b/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown_test.html index 250c416..456f235 100644 --- a/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown_test.html +++ b/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown_test.html
@@ -112,21 +112,16 @@ }); test('non link items', () => { - const nativeTapHandler = sandbox.stub(); const item0 = {name: 'item one', id: 'foo'}; element.items = [item0, {name: 'item two', id: 'bar'}]; const fooTapped = sandbox.stub(); const tapped = sandbox.stub(); element.addEventListener('tap-item-foo', fooTapped); element.addEventListener('tap-item', tapped); - element.addEventListener('tap', nativeTapHandler); flushAsynchronousOperations(); - MockInteractions.tap(element.$$('.itemAction')); assert.isTrue(fooTapped.called); assert.isTrue(tapped.called); - assert.isFalse(nativeTapHandler.called); - assert.deepEqual(tapped.lastCall.args[0].detail, item0); });
diff --git a/tools/bzl/junit.bzl b/tools/bzl/junit.bzl index 19974a7..1abcc23 100644 --- a/tools/bzl/junit.bzl +++ b/tools/bzl/junit.bzl
@@ -67,7 +67,18 @@ _GenSuite(name = s_name, srcs = srcs, outname = s_name) + jvm_flags = kwargs.get("jvm_flags", []) + jvm_flags = jvm_flags + select({ + "//:java9": [ + # Enforce JDK 8 compatibility on Java 9, see + # https://docs.oracle.com/javase/9/intl/internationalization-enhancements-jdk-9.htm#JSINT-GUID-AF5AECA7-07C1-4E7D-BC10-BC7E73DC6C7F + "-Djava.locale.providers=COMPAT,CLDR,SPI", + "--add-modules java.activation", + "--add-opens=jdk.management/com.sun.management.internal=ALL-UNNAMED", + ], + "//conditions:default": [], + }) native.java_test(name = name, test_class = s_name, srcs = srcs + [":"+s_name], - **kwargs) + **dict(kwargs, jvm_flags=jvm_flags))