1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2025-02-26 05:29:06 +01:00
phorge-phorge/src/applications/harbormaster/controller/HarbormasterBuildViewController.php
James Rhodes a3d50118e1 Allow users to specify names of build steps
Summary: Ref T1049.  This provides a user-configurable name field on build steps, which allows users to uniquely identify their steps.  The intention is that this field will be used in D9806 to better identify the dependencies (rather than showing an unhelpful PHID).

Test Plan: Set the name of some build steps, saw it appear in the correct places.

Reviewers: epriestley, #blessed_reviewers

Reviewed By: epriestley, #blessed_reviewers

Subscribers: epriestley, Korvin

Maniphest Tasks: T1049

Differential Revision: https://secure.phabricator.com/D9816
2014-07-05 01:56:02 +10:00

375 lines
10 KiB
PHP

<?php
final class HarbormasterBuildViewController
extends HarbormasterController {
private $id;
public function willProcessRequest(array $data) {
$this->id = $data['id'];
}
public function processRequest() {
$request = $this->getRequest();
$viewer = $request->getUser();
$id = $this->id;
$build = id(new HarbormasterBuildQuery())
->setViewer($viewer)
->withIDs(array($id))
->executeOne();
if (!$build) {
return new Aphront404Response();
}
$title = pht('Build %d', $id);
$header = id(new PHUIHeaderView())
->setHeader($title)
->setUser($viewer)
->setPolicyObject($build);
if ($build->isRestarting()) {
$header->setStatus('fa-exclamation-triangle', 'red', pht('Restarting'));
} else if ($build->isStopping()) {
$header->setStatus('fa-exclamation-triangle', 'red', pht('Stopping'));
} else if ($build->isResuming()) {
$header->setStatus('fa-exclamation-triangle', 'red', pht('Resuming'));
}
$box = id(new PHUIObjectBoxView())
->setHeader($header);
$actions = $this->buildActionList($build);
$this->buildPropertyLists($box, $build, $actions);
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(
$build->getBuildable()->getMonogram(),
'/'.$build->getBuildable()->getMonogram());
$crumbs->addTextCrumb($title);
$build_targets = id(new HarbormasterBuildTargetQuery())
->setViewer($viewer)
->withBuildPHIDs(array($build->getPHID()))
->execute();
if ($build_targets) {
$messages = id(new HarbormasterBuildMessageQuery())
->setViewer($viewer)
->withBuildTargetPHIDs(mpull($build_targets, 'getPHID'))
->execute();
$messages = mgroup($messages, 'getBuildTargetPHID');
} else {
$messages = array();
}
$targets = array();
foreach ($build_targets as $build_target) {
$header = id(new PHUIHeaderView())
->setHeader(pht(
'Build Target %d (%s)',
$build_target->getID(),
$build_target->getName()))
->setUser($viewer);
$properties = new PHUIPropertyListView();
$details = $build_target->getDetails();
if ($details) {
$properties->addSectionHeader(pht('Configuration Details'));
foreach ($details as $key => $value) {
$properties->addProperty($key, $value);
}
}
$variables = $build_target->getVariables();
if ($variables) {
$properties->addSectionHeader(pht('Variables'));
foreach ($variables as $key => $value) {
$properties->addProperty($key, $value);
}
}
$targets[] = id(new PHUIObjectBoxView())
->setHeader($header)
->addPropertyList($properties);
$build_messages = idx($messages, $build_target->getPHID(), array());
$targets[] = $this->buildMessages($build_messages);
$targets[] = $this->buildArtifacts($build_target);
$targets[] = $this->buildLog($build, $build_target);
}
$xactions = id(new HarbormasterBuildTransactionQuery())
->setViewer($viewer)
->withObjectPHIDs(array($build->getPHID()))
->execute();
$timeline = id(new PhabricatorApplicationTransactionView())
->setUser($viewer)
->setObjectPHID($build->getPHID())
->setTransactions($xactions);
return $this->buildApplicationPage(
array(
$crumbs,
$box,
$targets,
$timeline,
),
array(
'title' => $title,
));
}
private function buildArtifacts(HarbormasterBuildTarget $build_target) {
$request = $this->getRequest();
$viewer = $request->getUser();
$artifacts = id(new HarbormasterBuildArtifactQuery())
->setViewer($viewer)
->withBuildTargetPHIDs(array($build_target->getPHID()))
->execute();
if (count($artifacts) === 0) {
return null;
}
$list = new PHUIObjectItemListView();
foreach ($artifacts as $artifact) {
$list->addItem($artifact->getObjectItemView($viewer));
}
$header = id(new PHUIHeaderView())
->setHeader(pht('Build Artifacts'))
->setUser($viewer);
$box = id(new PHUIObjectBoxView())
->setHeader($header);
return array($box, $list);
}
private function buildLog(
HarbormasterBuild $build,
HarbormasterBuildTarget $build_target) {
$request = $this->getRequest();
$viewer = $request->getUser();
$limit = $request->getInt('l', 25);
$logs = id(new HarbormasterBuildLogQuery())
->setViewer($viewer)
->withBuildTargetPHIDs(array($build_target->getPHID()))
->execute();
$log_boxes = array();
foreach ($logs as $log) {
$start = 1;
$lines = preg_split("/\r\n|\r|\n/", $log->getLogText());
if ($limit !== 0) {
$start = count($lines) - $limit;
if ($start >= 1) {
$lines = array_slice($lines, -$limit, $limit);
} else {
$start = 1;
}
}
$log_view = new ShellLogView();
$log_view->setLines($lines);
$log_view->setStart($start);
$header = id(new PHUIHeaderView())
->setHeader(pht(
'Build Log %d (%s - %s)',
$log->getID(),
$log->getLogSource(),
$log->getLogType()))
->setSubheader($this->createLogHeader($build, $log))
->setUser($viewer);
$log_boxes[] = id(new PHUIObjectBoxView())
->setHeader($header)
->setForm($log_view);
}
return $log_boxes;
}
private function createLogHeader($build, $log) {
$request = $this->getRequest();
$limit = $request->getInt('l', 25);
$lines_25 = $this->getApplicationURI('/build/'.$build->getID().'/?l=25');
$lines_50 = $this->getApplicationURI('/build/'.$build->getID().'/?l=50');
$lines_100 =
$this->getApplicationURI('/build/'.$build->getID().'/?l=100');
$lines_0 = $this->getApplicationURI('/build/'.$build->getID().'/?l=0');
$link_25 = phutil_tag('a', array('href' => $lines_25), pht('25'));
$link_50 = phutil_tag('a', array('href' => $lines_50), pht('50'));
$link_100 = phutil_tag('a', array('href' => $lines_100), pht('100'));
$link_0 = phutil_tag('a', array('href' => $lines_0), pht('Unlimited'));
if ($limit === 25) {
$link_25 = phutil_tag('strong', array(), $link_25);
} else if ($limit === 50) {
$link_50 = phutil_tag('strong', array(), $link_50);
} else if ($limit === 100) {
$link_100 = phutil_tag('strong', array(), $link_100);
} else if ($limit === 0) {
$link_0 = phutil_tag('strong', array(), $link_0);
}
return phutil_tag(
'span',
array(),
array(
$link_25,
' - ',
$link_50,
' - ',
$link_100,
' - ',
$link_0,
' Lines'));
}
private function buildActionList(HarbormasterBuild $build) {
$request = $this->getRequest();
$viewer = $request->getUser();
$id = $build->getID();
$list = id(new PhabricatorActionListView())
->setUser($viewer)
->setObject($build)
->setObjectURI("/build/{$id}");
$can_restart = $build->canRestartBuild();
$can_stop = $build->canStopBuild();
$can_resume = $build->canResumeBuild();
$list->addAction(
id(new PhabricatorActionView())
->setName(pht('Restart Build'))
->setIcon('fa-backward')
->setHref($this->getApplicationURI('/build/restart/'.$id.'/'))
->setDisabled(!$can_restart)
->setWorkflow(true));
$list->addAction(
id(new PhabricatorActionView())
->setName(pht('Stop Build'))
->setIcon('fa-stop')
->setHref($this->getApplicationURI('/build/stop/'.$id.'/'))
->setDisabled(!$can_stop)
->setWorkflow(true));
$list->addAction(
id(new PhabricatorActionView())
->setName(pht('Resume Build'))
->setIcon('fa-play')
->setHref($this->getApplicationURI('/build/resume/'.$id.'/'))
->setDisabled(!$can_resume)
->setWorkflow(true));
return $list;
}
private function buildPropertyLists(
PHUIObjectBoxView $box,
HarbormasterBuild $build,
PhabricatorActionListView $actions) {
$request = $this->getRequest();
$viewer = $request->getUser();
$properties = id(new PHUIPropertyListView())
->setUser($viewer)
->setObject($build)
->setActionList($actions);
$box->addPropertyList($properties);
$properties->addProperty(
pht('Status'),
$this->getStatus($build));
$handles = id(new PhabricatorHandleQuery())
->setViewer($viewer)
->withPHIDs(array(
$build->getBuildablePHID(),
$build->getBuildPlanPHID()))
->execute();
$properties->addProperty(
pht('Buildable'),
$handles[$build->getBuildablePHID()]->renderLink());
$properties->addProperty(
pht('Build Plan'),
$handles[$build->getBuildPlanPHID()]->renderLink());
}
private function getStatus(HarbormasterBuild $build) {
if ($build->isStopping()) {
return pht('Stopping');
}
return HarbormasterBuild::getBuildStatusName($build->getBuildStatus());
}
private function buildMessages(array $messages) {
$viewer = $this->getRequest()->getUser();
if ($messages) {
$handles = id(new PhabricatorHandleQuery())
->setViewer($viewer)
->withPHIDs(mpull($messages, 'getAuthorPHID'))
->execute();
} else {
$handles = array();
}
$rows = array();
foreach ($messages as $message) {
$rows[] = array(
$message->getID(),
$handles[$message->getAuthorPHID()]->renderLink(),
$message->getType(),
$message->getIsConsumed() ? pht('Consumed') : null,
phabricator_datetime($message->getDateCreated(), $viewer),
);
}
$table = new AphrontTableView($rows);
$table->setNoDataString(pht('No messages for this build target.'));
$table->setHeaders(
array(
pht('ID'),
pht('From'),
pht('Type'),
pht('Consumed'),
pht('Received'),
));
$table->setColumnClasses(
array(
'',
'',
'wide',
'',
'date',
));
$box = id(new PHUIObjectBoxView())
->setHeaderText(pht('Build Target Messages'))
->appendChild($table);
return $box;
}
}