@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.

Smooth out some UI/UX issues in Harbormaster

Summary:
Ref T8096. Fixes a few bugs and glitches.

- Set build completion time when handling a message.
- Format duration information in a more human-readable way.
- Use a table for build variables.
- Fix up container PHIDs on diffs (a touch hacky, should be OK for now though).

Test Plan: Browsed around the UI.

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: epriestley

Maniphest Tasks: T8096

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

+119 -45
+15
src/applications/differential/editor/DifferentialTransactionEditor.php
··· 587 587 588 588 $diff->setRevisionID($object->getID()); 589 589 $diff->save(); 590 + 591 + // Update Harbormaster to set the containerPHID correctly for any 592 + // existing buildables. We may otherwise have buildables stuck with 593 + // the old (`null`) container. 594 + 595 + // TODO: This is a bit iffy, maybe we can find a cleaner approach? 596 + $table = new HarbormasterBuildable(); 597 + $conn_w = $table->establishConnection('w'); 598 + queryfx( 599 + $conn_w, 600 + 'UPDATE %T SET containerPHID = %s WHERE buildablePHID = %s', 601 + $table->getTableName(), 602 + $object->getPHID(), 603 + $diff->getPHID()); 604 + 590 605 return; 591 606 } 592 607
+75 -25
src/applications/harbormaster/controller/HarbormasterBuildViewController.php
··· 48 48 $this->buildPropertyLists($box, $build, $actions); 49 49 50 50 $crumbs = $this->buildApplicationCrumbs(); 51 - $crumbs->addTextCrumb( 52 - $build->getBuildable()->getMonogram(), 53 - '/'.$build->getBuildable()->getMonogram()); 51 + $this->addBuildableCrumb($crumbs, $build->getBuildable()); 54 52 $crumbs->addTextCrumb($title); 55 53 56 54 if ($generation === null || $generation > $build->getBuildGeneration() || ··· 99 97 $item->setIcon($icon, $color); 100 98 $status_view->addItem($item); 101 99 102 - $properties->addProperty(pht('Name'), $build_target->getName()); 100 + $when = array(); 101 + $started = $build_target->getDateStarted(); 102 + $now = PhabricatorTime::getNow(); 103 + if ($started) { 104 + $ended = $build_target->getDateCompleted(); 105 + if ($ended) { 106 + $when[] = pht( 107 + 'Completed at %s', 108 + phabricator_datetime($started, $viewer)); 103 109 104 - if ($build_target->getDateStarted() !== null) { 105 - $properties->addProperty( 106 - pht('Started'), 107 - phabricator_datetime($build_target->getDateStarted(), $viewer)); 108 - if ($build_target->isComplete()) { 109 - $properties->addProperty( 110 - pht('Completed'), 111 - phabricator_datetime($build_target->getDateCompleted(), $viewer)); 112 - $properties->addProperty( 113 - pht('Duration'), 114 - phutil_format_relative_time_detailed( 115 - $build_target->getDateCompleted() - 116 - $build_target->getDateStarted())); 110 + $duration = ($ended - $started); 111 + if ($duration) { 112 + $when[] = pht( 113 + 'Built for %s', 114 + phutil_format_relative_time_detailed($duration)); 115 + } else { 116 + $when[] = pht('Built instantly'); 117 + } 117 118 } else { 118 - $properties->addProperty( 119 - pht('Elapsed'), 120 - phutil_format_relative_time_detailed( 121 - time() - $build_target->getDateStarted())); 119 + $when[] = pht( 120 + 'Started at %s', 121 + phabricator_datetime($started, $viewer)); 122 + $duration = ($now - $started); 123 + if ($duration) { 124 + $when[] = pht( 125 + 'Running for %s', 126 + phutil_format_relative_time_detailed($duration)); 127 + } 128 + } 129 + } else { 130 + $created = $build_target->getDateCreated(); 131 + $when[] = pht( 132 + 'Queued at %s', 133 + phabricator_datetime($started, $viewer)); 134 + $duration = ($now - $created); 135 + if ($duration) { 136 + $when[] = pht( 137 + 'Waiting for %s', 138 + phutil_format_relative_time_detailed($duration)); 122 139 } 123 140 } 141 + 142 + $properties->addProperty( 143 + pht('When'), 144 + phutil_implode_html(" \xC2\xB7 ", $when)); 124 145 125 146 $properties->addProperty(pht('Status'), $status_view); 126 147 ··· 162 183 $variables = $build_target->getVariables(); 163 184 if ($variables) { 164 185 $properties = new PHUIPropertyListView(); 165 - foreach ($variables as $key => $value) { 166 - $properties->addProperty($key, $value); 167 - } 186 + $properties->addRawContent($this->buildProperties($variables)); 168 187 $target_box->addPropertyList($properties, pht('Variables')); 169 188 } 170 189 ··· 183 202 } 184 203 185 204 $properties = new PHUIPropertyListView(); 186 - $properties->addProperty(pht('Build Target ID'), $build_target->getID()); 205 + $properties->addProperty( 206 + pht('Build Target ID'), 207 + $build_target->getID()); 208 + $properties->addProperty( 209 + pht('Build Target PHID'), 210 + $build_target->getPHID()); 187 211 $target_box->addPropertyList($properties, pht('Metadata')); 188 212 189 213 $targets[] = $target_box; ··· 524 548 '', 525 549 'date', 526 550 )); 551 + 552 + return $table; 553 + } 554 + 555 + private function buildProperties(array $properties) { 556 + ksort($properties); 557 + 558 + $rows = array(); 559 + foreach ($properties as $key => $value) { 560 + $rows[] = array( 561 + $key, 562 + $value, 563 + ); 564 + } 565 + 566 + $table = id(new AphrontTableView($rows)) 567 + ->setHeaders( 568 + array( 569 + pht('Key'), 570 + pht('Value'), 571 + )) 572 + ->setColumnClasses( 573 + array( 574 + 'pri right', 575 + 'wide', 576 + )); 527 577 528 578 return $table; 529 579 }
+11 -17
src/applications/harbormaster/controller/HarbormasterBuildableViewController.php
··· 3 3 final class HarbormasterBuildableViewController 4 4 extends HarbormasterController { 5 5 6 - private $id; 7 - 8 - public function willProcessRequest(array $data) { 9 - $this->id = $data['id']; 10 - } 11 - 12 - public function processRequest() { 13 - $request = $this->getRequest(); 14 - $viewer = $request->getUser(); 15 - 16 - $id = $this->id; 6 + public function handleRequest(AphrontRequest $request) { 7 + $viewer = $this->getViewer(); 17 8 18 9 $buildable = id(new HarbormasterBuildableQuery()) 19 10 ->setViewer($viewer) 20 - ->withIDs(array($id)) 11 + ->withIDs(array($request->getURIData('id'))) 21 12 ->needBuildableHandles(true) 22 13 ->needContainerHandles(true) 23 14 ->executeOne(); ··· 25 16 return new Aphront404Response(); 26 17 } 27 18 19 + $id = $buildable->getID(); 20 + 28 21 // Pull builds and build targets. 29 22 $builds = id(new HarbormasterBuildQuery()) 30 23 ->setViewer($viewer) ··· 33 26 ->execute(); 34 27 35 28 $buildable->attachBuilds($builds); 29 + $object = $buildable->getBuildableObject(); 36 30 37 31 $build_list = $this->buildBuildList($buildable); 38 32 ··· 55 49 $this->buildPropertyLists($box, $buildable, $actions); 56 50 57 51 $crumbs = $this->buildApplicationCrumbs(); 58 - $crumbs->addTextCrumb("B{$id}"); 52 + $crumbs->addTextCrumb($buildable->getMonogram()); 59 53 60 54 return $this->buildApplicationPage( 61 55 array( ··· 144 138 ->setActionList($actions); 145 139 $box->addPropertyList($properties); 146 140 147 - $properties->addProperty( 148 - pht('Buildable'), 149 - $buildable->getBuildableHandle()->renderLink()); 150 - 151 141 if ($buildable->getContainerHandle() !== null) { 152 142 $properties->addProperty( 153 143 pht('Container'), 154 144 $buildable->getContainerHandle()->renderLink()); 155 145 } 146 + 147 + $properties->addProperty( 148 + pht('Buildable'), 149 + $buildable->getBuildableHandle()->renderLink()); 156 150 157 151 $properties->addProperty( 158 152 pht('Origin'),
+10
src/applications/harbormaster/controller/HarbormasterController.php
··· 2 2 3 3 abstract class HarbormasterController extends PhabricatorController { 4 4 5 + protected function addBuildableCrumb( 6 + PHUICrumbsView $crumbs, 7 + HarbormasterBuildable $buildable) { 8 + 9 + $monogram = $buildable->getMonogram(); 10 + $uri = '/'.$monogram; 11 + 12 + $crumbs->addTextCrumb($monogram, $uri); 13 + } 14 + 5 15 }
+5
src/applications/harbormaster/engine/HarbormasterBuildEngine.php
··· 332 332 $message->save(); 333 333 334 334 $target->setTargetStatus($new_status); 335 + 336 + if ($target->isComplete()) { 337 + $target->setDateCompleted(PhabricatorTime::getNow()); 338 + } 339 + 335 340 $target->save(); 336 341 } 337 342 }
+3 -3
src/applications/harbormaster/worker/HarbormasterTargetWorker.php
··· 59 59 $target->setTargetStatus($next_status); 60 60 61 61 if ($target->isComplete()) { 62 - $target->setDateCompleted(time()); 62 + $target->setDateCompleted(PhabricatorTime::getNow()); 63 63 } 64 64 65 65 $target->save(); ··· 70 70 } catch (HarbormasterBuildFailureException $ex) { 71 71 // A build step wants to fail explicitly. 72 72 $target->setTargetStatus(HarbormasterBuildTarget::STATUS_FAILED); 73 - $target->setDateCompleted(time()); 73 + $target->setDateCompleted(PhabricatorTime::getNow()); 74 74 $target->save(); 75 75 } catch (HarbormasterBuildAbortedException $ex) { 76 76 // A build step is aborting because the build has been restarted. 77 77 $target->setTargetStatus(HarbormasterBuildTarget::STATUS_ABORTED); 78 - $target->setDateCompleted(time()); 78 + $target->setDateCompleted(PhabricatorTime::getNow()); 79 79 $target->save(); 80 80 } catch (Exception $ex) { 81 81 phlog($ex);