Add support for cherry-picking even with merge conflicts

Supported since [1]

[1] Iae9eef38ad2a7810a736823c7bd80b8a7a2a214f

Bug: Issue 5728
Change-Id: Idb749f77cc7063eb9d93ebbf7a10d81bc5384750
This commit is contained in:
Paladox none
2018-10-11 22:36:26 +00:00
parent d26237eaa8
commit 35c3de368f
7 changed files with 227 additions and 7 deletions

View File

@@ -32,6 +32,7 @@ limitations under the License.
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
<link rel="import" href="../gr-confirm-abandon-dialog/gr-confirm-abandon-dialog.html">
<link rel="import" href="../gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog.html">
<link rel="import" href="../gr-confirm-cherrypick-conflict-dialog/gr-confirm-cherrypick-conflict-dialog.html">
<link rel="import" href="../gr-confirm-move-dialog/gr-confirm-move-dialog.html">
<link rel="import" href="../gr-confirm-rebase-dialog/gr-confirm-rebase-dialog.html">
<link rel="import" href="../gr-confirm-revert-dialog/gr-confirm-revert-dialog.html">
@@ -187,6 +188,15 @@ limitations under the License.
on-cancel="_handleConfirmDialogCancel"
project="[[change.project]]"
hidden></gr-confirm-cherrypick-dialog>
<gr-confirm-cherrypick-conflict-dialog id="confirmCherrypickConflict"
class="confirmDialog"
change-status="[[changeStatus]]"
commit-message="[[commitMessage]]"
commit-num="[[commitNum]]"
on-confirm="_handleCherrypickConflictConfirm"
on-cancel="_handleConfirmDialogCancel"
project="[[change.project]]"
hidden></gr-confirm-cherrypick-conflict-dialog>
<gr-confirm-move-dialog id="confirmMove"
class="confirmDialog"
on-confirm="_handleMoveConfirm"

View File

@@ -991,6 +991,14 @@
},
_handleCherrypickConfirm() {
this._handleCherryPickRestApi(false);
},
_handleCherrypickConflictConfirm() {
this._handleCherryPickRestApi(true);
},
_handleCherryPickRestApi(conflicts) {
const el = this.$.confirmCherrypick;
if (!el.branch) {
// TODO(davido): Fix error handling
@@ -1011,6 +1019,7 @@
destination: el.branch,
base: el.baseCommit ? el.baseCommit : null,
message: el.message,
allow_conflicts: conflicts,
}
);
},
@@ -1113,8 +1122,9 @@
_fireAction(endpoint, action, revAction, opt_payload) {
const cleanupFn =
this._setLoadingOnButtonWithKey(action.__type, action.__key);
this._send(action.method, opt_payload, endpoint, revAction, cleanupFn)
.then(this._handleResponse.bind(this, action));
this._send(action.method, opt_payload, endpoint, revAction, cleanupFn,
action).then(this._handleResponse.bind(this, action));
},
_showActionDialog(dialog) {
@@ -1171,7 +1181,14 @@
});
},
_handleResponseError(response) {
_handleResponseError(action, response, body) {
if (action && action.__key === RevisionActions.CHERRYPICK) {
if (response && response.status === 409 &&
body && !body.allow_conflicts) {
return this._showActionDialog(
this.$.confirmCherrypickConflict);
}
}
return response.text().then(errText => {
this.fire('show-error',
{message: `Could not perform action: ${errText}`});
@@ -1187,13 +1204,12 @@
* @param {string} actionEndpoint
* @param {boolean} revisionAction
* @param {?Function} cleanupFn
* @param {?Function=} opt_errorFn
* @param {!Object|undefined} action
*/
_send(method, payload, actionEndpoint, revisionAction, cleanupFn,
opt_errorFn) {
_send(method, payload, actionEndpoint, revisionAction, cleanupFn, action) {
const handleError = response => {
cleanupFn.call(this);
this._handleResponseError(response);
this._handleResponseError(action, response, payload);
};
return this.fetchChangeUpdates(this.change, this.$.restAPI)

View File

@@ -599,6 +599,38 @@ limitations under the License.
destination: 'master',
base: null,
message: 'foo message',
allow_conflicts: false,
},
]);
});
test('cherry pick even with conflicts', () => {
element._handleCherrypickTap();
const action = {
__key: 'cherrypick',
__type: 'revision',
__primary: false,
enabled: true,
label: 'Cherry pick',
method: 'POST',
title: 'Cherry pick change to a different branch',
};
element.$.confirmCherrypick.branch = 'master';
// Add attributes that are used to determine the message.
element.$.confirmCherrypick.commitMessage = 'foo message';
element.$.confirmCherrypick.changeStatus = 'OPEN';
element.$.confirmCherrypick.commitNum = '123';
element._handleCherrypickConflictConfirm();
assert.deepEqual(fireActionStub.lastCall.args, [
'/cherrypick', action, true, {
destination: 'master',
base: null,
message: 'foo message',
allow_conflicts: true,
},
]);
});

View File

@@ -0,0 +1,51 @@
<!--
@license
Copyright (C) 2018 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="../../../styles/shared-styles.html">
<link rel="import" href="../../shared/gr-dialog/gr-dialog.html">
<dom-module id="gr-confirm-cherrypick-conflict-dialog">
<template>
<style include="shared-styles">
:host {
display: block;
}
:host([disabled]) {
opacity: .5;
pointer-events: none;
}
.main {
display: flex;
flex-direction: column;
width: 100%;
}
</style>
<gr-dialog
confirm-label="Continue"
on-confirm="_handleConfirmTap"
on-cancel="_handleCancelTap">
<div class="header" slot="header">Cherry Pick Conflict!</div>
<div class="main" slot="main">
<span>Cherry Pick failed! (merge conflicts)</span>
<span>Please select "Continue" to continue with conflicts or select "cancel" to close the dialog.</span>
</div>
</gr-dialog>
</template>
<script src="gr-confirm-cherrypick-conflict-dialog.js"></script>
</dom-module>

View File

@@ -0,0 +1,45 @@
/**
* @license
* Copyright (C) 2018 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-confirm-cherrypick-conflict-dialog',
/**
* Fired when the confirm button is pressed.
*
* @event confirm
*/
/**
* Fired when the cancel button is pressed.
*
* @event cancel
*/
_handleConfirmTap(e) {
e.preventDefault();
this.fire('confirm', null, {bubbles: false});
},
_handleCancelTap(e) {
e.preventDefault();
this.fire('cancel', null, {bubbles: false});
},
});
})();

View File

@@ -0,0 +1,65 @@
<!DOCTYPE html>
<!--
@license
Copyright (C) 2018 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-confirm-cherrypick-conflict-dialog</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="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-confirm-cherrypick-conflict-dialog.html">
<script>void(0);</script>
<test-fixture id="basic">
<template>
<gr-confirm-cherrypick-conflict-dialog></gr-confirm-cherrypick-conflict-dialog>
</template>
</test-fixture>
<script>
suite('gr-confirm-cherrypick-conflict-dialog tests', () => {
let element;
let sandbox;
setup(() => {
sandbox = sinon.sandbox.create();
element = fixture('basic');
});
teardown(() => { sandbox.restore(); });
test('_handleConfirmTap', () => {
const confirmHandler = sandbox.stub();
element.addEventListener('confirm', confirmHandler);
sandbox.stub(element, '_handleConfirmTap');
element.$$('gr-dialog').fire('confirm');
assert.isTrue(confirmHandler.called);
assert.isTrue(element._handleConfirmTap.called);
});
test('_handleCancelTap', () => {
const cancelHandler = sandbox.stub();
element.addEventListener('cancel', cancelHandler);
sandbox.stub(element, '_handleCancelTap');
element.$$('gr-dialog').fire('cancel');
assert.isTrue(cancelHandler.called);
assert.isTrue(element._handleCancelTap.called);
});
});
</script>

View File

@@ -71,6 +71,7 @@ limitations under the License.
'change/gr-commit-info/gr-commit-info_test.html',
'change/gr-confirm-abandon-dialog/gr-confirm-abandon-dialog_test.html',
'change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog_test.html',
'change/gr-confirm-cherrypick-conflict-dialog/gr-confirm-cherrypick-conflict-dialog_test.html',
'change/gr-confirm-move-dialog/gr-confirm-move-dialog_test.html',
'change/gr-confirm-rebase-dialog/gr-confirm-rebase-dialog_test.html',
'change/gr-confirm-revert-dialog/gr-confirm-revert-dialog_test.html',