1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-22 13:30:55 +01:00

When the push phase of "Land Revision" fails, show the error in the UI

Summary: T10447

Test Plan: tested on my dev instance

Reviewers: #blessed_reviewers, epriestley

Reviewed By: #blessed_reviewers, epriestley

Subscribers: Korvin, yelirekim

Differential Revision: https://secure.phabricator.com/D15350
This commit is contained in:
Nick Zheng 2016-02-26 09:38:24 -08:00
parent 7d4b323da2
commit 6861af0cbb
7 changed files with 54 additions and 32 deletions

View file

@ -27,6 +27,7 @@ phutil_register_library_map(array(
'AlmanacClusterServiceType' => 'applications/almanac/servicetype/AlmanacClusterServiceType.php', 'AlmanacClusterServiceType' => 'applications/almanac/servicetype/AlmanacClusterServiceType.php',
'AlmanacConsoleController' => 'applications/almanac/controller/AlmanacConsoleController.php', 'AlmanacConsoleController' => 'applications/almanac/controller/AlmanacConsoleController.php',
'AlmanacController' => 'applications/almanac/controller/AlmanacController.php', 'AlmanacController' => 'applications/almanac/controller/AlmanacController.php',
'AlmanacCreateClusterServicesCapability' => 'applications/almanac/capability/AlmanacCreateClusterServicesCapability.php',
'AlmanacCreateDevicesCapability' => 'applications/almanac/capability/AlmanacCreateDevicesCapability.php', 'AlmanacCreateDevicesCapability' => 'applications/almanac/capability/AlmanacCreateDevicesCapability.php',
'AlmanacCreateNamespacesCapability' => 'applications/almanac/capability/AlmanacCreateNamespacesCapability.php', 'AlmanacCreateNamespacesCapability' => 'applications/almanac/capability/AlmanacCreateNamespacesCapability.php',
'AlmanacCreateNetworksCapability' => 'applications/almanac/capability/AlmanacCreateNetworksCapability.php', 'AlmanacCreateNetworksCapability' => 'applications/almanac/capability/AlmanacCreateNetworksCapability.php',
@ -57,9 +58,10 @@ phutil_register_library_map(array(
'AlmanacInterfaceQuery' => 'applications/almanac/query/AlmanacInterfaceQuery.php', 'AlmanacInterfaceQuery' => 'applications/almanac/query/AlmanacInterfaceQuery.php',
'AlmanacInterfaceTableView' => 'applications/almanac/view/AlmanacInterfaceTableView.php', 'AlmanacInterfaceTableView' => 'applications/almanac/view/AlmanacInterfaceTableView.php',
'AlmanacKeys' => 'applications/almanac/util/AlmanacKeys.php', 'AlmanacKeys' => 'applications/almanac/util/AlmanacKeys.php',
'AlmanacManageClusterServicesCapability' => 'applications/almanac/capability/AlmanacManageClusterServicesCapability.php', 'AlmanacManagementLockWorkflow' => 'applications/almanac/management/AlmanacManagementLockWorkflow.php',
'AlmanacManagementRegisterWorkflow' => 'applications/almanac/management/AlmanacManagementRegisterWorkflow.php', 'AlmanacManagementRegisterWorkflow' => 'applications/almanac/management/AlmanacManagementRegisterWorkflow.php',
'AlmanacManagementTrustKeyWorkflow' => 'applications/almanac/management/AlmanacManagementTrustKeyWorkflow.php', 'AlmanacManagementTrustKeyWorkflow' => 'applications/almanac/management/AlmanacManagementTrustKeyWorkflow.php',
'AlmanacManagementUnlockWorkflow' => 'applications/almanac/management/AlmanacManagementUnlockWorkflow.php',
'AlmanacManagementUntrustKeyWorkflow' => 'applications/almanac/management/AlmanacManagementUntrustKeyWorkflow.php', 'AlmanacManagementUntrustKeyWorkflow' => 'applications/almanac/management/AlmanacManagementUntrustKeyWorkflow.php',
'AlmanacManagementWorkflow' => 'applications/almanac/management/AlmanacManagementWorkflow.php', 'AlmanacManagementWorkflow' => 'applications/almanac/management/AlmanacManagementWorkflow.php',
'AlmanacNames' => 'applications/almanac/util/AlmanacNames.php', 'AlmanacNames' => 'applications/almanac/util/AlmanacNames.php',
@ -971,6 +973,7 @@ phutil_register_library_map(array(
'DrydockWebrootInterface' => 'applications/drydock/interface/webroot/DrydockWebrootInterface.php', 'DrydockWebrootInterface' => 'applications/drydock/interface/webroot/DrydockWebrootInterface.php',
'DrydockWorker' => 'applications/drydock/worker/DrydockWorker.php', 'DrydockWorker' => 'applications/drydock/worker/DrydockWorker.php',
'DrydockWorkingCopyBlueprintImplementation' => 'applications/drydock/blueprint/DrydockWorkingCopyBlueprintImplementation.php', 'DrydockWorkingCopyBlueprintImplementation' => 'applications/drydock/blueprint/DrydockWorkingCopyBlueprintImplementation.php',
'DrydockCommandError' => 'applications/drydock/DrydockCommandError/DrydockCommandError.php',
'FeedConduitAPIMethod' => 'applications/feed/conduit/FeedConduitAPIMethod.php', 'FeedConduitAPIMethod' => 'applications/feed/conduit/FeedConduitAPIMethod.php',
'FeedPublishConduitAPIMethod' => 'applications/feed/conduit/FeedPublishConduitAPIMethod.php', 'FeedPublishConduitAPIMethod' => 'applications/feed/conduit/FeedPublishConduitAPIMethod.php',
'FeedPublisherHTTPWorker' => 'applications/feed/worker/FeedPublisherHTTPWorker.php', 'FeedPublisherHTTPWorker' => 'applications/feed/worker/FeedPublisherHTTPWorker.php',
@ -3994,7 +3997,6 @@ phutil_register_library_map(array(
'PhabricatorApplicationTransactionInterface', 'PhabricatorApplicationTransactionInterface',
'AlmanacPropertyInterface', 'AlmanacPropertyInterface',
'PhabricatorDestructibleInterface', 'PhabricatorDestructibleInterface',
'PhabricatorExtendedPolicyInterface',
), ),
'AlmanacBindingDisableController' => 'AlmanacServiceController', 'AlmanacBindingDisableController' => 'AlmanacServiceController',
'AlmanacBindingEditController' => 'AlmanacServiceController', 'AlmanacBindingEditController' => 'AlmanacServiceController',
@ -4012,6 +4014,7 @@ phutil_register_library_map(array(
'AlmanacClusterServiceType' => 'AlmanacServiceType', 'AlmanacClusterServiceType' => 'AlmanacServiceType',
'AlmanacConsoleController' => 'AlmanacController', 'AlmanacConsoleController' => 'AlmanacController',
'AlmanacController' => 'PhabricatorController', 'AlmanacController' => 'PhabricatorController',
'AlmanacCreateClusterServicesCapability' => 'PhabricatorPolicyCapability',
'AlmanacCreateDevicesCapability' => 'PhabricatorPolicyCapability', 'AlmanacCreateDevicesCapability' => 'PhabricatorPolicyCapability',
'AlmanacCreateNamespacesCapability' => 'PhabricatorPolicyCapability', 'AlmanacCreateNamespacesCapability' => 'PhabricatorPolicyCapability',
'AlmanacCreateNetworksCapability' => 'PhabricatorPolicyCapability', 'AlmanacCreateNetworksCapability' => 'PhabricatorPolicyCapability',
@ -4028,7 +4031,6 @@ phutil_register_library_map(array(
'PhabricatorDestructibleInterface', 'PhabricatorDestructibleInterface',
'PhabricatorNgramsInterface', 'PhabricatorNgramsInterface',
'PhabricatorConduitResultInterface', 'PhabricatorConduitResultInterface',
'PhabricatorExtendedPolicyInterface',
), ),
'AlmanacDeviceController' => 'AlmanacController', 'AlmanacDeviceController' => 'AlmanacController',
'AlmanacDeviceEditController' => 'AlmanacDeviceController', 'AlmanacDeviceEditController' => 'AlmanacDeviceController',
@ -4058,9 +4060,10 @@ phutil_register_library_map(array(
'AlmanacInterfaceQuery' => 'AlmanacQuery', 'AlmanacInterfaceQuery' => 'AlmanacQuery',
'AlmanacInterfaceTableView' => 'AphrontView', 'AlmanacInterfaceTableView' => 'AphrontView',
'AlmanacKeys' => 'Phobject', 'AlmanacKeys' => 'Phobject',
'AlmanacManageClusterServicesCapability' => 'PhabricatorPolicyCapability', 'AlmanacManagementLockWorkflow' => 'AlmanacManagementWorkflow',
'AlmanacManagementRegisterWorkflow' => 'AlmanacManagementWorkflow', 'AlmanacManagementRegisterWorkflow' => 'AlmanacManagementWorkflow',
'AlmanacManagementTrustKeyWorkflow' => 'AlmanacManagementWorkflow', 'AlmanacManagementTrustKeyWorkflow' => 'AlmanacManagementWorkflow',
'AlmanacManagementUnlockWorkflow' => 'AlmanacManagementWorkflow',
'AlmanacManagementUntrustKeyWorkflow' => 'AlmanacManagementWorkflow', 'AlmanacManagementUntrustKeyWorkflow' => 'AlmanacManagementWorkflow',
'AlmanacManagementWorkflow' => 'PhabricatorManagementWorkflow', 'AlmanacManagementWorkflow' => 'PhabricatorManagementWorkflow',
'AlmanacNames' => 'Phobject', 'AlmanacNames' => 'Phobject',
@ -4128,7 +4131,6 @@ phutil_register_library_map(array(
'PhabricatorDestructibleInterface', 'PhabricatorDestructibleInterface',
'PhabricatorNgramsInterface', 'PhabricatorNgramsInterface',
'PhabricatorConduitResultInterface', 'PhabricatorConduitResultInterface',
'PhabricatorExtendedPolicyInterface',
), ),
'AlmanacServiceController' => 'AlmanacController', 'AlmanacServiceController' => 'AlmanacController',
'AlmanacServiceDatasource' => 'PhabricatorTypeaheadDatasource', 'AlmanacServiceDatasource' => 'PhabricatorTypeaheadDatasource',

View file

@ -0,0 +1,18 @@
<?php
class DrydockCommandError {
public static function newFromCommandException(
$phase,
$command,
CommandException $ex) {
$error = array(
'phase' => $phase,
'command' => (string)$command,
'raw' => (string)$ex->getCommand(),
'err' => $ex->getError(),
'stdout' => $ex->getStdout(),
'stderr' => $ex->getStderr(),
);
return $error;
}
}

View file

@ -448,35 +448,17 @@ final class DrydockWorkingCopyBlueprintImplementation
try { try {
$interface->execx('%C', $real_command); $interface->execx('%C', $real_command);
} catch (CommandException $ex) { } catch (CommandException $ex) {
$this->setWorkingCopyVCSErrorFromCommandException( $error = DrydockCommandError::newFromCommandException(
$lease,
self::PHASE_SQUASHMERGE, self::PHASE_SQUASHMERGE,
$show_command, $show_command,
$ex); $ex);
$lease->setAttribute('workingcopy.vcs.error', $error);
throw $ex; throw $ex;
} }
} }
protected function setWorkingCopyVCSErrorFromCommandException( public function getCommandError(DrydockLease $lease) {
DrydockLease $lease,
$phase,
$command,
CommandException $ex) {
$error = array(
'phase' => $phase,
'command' => (string)$command,
'raw' => (string)$ex->getCommand(),
'err' => $ex->getError(),
'stdout' => $ex->getStdout(),
'stderr' => $ex->getStderr(),
);
$lease->setAttribute('workingcopy.vcs.error', $error);
}
public function getWorkingCopyVCSError(DrydockLease $lease) {
$error = $lease->getAttribute('workingcopy.vcs.error'); $error = $lease->getAttribute('workingcopy.vcs.error');
if (!$error) { if (!$error) {
return null; return null;

View file

@ -4,6 +4,7 @@ final class DrydockLandRepositoryOperation
extends DrydockRepositoryOperationType { extends DrydockRepositoryOperationType {
const OPCONST = 'land'; const OPCONST = 'land';
const PHASE_PUSH = 'push';
public function getOperationDescription( public function getOperationDescription(
DrydockRepositoryOperation $operation, DrydockRepositoryOperation $operation,
@ -122,10 +123,23 @@ final class DrydockLandRepositoryOperation
->write($commit_message) ->write($commit_message)
->resolvex(); ->resolvex();
$interface->execx( try {
$interface->execx(
'git push origin -- %s:%s',
'HEAD',
$push_dst);
} catch (CommandException $ex) {
$show_command = csprintf(
'git push origin -- %s:%s', 'git push origin -- %s:%s',
'HEAD', 'HEAD',
$push_dst); $push_dst);
$error = DrydockCommandError::newFromCommandException(
self::PHASE_PUSH,
$show_command,
$ex);
$operation->setCommandError($error);
throw $ex;
}
} }
private function getCommitterInfo(DrydockRepositoryOperation $operation) { private function getCommitterInfo(DrydockRepositoryOperation $operation) {

View file

@ -178,11 +178,11 @@ final class DrydockRepositoryOperation extends DrydockDAO
return $this->getProperty('exec.leasePHID'); return $this->getProperty('exec.leasePHID');
} }
public function setWorkingCopyVCSError(array $error) { public function setCommandError(array $error) {
return $this->setProperty('exec.workingcopy.error', $error); return $this->setProperty('exec.workingcopy.error', $error);
} }
public function getWorkingCopyVCSError() { public function getCommandError() {
return $this->getProperty('exec.workingcopy.error'); return $this->getProperty('exec.workingcopy.error');
} }

View file

@ -74,7 +74,7 @@ final class DrydockRepositoryOperationStatusView
if ($state != DrydockRepositoryOperation::STATE_FAIL) { if ($state != DrydockRepositoryOperation::STATE_FAIL) {
$item->addAttribute($operation->getOperationCurrentStatus($viewer)); $item->addAttribute($operation->getOperationCurrentStatus($viewer));
} else { } else {
$vcs_error = $operation->getWorkingCopyVCSError(); $vcs_error = $operation->getCommandError();
if ($vcs_error) { if ($vcs_error) {
switch ($vcs_error['phase']) { switch ($vcs_error['phase']) {
case DrydockWorkingCopyBlueprintImplementation::PHASE_SQUASHMERGE: case DrydockWorkingCopyBlueprintImplementation::PHASE_SQUASHMERGE:
@ -82,6 +82,12 @@ final class DrydockRepositoryOperationStatusView
'This change did not merge cleanly. This usually indicates '. 'This change did not merge cleanly. This usually indicates '.
'that the change is out of date and needs to be updated.'); 'that the change is out of date and needs to be updated.');
break; break;
case DrydockLandRepositoryOperation::PHASE_PUSH:
$message = pht(
'The push failed. This usually indicates '.
'that the change is breaking some rules or '.
'some custom commit hook has failed.');
break;
default: default:
$message = pht( $message = pht(
'Operation encountered an error while performing repository '. 'Operation encountered an error while performing repository '.

View file

@ -138,10 +138,10 @@ final class DrydockRepositoryOperationUpdateWorker
} }
if (!$lease->isActive()) { if (!$lease->isActive()) {
$vcs_error = $working_copy->getWorkingCopyVCSError($lease); $vcs_error = $working_copy->getCommandError($lease);
if ($vcs_error) { if ($vcs_error) {
$operation $operation
->setWorkingCopyVCSError($vcs_error) ->setCommandError($vcs_error)
->save(); ->save();
} }