Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15285401
D14343.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
7 KB
Referenced Files
None
Subscribers
None
D14343.diff
View Options
diff --git a/src/applications/drydock/blueprint/DrydockWorkingCopyBlueprintImplementation.php b/src/applications/drydock/blueprint/DrydockWorkingCopyBlueprintImplementation.php
--- a/src/applications/drydock/blueprint/DrydockWorkingCopyBlueprintImplementation.php
+++ b/src/applications/drydock/blueprint/DrydockWorkingCopyBlueprintImplementation.php
@@ -3,6 +3,8 @@
final class DrydockWorkingCopyBlueprintImplementation
extends DrydockBlueprintImplementation {
+ const PHASE_SQUASHMERGE = 'squashmerge';
+
public function isEnabled() {
return true;
}
@@ -288,7 +290,7 @@
$merges = idx($spec, 'merges');
if ($merges) {
foreach ($merges as $merge) {
- $this->applyMerge($interface, $merge);
+ $this->applyMerge($lease, $interface, $merge);
}
}
@@ -416,6 +418,7 @@
}
private function applyMerge(
+ DrydockLease $lease,
DrydockCommandInterface $interface,
array $merge) {
@@ -428,15 +431,48 @@
$src_ref,
$src_ref);
+ $command = csprintf(
+ 'git merge --no-stat --squash --ff-only -- %R',
+ $src_ref);
+
try {
- $interface->execx(
- 'git merge --no-stat --squash --ff-only -- %s',
- $src_ref);
+ $interface->execx('%C', $command);
} catch (CommandException $ex) {
- // TODO: Specifically note this as a merge conflict.
+ $this->setWorkingCopyVCSErrorFromCommandException(
+ $lease,
+ self::PHASE_SQUASHMERGE,
+ $command,
+ $ex);
+
throw $ex;
}
}
+ protected function setWorkingCopyVCSErrorFromCommandException(
+ 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');
+ if (!$error) {
+ return null;
+ } else {
+ return $error;
+ }
+ }
}
diff --git a/src/applications/drydock/storage/DrydockRepositoryOperation.php b/src/applications/drydock/storage/DrydockRepositoryOperation.php
--- a/src/applications/drydock/storage/DrydockRepositoryOperation.php
+++ b/src/applications/drydock/storage/DrydockRepositoryOperation.php
@@ -175,6 +175,14 @@
return $this->getProperty('exec.leasePHID');
}
+ public function setWorkingCopyVCSError(array $error) {
+ return $this->setProperty('exec.workingcopy.error', $error);
+ }
+
+ public function getWorkingCopyVCSError() {
+ return $this->getProperty('exec.workingcopy.error');
+ }
+
/* -( PhabricatorPolicyInterface )----------------------------------------- */
diff --git a/src/applications/drydock/view/DrydockRepositoryOperationStatusView.php b/src/applications/drydock/view/DrydockRepositoryOperationStatusView.php
--- a/src/applications/drydock/view/DrydockRepositoryOperationStatusView.php
+++ b/src/applications/drydock/view/DrydockRepositoryOperationStatusView.php
@@ -73,12 +73,104 @@
if ($state != DrydockRepositoryOperation::STATE_FAIL) {
$item->addAttribute($operation->getOperationCurrentStatus($viewer));
} else {
- // TODO: Make this more useful.
- $item->addAttribute(pht('Operation encountered an error.'));
+ $vcs_error = $operation->getWorkingCopyVCSError();
+ if ($vcs_error) {
+ switch ($vcs_error['phase']) {
+ case DrydockWorkingCopyBlueprintImplementation::PHASE_SQUASHMERGE:
+ $message = pht(
+ 'This change did not merge cleanly. This usually indicates '.
+ 'that the change is out of date and needs to be updated.');
+ break;
+ default:
+ $message = pht(
+ 'Operation encountered an error while performing repository '.
+ 'operations.');
+ break;
+ }
+
+ $item->addAttribute($message);
+
+ $table = $this->renderVCSErrorTable($vcs_error);
+ list($links, $info) = $this->renderDetailToggles($table);
+
+ $item->addAttribute($links);
+ $item->appendChild($info);
+ } else {
+ $item->addAttribute(pht('Operation encountered an error.'));
+ }
}
return id(new PHUIObjectItemListView())
->addItem($item);
}
+ private function renderVCSErrorTable(array $vcs_error) {
+ $rows = array();
+ $rows[] = array(pht('Command'), $vcs_error['command']);
+ $rows[] = array(pht('Error'), $vcs_error['err']);
+ $rows[] = array(pht('Stdout'), $vcs_error['stdout']);
+ $rows[] = array(pht('Stderr'), $vcs_error['stderr']);
+
+ $table = id(new AphrontTableView($rows))
+ ->setColumnClasses(
+ array(
+ 'header',
+ 'wide',
+ ));
+
+ return $table;
+ }
+
+ private function renderDetailToggles(AphrontTableView $table) {
+ $show_id = celerity_generate_unique_node_id();
+ $hide_id = celerity_generate_unique_node_id();
+ $info_id = celerity_generate_unique_node_id();
+
+ Javelin::initBehavior('phabricator-reveal-content');
+
+ $show_details = javelin_tag(
+ 'a',
+ array(
+ 'id' => $show_id,
+ 'href' => '#',
+ 'sigil' => 'reveal-content',
+ 'mustcapture' => true,
+ 'meta' => array(
+ 'hideIDs' => array($show_id),
+ 'showIDs' => array($hide_id, $info_id),
+ ),
+ ),
+ pht('Show Details'));
+
+ $hide_details = javelin_tag(
+ 'a',
+ array(
+ 'id' => $hide_id,
+ 'href' => '#',
+ 'sigil' => 'reveal-content',
+ 'mustcapture' => true,
+ 'style' => 'display: none',
+ 'meta' => array(
+ 'hideIDs' => array($hide_id, $info_id),
+ 'showIDs' => array($show_id),
+ ),
+ ),
+ pht('Hide Details'));
+
+ $info = javelin_tag(
+ 'div',
+ array(
+ 'id' => $info_id,
+ 'style' => 'display: none',
+ ),
+ $table);
+
+ $links = array(
+ $show_details,
+ $hide_details,
+ );
+
+ return array($links, $info);
+ }
+
}
diff --git a/src/applications/drydock/worker/DrydockRepositoryOperationUpdateWorker.php b/src/applications/drydock/worker/DrydockRepositoryOperationUpdateWorker.php
--- a/src/applications/drydock/worker/DrydockRepositoryOperationUpdateWorker.php
+++ b/src/applications/drydock/worker/DrydockRepositoryOperationUpdateWorker.php
@@ -90,6 +90,9 @@
// TODO: This is very similar to leasing in Harbormaster, maybe we can
// share some of the logic?
+ $working_copy = new DrydockWorkingCopyBlueprintImplementation();
+ $working_copy_type = $working_copy->getType();
+
$lease_phid = $operation->getProperty('exec.leasePHID');
if ($lease_phid) {
$lease = id(new DrydockLeaseQuery())
@@ -103,9 +106,6 @@
$lease_phid));
}
} else {
- $working_copy_type = id(new DrydockWorkingCopyBlueprintImplementation())
- ->getType();
-
$repository = $operation->getRepository();
$allowed_phids = $repository->getAutomationBlueprintPHIDs();
@@ -138,6 +138,13 @@
}
if (!$lease->isActive()) {
+ $vcs_error = $working_copy->getWorkingCopyVCSError($lease);
+ if ($vcs_error) {
+ $operation
+ ->setWorkingCopyVCSError($vcs_error)
+ ->save();
+ }
+
throw new PhabricatorWorkerPermanentFailureException(
pht(
'Lease "%s" never activated.',
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Mar 5, 1:27 PM (23 h, 30 m ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7225642
Default Alt Text
D14343.diff (7 KB)
Attached To
Mode
D14343: Make "Land Revision" show merge conflicts more clearly
Attached
Detach File
Event Timeline
Log In to Comment