mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-23 22:10:55 +01:00
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
This commit is contained in:
parent
8338f94057
commit
620047bcfe
6 changed files with 151 additions and 65 deletions
|
@ -1370,6 +1370,7 @@ phutil_register_library_map(array(
|
|||
'HarbormasterBuildTransactionQuery' => 'applications/harbormaster/query/HarbormasterBuildTransactionQuery.php',
|
||||
'HarbormasterBuildUnitMessage' => 'applications/harbormaster/storage/build/HarbormasterBuildUnitMessage.php',
|
||||
'HarbormasterBuildUnitMessageQuery' => 'applications/harbormaster/query/HarbormasterBuildUnitMessageQuery.php',
|
||||
'HarbormasterBuildView' => 'applications/harbormaster/view/HarbormasterBuildView.php',
|
||||
'HarbormasterBuildViewController' => 'applications/harbormaster/controller/HarbormasterBuildViewController.php',
|
||||
'HarbormasterBuildWorker' => 'applications/harbormaster/worker/HarbormasterBuildWorker.php',
|
||||
'HarbormasterBuildable' => 'applications/harbormaster/storage/HarbormasterBuildable.php',
|
||||
|
@ -6999,6 +7000,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorPolicyInterface',
|
||||
),
|
||||
'HarbormasterBuildUnitMessageQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'HarbormasterBuildView' => 'AphrontView',
|
||||
'HarbormasterBuildViewController' => 'HarbormasterController',
|
||||
'HarbormasterBuildWorker' => 'HarbormasterWorker',
|
||||
'HarbormasterBuildable' => array(
|
||||
|
|
|
@ -18,11 +18,6 @@ final class HarbormasterPlanViewController extends HarbormasterPlanController {
|
|||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$timeline = $this->buildTransactionTimeline(
|
||||
$plan,
|
||||
new HarbormasterBuildPlanTransactionQuery());
|
||||
$timeline->setShouldTerminate(true);
|
||||
|
||||
$title = $plan->getName();
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
|
@ -33,24 +28,30 @@ final class HarbormasterPlanViewController extends HarbormasterPlanController {
|
|||
|
||||
$curtain = $this->buildCurtainView($plan);
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$crumbs->addTextCrumb(pht('Plan %d', $id));
|
||||
$crumbs->setBorder(true);
|
||||
$crumbs = $this->buildApplicationCrumbs()
|
||||
->addTextCrumb($plan->getObjectName())
|
||||
->setBorder(true);
|
||||
|
||||
list($step_list, $has_any_conflicts, $would_deadlock) =
|
||||
list($step_list, $has_any_conflicts, $would_deadlock, $steps) =
|
||||
$this->buildStepList($plan);
|
||||
|
||||
$error = null;
|
||||
if ($would_deadlock) {
|
||||
$error = pht('This build plan will deadlock when executed, due to '.
|
||||
'circular dependencies present in the build plan. '.
|
||||
'Examine the step list and resolve the deadlock.');
|
||||
if (!$steps) {
|
||||
$error = pht(
|
||||
'This build plan does not have any build steps yet, so it will '.
|
||||
'not do anything when run.');
|
||||
} else if ($would_deadlock) {
|
||||
$error = pht(
|
||||
'This build plan will deadlock when executed, due to circular '.
|
||||
'dependencies present in the build plan. Examine the step list '.
|
||||
'and resolve the deadlock.');
|
||||
} else if ($has_any_conflicts) {
|
||||
// A deadlocking build will also cause all the artifacts to be
|
||||
// invalid, so we just skip showing this message if that's the
|
||||
// case.
|
||||
$error = pht('This build plan has conflicts in one or more build steps. '.
|
||||
'Examine the step list and resolve the listed errors.');
|
||||
$error = pht(
|
||||
'This build plan has conflicts in one or more build steps. '.
|
||||
'Examine the step list and resolve the listed errors.');
|
||||
}
|
||||
|
||||
if ($error) {
|
||||
|
@ -59,18 +60,28 @@ final class HarbormasterPlanViewController extends HarbormasterPlanController {
|
|||
->appendChild($error);
|
||||
}
|
||||
|
||||
$builds_view = $this->newBuildsView($plan);
|
||||
|
||||
$timeline = $this->buildTransactionTimeline(
|
||||
$plan,
|
||||
new HarbormasterBuildPlanTransactionQuery());
|
||||
$timeline->setShouldTerminate(true);
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setCurtain($curtain)
|
||||
->setMainColumn(array(
|
||||
$error,
|
||||
$step_list,
|
||||
$timeline,
|
||||
));
|
||||
->setMainColumn(
|
||||
array(
|
||||
$error,
|
||||
$step_list,
|
||||
$builds_view,
|
||||
$timeline,
|
||||
));
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($title)
|
||||
->setCrumbs($crumbs)
|
||||
->setPageObjectPHIDs(array($plan->getPHID()))
|
||||
->appendChild($view);
|
||||
}
|
||||
|
||||
|
@ -213,7 +224,7 @@ final class HarbormasterPlanViewController extends HarbormasterPlanController {
|
|||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->appendChild($step_list);
|
||||
|
||||
return array($step_box, $has_any_conflicts, $is_deadlocking);
|
||||
return array($step_box, $has_any_conflicts, $is_deadlocking, $steps);
|
||||
}
|
||||
|
||||
private function buildCurtainView(HarbormasterBuildPlan $plan) {
|
||||
|
@ -376,7 +387,7 @@ final class HarbormasterPlanViewController extends HarbormasterPlanController {
|
|||
array $steps) {
|
||||
$has_conflicts = false;
|
||||
|
||||
if (count($step_phids) === 0) {
|
||||
if (!$step_phids) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -436,4 +447,41 @@ final class HarbormasterPlanViewController extends HarbormasterPlanController {
|
|||
|
||||
return array($ui, $has_conflicts);
|
||||
}
|
||||
|
||||
private function newBuildsView(HarbormasterBuildPlan $plan) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$builds = id(new HarbormasterBuildQuery())
|
||||
->setViewer($viewer)
|
||||
->withBuildPlanPHIDs(array($plan->getPHID()))
|
||||
->setLimit(10)
|
||||
->execute();
|
||||
|
||||
$list = id(new HarbormasterBuildView())
|
||||
->setViewer($viewer)
|
||||
->setBuilds($builds)
|
||||
->newObjectList();
|
||||
|
||||
$list->setNoDataString(pht('No recent builds.'));
|
||||
|
||||
$more_href = new PhutilURI(
|
||||
$this->getApplicationURI('/build/'),
|
||||
array('plan' => $plan->getPHID()));
|
||||
|
||||
$more_link = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setIcon('fa-list-ul')
|
||||
->setText(pht('View All Builds'))
|
||||
->setHref($more_href);
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader(pht('Recent Builds'))
|
||||
->addActionLink($more_link);
|
||||
|
||||
return id(new PHUIObjectBoxView())
|
||||
->setHeader($header)
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->appendChild($list);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -128,49 +128,14 @@ final class HarbormasterBuildSearchEngine
|
|||
|
||||
$viewer = $this->requireViewer();
|
||||
|
||||
$buildables = mpull($builds, 'getBuildable');
|
||||
$object_phids = mpull($buildables, 'getBuildablePHID');
|
||||
$initiator_phids = mpull($builds, 'getInitiatorPHID');
|
||||
$phids = array_mergev(array($initiator_phids, $object_phids));
|
||||
$phids = array_unique(array_filter($phids));
|
||||
$list = id(new HarbormasterBuildView())
|
||||
->setViewer($viewer)
|
||||
->setBuilds($builds)
|
||||
->newObjectList();
|
||||
|
||||
$handles = $viewer->loadHandles($phids);
|
||||
|
||||
$list = new PHUIObjectItemListView();
|
||||
foreach ($builds as $build) {
|
||||
$id = $build->getID();
|
||||
$initiator = $handles[$build->getInitiatorPHID()];
|
||||
$buildable_object = $handles[$build->getBuildable()->getBuildablePHID()];
|
||||
|
||||
$item = id(new PHUIObjectItemView())
|
||||
->setViewer($viewer)
|
||||
->setObject($build)
|
||||
->setObjectName(pht('Build %d', $build->getID()))
|
||||
->setHeader($build->getName())
|
||||
->setHref($build->getURI())
|
||||
->setEpoch($build->getDateCreated())
|
||||
->addAttribute($buildable_object->getName());
|
||||
|
||||
if ($initiator) {
|
||||
$item->addHandleIcon($initiator, $initiator->getName());
|
||||
}
|
||||
|
||||
$status = $build->getBuildStatus();
|
||||
|
||||
$status_icon = HarbormasterBuildStatus::getBuildStatusIcon($status);
|
||||
$status_color = HarbormasterBuildStatus::getBuildStatusColor($status);
|
||||
$status_label = HarbormasterBuildStatus::getBuildStatusName($status);
|
||||
|
||||
$item->setStatusIcon("{$status_icon} {$status_color}", $status_label);
|
||||
|
||||
$list->addItem($item);
|
||||
}
|
||||
|
||||
$result = new PhabricatorApplicationSearchResultView();
|
||||
$result->setObjectList($list);
|
||||
$result->setNoDataString(pht('No builds found.'));
|
||||
|
||||
return $result;
|
||||
return id(new PhabricatorApplicationSearchResultView())
|
||||
->setObjectList($list)
|
||||
->setNoDataString(pht('No builds found.'));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -193,6 +193,10 @@ final class HarbormasterBuild extends HarbormasterDAO
|
|||
return HarbormasterBuildStatus::newBuildStatusObject($status_key);
|
||||
}
|
||||
|
||||
public function getObjectName() {
|
||||
return pht('Build %d', $this->getID());
|
||||
}
|
||||
|
||||
|
||||
/* -( Build Commands )----------------------------------------------------- */
|
||||
|
||||
|
|
|
@ -91,7 +91,7 @@ final class HarbormasterBuildPlan extends HarbormasterDAO
|
|||
}
|
||||
|
||||
public function getObjectName() {
|
||||
return pht('Build Plan %d', $this->getID());
|
||||
return pht('Plan %d', $this->getID());
|
||||
}
|
||||
|
||||
|
||||
|
|
67
src/applications/harbormaster/view/HarbormasterBuildView.php
Normal file
67
src/applications/harbormaster/view/HarbormasterBuildView.php
Normal file
|
@ -0,0 +1,67 @@
|
|||
<?php
|
||||
|
||||
final class HarbormasterBuildView
|
||||
extends AphrontView {
|
||||
|
||||
private $builds = array();
|
||||
|
||||
public function setBuilds(array $builds) {
|
||||
assert_instances_of($builds, 'HarbormasterBuild');
|
||||
$this->builds = $builds;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getBuilds() {
|
||||
return $this->builds;
|
||||
}
|
||||
|
||||
public function render() {
|
||||
return $this->newObjectList();
|
||||
}
|
||||
|
||||
public function newObjectList() {
|
||||
$viewer = $this->getViewer();
|
||||
$builds = $this->getBuilds();
|
||||
|
||||
$buildables = mpull($builds, 'getBuildable');
|
||||
$object_phids = mpull($buildables, 'getBuildablePHID');
|
||||
$initiator_phids = mpull($builds, 'getInitiatorPHID');
|
||||
$phids = array_mergev(array($initiator_phids, $object_phids));
|
||||
$phids = array_unique(array_filter($phids));
|
||||
|
||||
$handles = $viewer->loadHandles($phids);
|
||||
|
||||
$list = new PHUIObjectItemListView();
|
||||
foreach ($builds as $build) {
|
||||
$id = $build->getID();
|
||||
$initiator = $handles[$build->getInitiatorPHID()];
|
||||
$buildable_object = $handles[$build->getBuildable()->getBuildablePHID()];
|
||||
|
||||
$item = id(new PHUIObjectItemView())
|
||||
->setViewer($viewer)
|
||||
->setObject($build)
|
||||
->setObjectName($build->getObjectName())
|
||||
->setHeader($build->getName())
|
||||
->setHref($build->getURI())
|
||||
->setEpoch($build->getDateCreated())
|
||||
->addAttribute($buildable_object->getName());
|
||||
|
||||
if ($initiator) {
|
||||
$item->addByline($initiator->renderLink());
|
||||
}
|
||||
|
||||
$status = $build->getBuildStatus();
|
||||
|
||||
$status_icon = HarbormasterBuildStatus::getBuildStatusIcon($status);
|
||||
$status_color = HarbormasterBuildStatus::getBuildStatusColor($status);
|
||||
$status_label = HarbormasterBuildStatus::getBuildStatusName($status);
|
||||
|
||||
$item->setStatusIcon("{$status_icon} {$status_color}", $status_label);
|
||||
|
||||
$list->addItem($item);
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue