@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add a "Recent Builds" element to the Build Plan UI and tighten up a few odds and ends

Summary:
Depends on D20218. Ref T13258. It's somewhat cumbersome to get from build plans to related builds but this is a reasonable thing to want to do, so make it a little easier.

Also clean up / standardize / hint a few things a little better.

Test Plan: {F6244116}

Reviewers: amckinley

Reviewed By: amckinley

Subscribers: PHID-OPKG-gm6ozazyms6q6i22gyam

Maniphest Tasks: T13258

Differential Revision: https://secure.phabricator.com/D20219

+151 -65
+2
src/__phutil_library_map__.php
··· 1370 1370 'HarbormasterBuildTransactionQuery' => 'applications/harbormaster/query/HarbormasterBuildTransactionQuery.php', 1371 1371 'HarbormasterBuildUnitMessage' => 'applications/harbormaster/storage/build/HarbormasterBuildUnitMessage.php', 1372 1372 'HarbormasterBuildUnitMessageQuery' => 'applications/harbormaster/query/HarbormasterBuildUnitMessageQuery.php', 1373 + 'HarbormasterBuildView' => 'applications/harbormaster/view/HarbormasterBuildView.php', 1373 1374 'HarbormasterBuildViewController' => 'applications/harbormaster/controller/HarbormasterBuildViewController.php', 1374 1375 'HarbormasterBuildWorker' => 'applications/harbormaster/worker/HarbormasterBuildWorker.php', 1375 1376 'HarbormasterBuildable' => 'applications/harbormaster/storage/HarbormasterBuildable.php', ··· 6999 7000 'PhabricatorPolicyInterface', 7000 7001 ), 7001 7002 'HarbormasterBuildUnitMessageQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 7003 + 'HarbormasterBuildView' => 'AphrontView', 7002 7004 'HarbormasterBuildViewController' => 'HarbormasterController', 7003 7005 'HarbormasterBuildWorker' => 'HarbormasterWorker', 7004 7006 'HarbormasterBuildable' => array(
+70 -22
src/applications/harbormaster/controller/HarbormasterPlanViewController.php
··· 18 18 return new Aphront404Response(); 19 19 } 20 20 21 - $timeline = $this->buildTransactionTimeline( 22 - $plan, 23 - new HarbormasterBuildPlanTransactionQuery()); 24 - $timeline->setShouldTerminate(true); 25 - 26 21 $title = $plan->getName(); 27 22 28 23 $header = id(new PHUIHeaderView()) ··· 33 28 34 29 $curtain = $this->buildCurtainView($plan); 35 30 36 - $crumbs = $this->buildApplicationCrumbs(); 37 - $crumbs->addTextCrumb(pht('Plan %d', $id)); 38 - $crumbs->setBorder(true); 31 + $crumbs = $this->buildApplicationCrumbs() 32 + ->addTextCrumb($plan->getObjectName()) 33 + ->setBorder(true); 39 34 40 - list($step_list, $has_any_conflicts, $would_deadlock) = 35 + list($step_list, $has_any_conflicts, $would_deadlock, $steps) = 41 36 $this->buildStepList($plan); 42 37 43 38 $error = null; 44 - if ($would_deadlock) { 45 - $error = pht('This build plan will deadlock when executed, due to '. 46 - 'circular dependencies present in the build plan. '. 47 - 'Examine the step list and resolve the deadlock.'); 39 + if (!$steps) { 40 + $error = pht( 41 + 'This build plan does not have any build steps yet, so it will '. 42 + 'not do anything when run.'); 43 + } else if ($would_deadlock) { 44 + $error = pht( 45 + 'This build plan will deadlock when executed, due to circular '. 46 + 'dependencies present in the build plan. Examine the step list '. 47 + 'and resolve the deadlock.'); 48 48 } else if ($has_any_conflicts) { 49 49 // A deadlocking build will also cause all the artifacts to be 50 50 // invalid, so we just skip showing this message if that's the 51 51 // case. 52 - $error = pht('This build plan has conflicts in one or more build steps. '. 53 - 'Examine the step list and resolve the listed errors.'); 52 + $error = pht( 53 + 'This build plan has conflicts in one or more build steps. '. 54 + 'Examine the step list and resolve the listed errors.'); 54 55 } 55 56 56 57 if ($error) { ··· 59 60 ->appendChild($error); 60 61 } 61 62 63 + $builds_view = $this->newBuildsView($plan); 64 + 65 + $timeline = $this->buildTransactionTimeline( 66 + $plan, 67 + new HarbormasterBuildPlanTransactionQuery()); 68 + $timeline->setShouldTerminate(true); 69 + 62 70 $view = id(new PHUITwoColumnView()) 63 71 ->setHeader($header) 64 72 ->setCurtain($curtain) 65 - ->setMainColumn(array( 66 - $error, 67 - $step_list, 68 - $timeline, 69 - )); 73 + ->setMainColumn( 74 + array( 75 + $error, 76 + $step_list, 77 + $builds_view, 78 + $timeline, 79 + )); 70 80 71 81 return $this->newPage() 72 82 ->setTitle($title) 73 83 ->setCrumbs($crumbs) 84 + ->setPageObjectPHIDs(array($plan->getPHID())) 74 85 ->appendChild($view); 75 86 } 76 87 ··· 213 224 ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 214 225 ->appendChild($step_list); 215 226 216 - return array($step_box, $has_any_conflicts, $is_deadlocking); 227 + return array($step_box, $has_any_conflicts, $is_deadlocking, $steps); 217 228 } 218 229 219 230 private function buildCurtainView(HarbormasterBuildPlan $plan) { ··· 376 387 array $steps) { 377 388 $has_conflicts = false; 378 389 379 - if (count($step_phids) === 0) { 390 + if (!$step_phids) { 380 391 return null; 381 392 } 382 393 ··· 436 447 437 448 return array($ui, $has_conflicts); 438 449 } 450 + 451 + private function newBuildsView(HarbormasterBuildPlan $plan) { 452 + $viewer = $this->getViewer(); 453 + 454 + $builds = id(new HarbormasterBuildQuery()) 455 + ->setViewer($viewer) 456 + ->withBuildPlanPHIDs(array($plan->getPHID())) 457 + ->setLimit(10) 458 + ->execute(); 459 + 460 + $list = id(new HarbormasterBuildView()) 461 + ->setViewer($viewer) 462 + ->setBuilds($builds) 463 + ->newObjectList(); 464 + 465 + $list->setNoDataString(pht('No recent builds.')); 466 + 467 + $more_href = new PhutilURI( 468 + $this->getApplicationURI('/build/'), 469 + array('plan' => $plan->getPHID())); 470 + 471 + $more_link = id(new PHUIButtonView()) 472 + ->setTag('a') 473 + ->setIcon('fa-list-ul') 474 + ->setText(pht('View All Builds')) 475 + ->setHref($more_href); 476 + 477 + $header = id(new PHUIHeaderView()) 478 + ->setHeader(pht('Recent Builds')) 479 + ->addActionLink($more_link); 480 + 481 + return id(new PHUIObjectBoxView()) 482 + ->setHeader($header) 483 + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 484 + ->appendChild($list); 485 + } 486 + 439 487 }
+7 -42
src/applications/harbormaster/query/HarbormasterBuildSearchEngine.php
··· 128 128 129 129 $viewer = $this->requireViewer(); 130 130 131 - $buildables = mpull($builds, 'getBuildable'); 132 - $object_phids = mpull($buildables, 'getBuildablePHID'); 133 - $initiator_phids = mpull($builds, 'getInitiatorPHID'); 134 - $phids = array_mergev(array($initiator_phids, $object_phids)); 135 - $phids = array_unique(array_filter($phids)); 131 + $list = id(new HarbormasterBuildView()) 132 + ->setViewer($viewer) 133 + ->setBuilds($builds) 134 + ->newObjectList(); 136 135 137 - $handles = $viewer->loadHandles($phids); 138 - 139 - $list = new PHUIObjectItemListView(); 140 - foreach ($builds as $build) { 141 - $id = $build->getID(); 142 - $initiator = $handles[$build->getInitiatorPHID()]; 143 - $buildable_object = $handles[$build->getBuildable()->getBuildablePHID()]; 144 - 145 - $item = id(new PHUIObjectItemView()) 146 - ->setViewer($viewer) 147 - ->setObject($build) 148 - ->setObjectName(pht('Build %d', $build->getID())) 149 - ->setHeader($build->getName()) 150 - ->setHref($build->getURI()) 151 - ->setEpoch($build->getDateCreated()) 152 - ->addAttribute($buildable_object->getName()); 153 - 154 - if ($initiator) { 155 - $item->addHandleIcon($initiator, $initiator->getName()); 156 - } 157 - 158 - $status = $build->getBuildStatus(); 159 - 160 - $status_icon = HarbormasterBuildStatus::getBuildStatusIcon($status); 161 - $status_color = HarbormasterBuildStatus::getBuildStatusColor($status); 162 - $status_label = HarbormasterBuildStatus::getBuildStatusName($status); 163 - 164 - $item->setStatusIcon("{$status_icon} {$status_color}", $status_label); 165 - 166 - $list->addItem($item); 167 - } 168 - 169 - $result = new PhabricatorApplicationSearchResultView(); 170 - $result->setObjectList($list); 171 - $result->setNoDataString(pht('No builds found.')); 172 - 173 - return $result; 136 + return id(new PhabricatorApplicationSearchResultView()) 137 + ->setObjectList($list) 138 + ->setNoDataString(pht('No builds found.')); 174 139 } 175 140 176 141 }
+4
src/applications/harbormaster/storage/build/HarbormasterBuild.php
··· 193 193 return HarbormasterBuildStatus::newBuildStatusObject($status_key); 194 194 } 195 195 196 + public function getObjectName() { 197 + return pht('Build %d', $this->getID()); 198 + } 199 + 196 200 197 201 /* -( Build Commands )----------------------------------------------------- */ 198 202
+1 -1
src/applications/harbormaster/storage/configuration/HarbormasterBuildPlan.php
··· 91 91 } 92 92 93 93 public function getObjectName() { 94 - return pht('Build Plan %d', $this->getID()); 94 + return pht('Plan %d', $this->getID()); 95 95 } 96 96 97 97
+67
src/applications/harbormaster/view/HarbormasterBuildView.php
··· 1 + <?php 2 + 3 + final class HarbormasterBuildView 4 + extends AphrontView { 5 + 6 + private $builds = array(); 7 + 8 + public function setBuilds(array $builds) { 9 + assert_instances_of($builds, 'HarbormasterBuild'); 10 + $this->builds = $builds; 11 + return $this; 12 + } 13 + 14 + public function getBuilds() { 15 + return $this->builds; 16 + } 17 + 18 + public function render() { 19 + return $this->newObjectList(); 20 + } 21 + 22 + public function newObjectList() { 23 + $viewer = $this->getViewer(); 24 + $builds = $this->getBuilds(); 25 + 26 + $buildables = mpull($builds, 'getBuildable'); 27 + $object_phids = mpull($buildables, 'getBuildablePHID'); 28 + $initiator_phids = mpull($builds, 'getInitiatorPHID'); 29 + $phids = array_mergev(array($initiator_phids, $object_phids)); 30 + $phids = array_unique(array_filter($phids)); 31 + 32 + $handles = $viewer->loadHandles($phids); 33 + 34 + $list = new PHUIObjectItemListView(); 35 + foreach ($builds as $build) { 36 + $id = $build->getID(); 37 + $initiator = $handles[$build->getInitiatorPHID()]; 38 + $buildable_object = $handles[$build->getBuildable()->getBuildablePHID()]; 39 + 40 + $item = id(new PHUIObjectItemView()) 41 + ->setViewer($viewer) 42 + ->setObject($build) 43 + ->setObjectName($build->getObjectName()) 44 + ->setHeader($build->getName()) 45 + ->setHref($build->getURI()) 46 + ->setEpoch($build->getDateCreated()) 47 + ->addAttribute($buildable_object->getName()); 48 + 49 + if ($initiator) { 50 + $item->addByline($initiator->renderLink()); 51 + } 52 + 53 + $status = $build->getBuildStatus(); 54 + 55 + $status_icon = HarbormasterBuildStatus::getBuildStatusIcon($status); 56 + $status_color = HarbormasterBuildStatus::getBuildStatusColor($status); 57 + $status_label = HarbormasterBuildStatus::getBuildStatusName($status); 58 + 59 + $item->setStatusIcon("{$status_icon} {$status_color}", $status_label); 60 + 61 + $list->addItem($item); 62 + } 63 + 64 + return $list; 65 + } 66 + 67 + }