Page MenuHomestyx hydra

No OneTemporary

diff --git a/src/applications/harbormaster/artifact/HarbormasterURIArtifact.php b/src/applications/harbormaster/artifact/HarbormasterURIArtifact.php
index 53d3241711..311492de20 100644
--- a/src/applications/harbormaster/artifact/HarbormasterURIArtifact.php
+++ b/src/applications/harbormaster/artifact/HarbormasterURIArtifact.php
@@ -1,100 +1,109 @@
<?php
final class HarbormasterURIArtifact extends HarbormasterArtifact {
const ARTIFACTCONST = 'uri';
public function getArtifactTypeName() {
return pht('URI');
}
public function getArtifactTypeSummary() {
return pht('Stores a URI.');
}
public function getArtifactTypeDescription() {
return pht(
"Stores a URI.\n\n".
"With `ui.external`, you can use this artifact type to add links to ".
"build results in an external build system.");
}
public function getArtifactParameterSpecification() {
return array(
'uri' => 'string',
'name' => 'optional string',
'ui.external' => 'optional bool',
);
}
public function getArtifactParameterDescriptions() {
return array(
'uri' => pht('The URI to store.'),
'name' => pht('Optional label for this URI.'),
'ui.external' => pht(
'If true, display this URI in the UI as an link to '.
'additional build details in an external build system.'),
);
}
public function getArtifactDataExample() {
return array(
'uri' => 'https://buildserver.mycompany.com/build/123/',
'name' => pht('View External Build Results'),
'ui.external' => true,
);
}
public function renderArtifactSummary(PhabricatorUser $viewer) {
+ return $this->renderLink();
+ }
+
+ public function isExternalLink() {
+ $artifact = $this->getBuildArtifact();
+ return (bool)$artifact->getProperty('ui.external', false);
+ }
+
+ public function renderLink() {
$artifact = $this->getBuildArtifact();
$uri = $artifact->getProperty('uri');
try {
$this->validateURI($uri);
} catch (Exception $ex) {
return pht('<Invalid URI>');
}
$name = $artifact->getProperty('name', $uri);
return phutil_tag(
'a',
array(
'href' => $uri,
'target' => '_blank',
),
$name);
}
public function willCreateArtifact(PhabricatorUser $actor) {
$artifact = $this->getBuildArtifact();
$uri = $artifact->getProperty('uri');
$this->validateURI($uri);
}
private function validateURI($raw_uri) {
$uri = new PhutilURI($raw_uri);
$protocol = $uri->getProtocol();
if (!strlen($protocol)) {
throw new Exception(
pht(
'Unable to identify the protocol for URI "%s". URIs must be '.
'fully qualified and have an identifiable protocol.',
$raw_uri));
}
$protocol_key = 'uri.allowed-protocols';
$protocols = PhabricatorEnv::getEnvConfig($protocol_key);
if (empty($protocols[$protocol])) {
throw new Exception(
pht(
'URI "%s" does not have an allowable protocol. Configure '.
'protocols in `%s`. Allowed protocols are: %s.',
$raw_uri,
$protocol_key,
implode(', ', array_keys($protocols))));
}
}
}
diff --git a/src/applications/harbormaster/controller/HarbormasterBuildViewController.php b/src/applications/harbormaster/controller/HarbormasterBuildViewController.php
index 189fa76ec2..1a9832c588 100644
--- a/src/applications/harbormaster/controller/HarbormasterBuildViewController.php
+++ b/src/applications/harbormaster/controller/HarbormasterBuildViewController.php
@@ -1,586 +1,614 @@
<?php
final class HarbormasterBuildViewController
extends HarbormasterController {
public function handleRequest(AphrontRequest $request) {
$request = $this->getRequest();
$viewer = $request->getUser();
$id = $request->getURIData('id');
$generation = $request->getInt('g');
$build = id(new HarbormasterBuildQuery())
->setViewer($viewer)
->withIDs(array($id))
->executeOne();
if (!$build) {
return new Aphront404Response();
}
require_celerity_resource('harbormaster-css');
$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('Pausing'));
} 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();
$this->addBuildableCrumb($crumbs, $build->getBuildable());
$crumbs->addTextCrumb($title);
if ($generation === null || $generation > $build->getBuildGeneration() ||
$generation < 0) {
$generation = $build->getBuildGeneration();
}
$build_targets = id(new HarbormasterBuildTargetQuery())
->setViewer($viewer)
->needBuildSteps(true)
->withBuildPHIDs(array($build->getPHID()))
->withBuildGenerations(array($generation))
->execute();
if ($build_targets) {
$messages = id(new HarbormasterBuildMessageQuery())
->setViewer($viewer)
->withBuildTargetPHIDs(mpull($build_targets, 'getPHID'))
->execute();
$messages = mgroup($messages, 'getBuildTargetPHID');
} else {
$messages = array();
}
+ if ($build_targets) {
+ $artifacts = id(new HarbormasterBuildArtifactQuery())
+ ->setViewer($viewer)
+ ->withBuildTargetPHIDs(mpull($build_targets, 'getPHID'))
+ ->execute();
+ $artifacts = msort($artifacts, 'getArtifactKey');
+ $artifacts = mgroup($artifacts, 'getBuildTargetPHID');
+ } else {
+ $artifacts = array();
+ }
+
+
$targets = array();
foreach ($build_targets as $build_target) {
$header = id(new PHUIHeaderView())
->setHeader($build_target->getName())
->setUser($viewer);
$target_box = id(new PHUIObjectBoxView())
->setHeader($header);
$properties = new PHUIPropertyListView();
+
+ $target_artifacts = idx($artifacts, $build_target->getPHID(), array());
+
+ $links = array();
+ $type_uri = HarbormasterURIArtifact::ARTIFACTCONST;
+ foreach ($target_artifacts as $artifact) {
+ if ($artifact->getArtifactType() == $type_uri) {
+ $impl = $artifact->getArtifactImplementation();
+ if ($impl->isExternalLink()) {
+ $links[] = $impl->renderLink();
+ }
+ }
+ }
+
+ if ($links) {
+ $links = phutil_implode_html(phutil_tag('br'), $links);
+ $properties->addProperty(
+ pht('External Link'),
+ $links);
+ }
+
$status_view = new PHUIStatusListView();
$item = new PHUIStatusItemView();
$status = $build_target->getTargetStatus();
$status_name =
HarbormasterBuildTarget::getBuildTargetStatusName($status);
$icon = HarbormasterBuildTarget::getBuildTargetStatusIcon($status);
$color = HarbormasterBuildTarget::getBuildTargetStatusColor($status);
$item->setTarget($status_name);
$item->setIcon($icon, $color);
$status_view->addItem($item);
$when = array();
$started = $build_target->getDateStarted();
$now = PhabricatorTime::getNow();
if ($started) {
$ended = $build_target->getDateCompleted();
if ($ended) {
$when[] = pht(
'Completed at %s',
phabricator_datetime($started, $viewer));
$duration = ($ended - $started);
if ($duration) {
$when[] = pht(
'Built for %s',
phutil_format_relative_time_detailed($duration));
} else {
$when[] = pht('Built instantly');
}
} else {
$when[] = pht(
'Started at %s',
phabricator_datetime($started, $viewer));
$duration = ($now - $started);
if ($duration) {
$when[] = pht(
'Running for %s',
phutil_format_relative_time_detailed($duration));
}
}
} else {
$created = $build_target->getDateCreated();
$when[] = pht(
'Queued at %s',
phabricator_datetime($started, $viewer));
$duration = ($now - $created);
if ($duration) {
$when[] = pht(
'Waiting for %s',
phutil_format_relative_time_detailed($duration));
}
}
$properties->addProperty(
pht('When'),
phutil_implode_html(" \xC2\xB7 ", $when));
$properties->addProperty(pht('Status'), $status_view);
$target_box->addPropertyList($properties, pht('Overview'));
$step = $build_target->getBuildStep();
if ($step) {
$description = $step->getDescription();
if ($description) {
$rendered = PhabricatorMarkupEngine::renderOneObject(
id(new PhabricatorMarkupOneOff())
->setContent($description)
->setPreserveLinebreaks(true),
'default',
$viewer);
$properties->addSectionHeader(pht('Description'));
$properties->addTextContent($rendered);
}
} else {
$target_box->setFormErrors(
array(
pht(
'This build step has since been deleted on the build plan. '.
'Some information may be omitted.'),
));
}
$details = $build_target->getDetails();
$properties = new PHUIPropertyListView();
foreach ($details as $key => $value) {
$properties->addProperty($key, $value);
}
$target_box->addPropertyList($properties, pht('Configuration'));
$variables = $build_target->getVariables();
$properties = new PHUIPropertyListView();
$properties->addRawContent($this->buildProperties($variables));
$target_box->addPropertyList($properties, pht('Variables'));
- $artifacts = $this->buildArtifacts($build_target);
+ $artifacts_tab = $this->buildArtifacts($build_target, $target_artifacts);
$properties = new PHUIPropertyListView();
- $properties->addRawContent($artifacts);
+ $properties->addRawContent($artifacts_tab);
$target_box->addPropertyList($properties, pht('Artifacts'));
$build_messages = idx($messages, $build_target->getPHID(), array());
$properties = new PHUIPropertyListView();
$properties->addRawContent($this->buildMessages($build_messages));
$target_box->addPropertyList($properties, pht('Messages'));
$properties = new PHUIPropertyListView();
$properties->addProperty(
pht('Build Target ID'),
$build_target->getID());
$properties->addProperty(
pht('Build Target PHID'),
$build_target->getPHID());
$target_box->addPropertyList($properties, pht('Metadata'));
$targets[] = $target_box;
$targets[] = $this->buildLog($build, $build_target);
}
$timeline = $this->buildTransactionTimeline(
$build,
new HarbormasterBuildTransactionQuery());
$timeline->setShouldTerminate(true);
return $this->buildApplicationPage(
array(
$crumbs,
$box,
$targets,
$timeline,
),
array(
'title' => $title,
));
}
- private function buildArtifacts(HarbormasterBuildTarget $build_target) {
+ private function buildArtifacts(
+ HarbormasterBuildTarget $build_target,
+ array $artifacts) {
$viewer = $this->getViewer();
- $artifacts = id(new HarbormasterBuildArtifactQuery())
- ->setViewer($viewer)
- ->withBuildTargetPHIDs(array($build_target->getPHID()))
- ->execute();
-
- $artifacts = msort($artifacts, 'getArtifactKey');
-
$rows = array();
foreach ($artifacts as $artifact) {
$impl = $artifact->getArtifactImplementation();
if ($impl) {
$summary = $impl->renderArtifactSummary($viewer);
$type_name = $impl->getArtifactTypeName();
} else {
$summary = pht('<Unknown Artifact Type>');
$type_name = $artifact->getType();
}
$rows[] = array(
$artifact->getArtifactKey(),
$type_name,
$summary,
);
}
$table = id(new AphrontTableView($rows))
->setNoDataString(pht('This target has no associated artifacts.'))
->setHeaders(
array(
pht('Key'),
pht('Type'),
pht('Summary'),
))
->setColumnClasses(
array(
'pri',
'',
'wide',
));
return $table;
}
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();
$empty_logs = array();
$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;
}
}
$id = null;
$is_empty = false;
if (count($lines) === 1 && trim($lines[0]) === '') {
// Prevent Harbormaster from showing empty build logs.
$id = celerity_generate_unique_node_id();
$empty_logs[] = $id;
$is_empty = true;
}
$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_box = id(new PHUIObjectBoxView())
->setHeader($header)
->setForm($log_view);
if ($is_empty) {
$log_box = phutil_tag(
'div',
array(
'style' => 'display: none',
'id' => $id,
),
$log_box);
}
$log_boxes[] = $log_box;
}
if ($empty_logs) {
$hide_id = celerity_generate_unique_node_id();
Javelin::initBehavior('phabricator-reveal-content');
$expand = phutil_tag(
'div',
array(
'id' => $hide_id,
'class' => 'harbormaster-empty-logs-are-hidden mlr mlt mll',
),
array(
pht(
'%s empty logs are hidden.',
new PhutilNumber(count($empty_logs))),
' ',
javelin_tag(
'a',
array(
'href' => '#',
'sigil' => 'reveal-content',
'meta' => array(
'showIDs' => $empty_logs,
'hideIDs' => array($hide_id),
),
),
pht('Show all logs.')),
));
array_unshift($log_boxes, $expand);
}
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-repeat')
->setHref($this->getApplicationURI('/build/restart/'.$id.'/'))
->setDisabled(!$can_restart)
->setWorkflow(true));
if ($build->canResumeBuild()) {
$list->addAction(
id(new PhabricatorActionView())
->setName(pht('Resume Build'))
->setIcon('fa-play')
->setHref($this->getApplicationURI('/build/resume/'.$id.'/'))
->setDisabled(!$can_resume)
->setWorkflow(true));
} else {
$list->addAction(
id(new PhabricatorActionView())
->setName(pht('Pause Build'))
->setIcon('fa-pause')
->setHref($this->getApplicationURI('/build/stop/'.$id.'/'))
->setDisabled(!$can_stop)
->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);
$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());
$properties->addProperty(
pht('Restarts'),
$build->getBuildGeneration());
$properties->addProperty(
pht('Status'),
$this->getStatus($build));
}
private function getStatus(HarbormasterBuild $build) {
$status_view = new PHUIStatusListView();
$item = new PHUIStatusItemView();
if ($build->isStopping()) {
$status_name = pht('Pausing');
$icon = PHUIStatusItemView::ICON_RIGHT;
$color = 'dark';
} else {
$status = $build->getBuildStatus();
$status_name =
HarbormasterBuild::getBuildStatusName($status);
$icon = HarbormasterBuild::getBuildStatusIcon($status);
$color = HarbormasterBuild::getBuildStatusColor($status);
}
$item->setTarget($status_name);
$item->setIcon($icon, $color);
$status_view->addItem($item);
return $status_view;
}
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',
));
return $table;
}
private function buildProperties(array $properties) {
ksort($properties);
$rows = array();
foreach ($properties as $key => $value) {
$rows[] = array(
$key,
$value,
);
}
$table = id(new AphrontTableView($rows))
->setHeaders(
array(
pht('Key'),
pht('Value'),
))
->setColumnClasses(
array(
'pri right',
'wide',
));
return $table;
}
}
diff --git a/src/applications/harbormaster/event/HarbormasterUIEventListener.php b/src/applications/harbormaster/event/HarbormasterUIEventListener.php
index d0a79f4b12..82ffcad560 100644
--- a/src/applications/harbormaster/event/HarbormasterUIEventListener.php
+++ b/src/applications/harbormaster/event/HarbormasterUIEventListener.php
@@ -1,115 +1,148 @@
<?php
final class HarbormasterUIEventListener
extends PhabricatorEventListener {
public function register() {
$this->listen(PhabricatorEventType::TYPE_UI_WILLRENDERPROPERTIES);
}
public function handleEvent(PhutilEvent $event) {
switch ($event->getType()) {
case PhabricatorEventType::TYPE_UI_WILLRENDERPROPERTIES:
$this->handlePropertyEvent($event);
break;
}
}
private function handlePropertyEvent($ui_event) {
- $user = $ui_event->getUser();
+ $viewer = $ui_event->getUser();
$object = $ui_event->getValue('object');
if (!$object || !$object->getPHID()) {
// No object, or the object has no PHID yet..
return;
}
if ($object instanceof HarbormasterBuildable) {
// Although HarbormasterBuildable implements the correct interface, it
// does not make sense to show a build's build status. In the best case
// it is meaningless, and in the worst case it's confusing.
return;
}
if ($object instanceof DifferentialRevision) {
// TODO: This is a bit hacky and we could probably find a cleaner fix
// eventually, but we show build status on each diff, immediately below
// this property list, so it's redundant to show it on the revision view.
return;
}
if (!($object instanceof HarbormasterBuildableInterface)) {
return;
}
$buildable_phid = $object->getHarbormasterBuildablePHID();
if (!$buildable_phid) {
return;
}
if (!$this->canUseApplication($ui_event->getUser())) {
return;
}
$buildable = id(new HarbormasterBuildableQuery())
- ->setViewer($user)
+ ->setViewer($viewer)
->withManualBuildables(false)
->withBuildablePHIDs(array($buildable_phid))
->needBuilds(true)
+ ->needTargets(true)
->executeOne();
if (!$buildable) {
return;
}
$builds = $buildable->getBuilds();
- $build_handles = id(new PhabricatorHandleQuery())
- ->setViewer($user)
- ->withPHIDs(mpull($builds, 'getPHID'))
- ->execute();
+ $targets = array();
+ foreach ($builds as $build) {
+ foreach ($build->getBuildTargets() as $target) {
+ $targets[] = $target;
+ }
+ }
+
+ if ($targets) {
+ $artifacts = id(new HarbormasterBuildArtifactQuery())
+ ->setViewer($viewer)
+ ->withBuildTargetPHIDs(mpull($targets, 'getPHID'))
+ ->withArtifactTypes(
+ array(
+ HarbormasterURIArtifact::ARTIFACTCONST,
+ ))
+ ->execute();
+ $artifacts = mgroup($artifacts, 'getBuildTargetPHID');
+ } else {
+ $artifacts = array();
+ }
$status_view = new PHUIStatusListView();
$buildable_status = $buildable->getBuildableStatus();
$buildable_icon = HarbormasterBuildable::getBuildableStatusIcon(
$buildable_status);
$buildable_color = HarbormasterBuildable::getBuildableStatusColor(
$buildable_status);
$buildable_name = HarbormasterBuildable::getBuildableStatusName(
$buildable_status);
$target = phutil_tag(
'a',
array(
'href' => '/'.$buildable->getMonogram(),
),
pht('Buildable %d', $buildable->getID()));
$target = phutil_tag('strong', array(), $target);
+
$status_view
->addItem(
id(new PHUIStatusItemView())
->setIcon($buildable_icon, $buildable_color, $buildable_name)
->setTarget($target));
foreach ($builds as $build) {
$item = new PHUIStatusItemView();
- $item->setTarget($build_handles[$build->getPHID()]->renderLink());
+ $item->setTarget($viewer->renderHandle($build->getPHID()));
+
+ $links = array();
+ foreach ($build->getBuildTargets() as $build_target) {
+ $uris = idx($artifacts, $build_target->getPHID(), array());
+ foreach ($uris as $uri) {
+ $impl = $uri->getArtifactImplementation();
+ if ($impl->isExternalLink()) {
+ $links[] = $impl->renderLink();
+ }
+ }
+ }
+
+ if ($links) {
+ $links = phutil_implode_html(" \xC2\xB7 ", $links);
+ $item->setNote($links);
+ }
$status = $build->getBuildStatus();
$status_name = HarbormasterBuild::getBuildStatusName($status);
$icon = HarbormasterBuild::getBuildStatusIcon($status);
$color = HarbormasterBuild::getBuildStatusColor($status);
$item->setIcon($icon, $color, $status_name);
-
$status_view->addItem($item);
}
$view = $ui_event->getValue('view');
$view->addProperty(pht('Build Status'), $status_view);
}
}
diff --git a/src/applications/harbormaster/query/HarbormasterBuildQuery.php b/src/applications/harbormaster/query/HarbormasterBuildQuery.php
index d0b1e7420c..1ee1ecb3a8 100644
--- a/src/applications/harbormaster/query/HarbormasterBuildQuery.php
+++ b/src/applications/harbormaster/query/HarbormasterBuildQuery.php
@@ -1,186 +1,177 @@
<?php
final class HarbormasterBuildQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $buildStatuses;
private $buildablePHIDs;
private $buildPlanPHIDs;
private $needBuildTargets;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withBuildStatuses(array $build_statuses) {
$this->buildStatuses = $build_statuses;
return $this;
}
public function withBuildablePHIDs(array $buildable_phids) {
$this->buildablePHIDs = $buildable_phids;
return $this;
}
public function withBuildPlanPHIDs(array $build_plan_phids) {
$this->buildPlanPHIDs = $build_plan_phids;
return $this;
}
public function needBuildTargets($need_targets) {
$this->needBuildTargets = $need_targets;
return $this;
}
+ public function newResultObject() {
+ return new HarbormasterBuild();
+ }
+
protected function loadPage() {
- $table = new HarbormasterBuild();
- $conn_r = $table->establishConnection('r');
-
- $data = queryfx_all(
- $conn_r,
- 'SELECT * FROM %T %Q %Q %Q',
- $table->getTableName(),
- $this->buildWhereClause($conn_r),
- $this->buildOrderClause($conn_r),
- $this->buildLimitClause($conn_r));
-
- return $table->loadAllFromArray($data);
+ return $this->loadStandardPage($this->newResultObject());
}
protected function willFilterPage(array $page) {
$buildables = array();
$buildable_phids = array_filter(mpull($page, 'getBuildablePHID'));
if ($buildable_phids) {
$buildables = id(new PhabricatorObjectQuery())
->setViewer($this->getViewer())
->withPHIDs($buildable_phids)
->setParentQuery($this)
->execute();
$buildables = mpull($buildables, null, 'getPHID');
}
foreach ($page as $key => $build) {
$buildable_phid = $build->getBuildablePHID();
if (empty($buildables[$buildable_phid])) {
unset($page[$key]);
continue;
}
$build->attachBuildable($buildables[$buildable_phid]);
}
return $page;
}
protected function didFilterPage(array $page) {
$plans = array();
$plan_phids = array_filter(mpull($page, 'getBuildPlanPHID'));
if ($plan_phids) {
$plans = id(new PhabricatorObjectQuery())
->setViewer($this->getViewer())
->withPHIDs($plan_phids)
->setParentQuery($this)
->execute();
$plans = mpull($plans, null, 'getPHID');
}
foreach ($page as $key => $build) {
$plan_phid = $build->getBuildPlanPHID();
$build->attachBuildPlan(idx($plans, $plan_phid));
}
$build_phids = mpull($page, 'getPHID');
$commands = id(new HarbormasterBuildCommand())->loadAllWhere(
'targetPHID IN (%Ls) ORDER BY id ASC',
$build_phids);
$commands = mgroup($commands, 'getTargetPHID');
foreach ($page as $build) {
$unprocessed_commands = idx($commands, $build->getPHID(), array());
$build->attachUnprocessedCommands($unprocessed_commands);
}
if ($this->needBuildTargets) {
$targets = id(new HarbormasterBuildTargetQuery())
->setViewer($this->getViewer())
->setParentQuery($this)
->withBuildPHIDs($build_phids)
->execute();
// TODO: Some day, when targets have dependencies, we should toposort
// these. For now, just put them into chronological order.
$targets = array_reverse($targets);
$targets = mgroup($targets, 'getBuildPHID');
foreach ($page as $build) {
$build_targets = idx($targets, $build->getPHID(), array());
foreach ($build_targets as $phid => $target) {
if ($target->getBuildGeneration() !== $build->getBuildGeneration()) {
unset($build_targets[$phid]);
}
}
$build->attachBuildTargets($build_targets);
}
}
return $page;
}
- protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
- $where = array();
+ protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
+ $where = parent::buildWhereClauseParts($conn);
if ($this->ids !== null) {
$where[] = qsprintf(
- $conn_r,
+ $conn,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids !== null) {
$where[] = qsprintf(
- $conn_r,
+ $conn,
'phid in (%Ls)',
$this->phids);
}
if ($this->buildStatuses !== null) {
$where[] = qsprintf(
- $conn_r,
+ $conn,
'buildStatus in (%Ls)',
$this->buildStatuses);
}
if ($this->buildablePHIDs !== null) {
$where[] = qsprintf(
- $conn_r,
+ $conn,
'buildablePHID IN (%Ls)',
$this->buildablePHIDs);
}
if ($this->buildPlanPHIDs !== null) {
$where[] = qsprintf(
- $conn_r,
+ $conn,
'buildPlanPHID IN (%Ls)',
$this->buildPlanPHIDs);
}
- $where[] = $this->buildPagingClause($conn_r);
-
- return $this->formatWhereClause($where);
+ return $where;
}
public function getQueryApplicationClass() {
return 'PhabricatorHarbormasterApplication';
}
}
diff --git a/src/applications/harbormaster/query/HarbormasterBuildTargetQuery.php b/src/applications/harbormaster/query/HarbormasterBuildTargetQuery.php
index c61c0bd8b0..6872be835b 100644
--- a/src/applications/harbormaster/query/HarbormasterBuildTargetQuery.php
+++ b/src/applications/harbormaster/query/HarbormasterBuildTargetQuery.php
@@ -1,142 +1,133 @@
<?php
final class HarbormasterBuildTargetQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $buildPHIDs;
private $buildGenerations;
private $needBuildSteps;
public function withIDs(array $ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withBuildPHIDs(array $build_phids) {
$this->buildPHIDs = $build_phids;
return $this;
}
public function withBuildGenerations(array $build_generations) {
$this->buildGenerations = $build_generations;
return $this;
}
public function needBuildSteps($need_build_steps) {
$this->needBuildSteps = $need_build_steps;
return $this;
}
+ public function newResultObject() {
+ return new HarbormasterBuildTarget();
+ }
+
protected function loadPage() {
- $table = new HarbormasterBuildTarget();
- $conn_r = $table->establishConnection('r');
-
- $data = queryfx_all(
- $conn_r,
- 'SELECT * FROM %T %Q %Q %Q',
- $table->getTableName(),
- $this->buildWhereClause($conn_r),
- $this->buildOrderClause($conn_r),
- $this->buildLimitClause($conn_r));
-
- return $table->loadAllFromArray($data);
+ return $this->loadStandardPage($this->newResultObject());
}
- protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
- $where = array();
+ protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
+ $where = parent::buildWhereClauseParts($conn);
- if ($this->ids) {
+ if ($this->ids !== null) {
$where[] = qsprintf(
- $conn_r,
+ $conn,
'id IN (%Ld)',
$this->ids);
}
- if ($this->phids) {
+ if ($this->phids !== null) {
$where[] = qsprintf(
- $conn_r,
+ $conn,
'phid in (%Ls)',
$this->phids);
}
- if ($this->buildPHIDs) {
+ if ($this->buildPHIDs !== null) {
$where[] = qsprintf(
- $conn_r,
+ $conn,
'buildPHID in (%Ls)',
$this->buildPHIDs);
}
- if ($this->buildGenerations) {
+ if ($this->buildGenerations !== null) {
$where[] = qsprintf(
- $conn_r,
+ $conn,
'buildGeneration in (%Ld)',
$this->buildGenerations);
}
- $where[] = $this->buildPagingClause($conn_r);
-
- return $this->formatWhereClause($where);
+ return $where;
}
protected function didFilterPage(array $page) {
if ($this->needBuildSteps) {
$step_phids = array();
foreach ($page as $target) {
$step_phids[] = $target->getBuildStepPHID();
}
$steps = id(new HarbormasterBuildStepQuery())
->setViewer($this->getViewer())
->setParentQuery($this)
->withPHIDs($step_phids)
->execute();
$steps = mpull($steps, null, 'getPHID');
foreach ($page as $target) {
$target->attachBuildStep(
idx($steps, $target->getBuildStepPHID()));
}
}
return $page;
}
protected function willFilterPage(array $page) {
$builds = array();
$build_phids = array_filter(mpull($page, 'getBuildPHID'));
if ($build_phids) {
$builds = id(new PhabricatorObjectQuery())
->setViewer($this->getViewer())
->withPHIDs($build_phids)
->setParentQuery($this)
->execute();
$builds = mpull($builds, null, 'getPHID');
}
foreach ($page as $key => $build_target) {
$build_phid = $build_target->getBuildPHID();
if (empty($builds[$build_phid])) {
unset($page[$key]);
continue;
}
$build_target->attachBuild($builds[$build_phid]);
}
return $page;
}
public function getQueryApplicationClass() {
return 'PhabricatorHarbormasterApplication';
}
}

File Metadata

Mime Type
text/x-diff
Expires
Thu, Jul 3, 6:56 PM (3 h, 40 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
166215
Default Alt Text
(36 KB)

Event Timeline