Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F18086988
D16417.id39485.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
23 KB
Referenced Files
None
Subscribers
None
D16417.id39485.diff
View Options
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -1187,6 +1187,7 @@
'HarbormasterLeaseWorkingCopyBuildStepImplementation' => 'applications/harbormaster/step/HarbormasterLeaseWorkingCopyBuildStepImplementation.php',
'HarbormasterLintMessagesController' => 'applications/harbormaster/controller/HarbormasterLintMessagesController.php',
'HarbormasterLintPropertyView' => 'applications/harbormaster/view/HarbormasterLintPropertyView.php',
+ 'HarbormasterLintStatus' => 'applications/harbormaster/constants/HarbormasterLintStatus.php',
'HarbormasterManagementArchiveLogsWorkflow' => 'applications/harbormaster/management/HarbormasterManagementArchiveLogsWorkflow.php',
'HarbormasterManagementBuildWorkflow' => 'applications/harbormaster/management/HarbormasterManagementBuildWorkflow.php',
'HarbormasterManagementUpdateWorkflow' => 'applications/harbormaster/management/HarbormasterManagementUpdateWorkflow.php',
@@ -5766,6 +5767,7 @@
'HarbormasterLeaseWorkingCopyBuildStepImplementation' => 'HarbormasterBuildStepImplementation',
'HarbormasterLintMessagesController' => 'HarbormasterController',
'HarbormasterLintPropertyView' => 'AphrontView',
+ 'HarbormasterLintStatus' => 'Phobject',
'HarbormasterManagementArchiveLogsWorkflow' => 'HarbormasterManagementWorkflow',
'HarbormasterManagementBuildWorkflow' => 'HarbormasterManagementWorkflow',
'HarbormasterManagementUpdateWorkflow' => 'HarbormasterManagementWorkflow',
diff --git a/src/applications/differential/controller/DifferentialController.php b/src/applications/differential/controller/DifferentialController.php
--- a/src/applications/differential/controller/DifferentialController.php
+++ b/src/applications/differential/controller/DifferentialController.php
@@ -108,8 +108,7 @@
}
}
-
- protected function loadHarbormasterData(array $diffs) {
+ protected function loadHarbormasterBuilds(array $diffs) {
$viewer = $this->getViewer();
$diffs = mpull($diffs, null, 'getPHID');
@@ -127,6 +126,11 @@
$diff->attachBuildable(idx($buildables, $phid));
}
+ }
+
+ protected function loadHarbormasterData(array $diffs) {
+ $diffs = mpull($diffs, null, 'getPHID');
+
$target_map = array();
foreach ($diffs as $phid => $diff) {
$target_map[$phid] = $diff->getBuildTargetPHIDs();
diff --git a/src/applications/differential/controller/DifferentialRevisionViewController.php b/src/applications/differential/controller/DifferentialRevisionViewController.php
--- a/src/applications/differential/controller/DifferentialRevisionViewController.php
+++ b/src/applications/differential/controller/DifferentialRevisionViewController.php
@@ -239,6 +239,8 @@
->setErrors($revision_warnings);
}
+ $this->loadHarbormasterBuilds($diffs);
+
$detail_diffs = array_select_keys(
$diffs,
array($diff_vs, $target->getID()));
diff --git a/src/applications/differential/customfield/DifferentialLintField.php b/src/applications/differential/customfield/DifferentialLintField.php
--- a/src/applications/differential/customfield/DifferentialLintField.php
+++ b/src/applications/differential/customfield/DifferentialLintField.php
@@ -3,6 +3,8 @@
final class DifferentialLintField
extends DifferentialHarbormasterField {
+ // For lint, we're loading all the messages anyway, to display them inline.
+
public function getFieldKey() {
return 'differential:lint';
}
@@ -84,6 +86,7 @@
DifferentialDiff $diff,
array $messages) {
+ $status = DifferentialRevisionUpdateHistoryView::getDiffLintStatus($diff);
$colors = array(
DifferentialLintStatus::LINT_NONE => 'grey',
DifferentialLintStatus::LINT_OKAY => 'green',
@@ -92,9 +95,9 @@
DifferentialLintStatus::LINT_SKIP => 'blue',
DifferentialLintStatus::LINT_AUTO_SKIP => 'blue',
);
- $icon_color = idx($colors, $diff->getLintStatus(), 'grey');
+ $icon_color = idx($colors, $status, 'grey'); // TODO fetch from build/buildtarget
- $message = DifferentialRevisionUpdateHistoryView::getDiffLintMessage($diff);
+ $message = DifferentialRevisionUpdateHistoryView::getDiffLintMessage($status);
$excuse = $diff->getProperty('arc:lint-excuse');
if (strlen($excuse)) {
diff --git a/src/applications/differential/customfield/DifferentialUnitField.php b/src/applications/differential/customfield/DifferentialUnitField.php
--- a/src/applications/differential/customfield/DifferentialUnitField.php
+++ b/src/applications/differential/customfield/DifferentialUnitField.php
@@ -34,6 +34,7 @@
public function getWarningsForDetailView() {
$status = $this->getObject()->getActiveDiff()->getUnitStatus();
+
$warnings = array();
if ($status < DifferentialUnitStatus::UNIT_WARN) {
// Don't show any warnings.
@@ -51,6 +52,24 @@
public function renderDiffPropertyViewValue(DifferentialDiff $diff) {
+ $target_phids = $diff->getBuildTargetPHIDs();
+
+ if ($target_phids) {
+ $targets = id(new HarbormasterBuildTargetQuery())
+ ->setViewer($this->getViewer())
+ ->withPHIDs($target_phids)
+ ->execute();
+ }
+ $builds_unit_status = array();
+ foreach ($targets as $target) {
+ $builds_unit_status[] = $target->getDetail(HarbormasterBuildTarget::DETAIL_UNIT_STATUS);
+ }
+ phlog($builds_unit_status);
+ $builds_unit_status = array_filter($builds_unit_status);
+ $builds_unit_status = HarbormasterUnitStatus::getWorstStatus($builds_unit_status);
+ $builds_unit_status = HarbormasterUnitStatus::getDifferentialUnitStatus($builds_unit_status);
+ var_dump($builds_unit_status);
+
$colors = array(
DifferentialUnitStatus::UNIT_NONE => 'grey',
DifferentialUnitStatus::UNIT_OKAY => 'green',
@@ -59,17 +78,29 @@
DifferentialUnitStatus::UNIT_SKIP => 'blue',
DifferentialUnitStatus::UNIT_AUTO_SKIP => 'blue',
);
- $icon_color = idx($colors, $diff->getUnitStatus(), 'grey');
- $message = DifferentialRevisionUpdateHistoryView::getDiffUnitMessage($diff);
+ $view = id(new PHUIStatusListView());
- $status = id(new PHUIStatusListView())
- ->addItem(
+ if ($builds_unit_status) {
+ $icon_color = idx($colors, $builds_unit_status, 'grey');
+ $message = DifferentialRevisionUpdateHistoryView::getDiffUnitMessage($builds_unit_status);
+ $view->addItem(
id(new PHUIStatusItemView())
->setIcon(PHUIStatusItemView::ICON_STAR, $icon_color)
->setTarget($message));
+ }
- return $status;
+ $manual_tests_status = $diff->getUnitStatus(); // try to pull off the autoplan first.
+ // TODO this is actually only interesting if the local is "skip"; OTherwise, it should be included with the builds.
+ if ($manual_tests_status !== null) {
+ $icon_color = idx($colors, $manual_tests_status, 'grey');
+ $message = DifferentialRevisionUpdateHistoryView::getDiffUnitMessage($manual_tests_status);
+ $view->addItem(
+ id(new PHUIStatusItemView())
+ ->setIcon(PHUIStatusItemView::ICON_STAR, $icon_color)
+ ->setTarget($message));
+ }
+ return $view;
}
diff --git a/src/applications/differential/storage/DifferentialDiff.php b/src/applications/differential/storage/DifferentialDiff.php
--- a/src/applications/differential/storage/DifferentialDiff.php
+++ b/src/applications/differential/storage/DifferentialDiff.php
@@ -360,20 +360,27 @@
}
public function getBuildTargetPHIDs() {
+ // TODO since this function would have broken anyway if the targets were not
+ // loaded, we probably always want to use getBuildTargets() anyway?
+ $targets = $this->getBuildTargets();
+ return mpull($targets, 'getPHID');
+ }
+
+ public function getBuildTargets() {
$buildable = $this->getBuildable();
if (!$buildable) {
return array();
}
- $target_phids = array();
+ $targets = array();
foreach ($buildable->getBuilds() as $build) {
foreach ($build->getBuildTargets() as $target) {
- $target_phids[] = $target->getPHID();
+ $targets[] = $target;
}
}
- return $target_phids;
+ return $targets;
}
public function loadCoverageMap(PhabricatorUser $viewer) {
diff --git a/src/applications/differential/view/DifferentialRevisionUpdateHistoryView.php b/src/applications/differential/view/DifferentialRevisionUpdateHistoryView.php
--- a/src/applications/differential/view/DifferentialRevisionUpdateHistoryView.php
+++ b/src/applications/differential/view/DifferentialRevisionUpdateHistoryView.php
@@ -139,21 +139,24 @@
}
if ($diff) {
- $lint = self::renderDiffLintStar($row['obj']);
+ $lint_status = self::getDiffLintStatus($diff);
+ $unit_status = self::getDiffUnitStatus($diff);
+
+ $lint = self::renderDiffLintStar($lint_status);
$lint = phutil_tag(
'div',
array(
'class' => 'lintunit-star',
- 'title' => self::getDiffLintMessage($diff),
+ 'title' => self::getDiffLintMessage($lint_status),
),
$lint);
- $unit = self::renderDiffUnitStar($row['obj']);
+ $unit = self::renderDiffUnitStar($unit_status);
$unit = phutil_tag(
'div',
array(
'class' => 'lintunit-star',
- 'title' => self::getDiffUnitMessage($diff),
+ 'title' => self::getDiffUnitMessage($unit_status),
),
$unit);
@@ -312,7 +315,37 @@
const STAR_FAIL = 'fail';
const STAR_SKIP = 'skip';
- public static function renderDiffLintStar(DifferentialDiff $diff) {
+ public static function getDiffLintStatus(DifferentialDiff $diff) {
+ // TODO for lint, "no information" might actually mean "lint ok", but it
+ // looks just like "linters not configured".
+ // This might require more magic in the hm.sendmessage.
+ $targets = $diff->getBuildTargets();
+ $builds_lint_status = array();
+ foreach ($targets as $target) {
+ $builds_lint_status[] = $target->getDetail(HarbormasterBuildTarget::DETAIL_LINT_STATUS);
+ }
+ $builds_lint_status = array_filter($builds_lint_status);
+ $builds_lint_status = HarbormasterLintStatus::getWorstStatus($builds_lint_status);
+ $builds_lint_status = HarbormasterLintStatus::getDifferentialLintStatus($builds_lint_status);
+
+ phlog($builds_lint_status, $diff->getLintStatus());
+ return coalesce($builds_lint_status, $diff->getLintStatus());
+ }
+
+ public static function getDiffUnitStatus(DifferentialDiff $diff) {
+ $targets = $diff->getBuildTargets();
+ $builds_unit_status = array();
+ foreach ($targets as $target) {
+ $builds_unit_status[] = $target->getDetail(HarbormasterBuildTarget::DETAIL_UNIT_STATUS);
+ }
+ $builds_unit_status = array_filter($builds_unit_status);
+ $builds_unit_status = HarbormasterUnitStatus::getWorstStatus($builds_unit_status);
+ $builds_unit_status = HarbormasterUnitStatus::getDifferentialUnitStatus($builds_unit_status);
+
+ return coalesce($builds_unit_status, $diff->getUnitStatus());
+ }
+
+ public static function renderDiffLintStar($status) {
static $map = array(
DifferentialLintStatus::LINT_NONE => self::STAR_NONE,
DifferentialLintStatus::LINT_OKAY => self::STAR_OKAY,
@@ -322,12 +355,12 @@
DifferentialLintStatus::LINT_AUTO_SKIP => self::STAR_SKIP,
);
- $star = idx($map, $diff->getLintStatus(), self::STAR_FAIL);
+ $star = idx($map, $status, self::STAR_FAIL);
return self::renderDiffStar($star);
}
- public static function renderDiffUnitStar(DifferentialDiff $diff) {
+ public static function renderDiffUnitStar($unit_status) {
static $map = array(
DifferentialUnitStatus::UNIT_NONE => self::STAR_NONE,
DifferentialUnitStatus::UNIT_OKAY => self::STAR_OKAY,
@@ -337,13 +370,14 @@
DifferentialUnitStatus::UNIT_AUTO_SKIP => self::STAR_SKIP,
);
- $star = idx($map, $diff->getUnitStatus(), self::STAR_FAIL);
+
+ $star = idx($map, $unit_status, self::STAR_FAIL);
return self::renderDiffStar($star);
}
- public static function getDiffLintMessage(DifferentialDiff $diff) {
- switch ($diff->getLintStatus()) {
+ public static function getDiffLintMessage($status) {
+ switch ($status) {
case DifferentialLintStatus::LINT_NONE:
return pht('No Linters Available');
case DifferentialLintStatus::LINT_OKAY:
@@ -360,8 +394,8 @@
return pht('Unknown');
}
- public static function getDiffUnitMessage(DifferentialDiff $diff) {
- switch ($diff->getUnitStatus()) {
+ public static function getDiffUnitMessage($status) {
+ switch ($status) {
case DifferentialUnitStatus::UNIT_NONE:
return pht('No Unit Test Coverage');
case DifferentialUnitStatus::UNIT_OKAY:
diff --git a/src/applications/harbormaster/constants/HarbormasterLintStatus.php b/src/applications/harbormaster/constants/HarbormasterLintStatus.php
new file mode 100644
--- /dev/null
+++ b/src/applications/harbormaster/constants/HarbormasterLintStatus.php
@@ -0,0 +1,67 @@
+<?php
+
+final class HarbormasterLintStatus
+ extends Phobject {
+
+ public static function getLintStatusLabel($status) {
+ $map = self::getLintStatusDictionary($status);
+ $default = pht('Unknown Status ("%s")', $status);
+ return idx($map, 'label', $default);
+ }
+
+ public static function getLintStatusSort($status) {
+ $map = self::getLintStatusDictionary($status);
+ $default = 'N';
+ return idx($map, 'sort', $default);
+ }
+
+ public static function getWorstStatus(array $statuses) {
+ if (!$statuses) {
+ return null;
+ }
+ $map = self::getLintStatusMap();
+ $default = 'Z';
+ $worst = head($statuses);
+ $w_index = idx($map, $worst, $default);
+ foreach ($statuses as $status) {
+ $r = idx($map, $status, $default);
+ if ($r < $w_index) {
+ $worst = $status;
+ $w_index = $r;
+ }
+ }
+ return $worst;
+ }
+
+ public static function getDifferentialLintStatus($status) {
+ $map = self::getLintStatusDictionary($status);
+ return idx($map, 'differential_value', $status);
+ }
+
+ private static function getLintStatusDictionary($status) {
+ $map = self::getLintStatusMap();
+ $default = array();
+ return idx($map, $status, $default);
+ }
+
+ private static function getLintStatusMap() {
+ return array(
+ ArcanistLintSeverity::SEVERITY_ERROR => array(
+ 'differential_value' => DifferentialLintStatus::LINT_FAIL,
+ 'label' => pht('Error'),
+ 'sort' => 'A',
+ ),
+ ArcanistLintSeverity::SEVERITY_WARNING => array(
+ 'differential_value' => DifferentialLintStatus::LINT_WARN,
+ 'label' => pht('Warning'),
+ 'sort' => 'B',
+ ),
+ ArcanistLintSeverity::SEVERITY_ADVICE => array(
+ 'differential_value' => DifferentialLintStatus::LINT_OKAY,
+ 'label' => pht('Advice'),
+ 'sort' => 'Y',
+ ),
+ );
+ }
+
+}
diff --git a/src/applications/harbormaster/constants/HarbormasterUnitStatus.php b/src/applications/harbormaster/constants/HarbormasterUnitStatus.php
--- a/src/applications/harbormaster/constants/HarbormasterUnitStatus.php
+++ b/src/applications/harbormaster/constants/HarbormasterUnitStatus.php
@@ -27,6 +27,29 @@
return idx($map, 'sort', $default);
}
+ public static function getWorstStatus(array $statuses) {
+ if (!$statuses) {
+ return null;
+ }
+ $map = self::getUnitStatusMap();
+ $default = 'Z';
+ $worst = head($statuses);
+ $w_index = idx($map, $worst, $default);
+ foreach ($statuses as $status) {
+ $r = idx($map, $status, $default);
+ if ($r < $w_index) {
+ $worst = $status;
+ $w_index = $r;
+ }
+ }
+ return $worst;
+ }
+
+ public static function getDifferentialUnitStatus($status) {
+ $map = self::getUnitStatusDictionary($status);
+ return idx($map, 'differantial_result', $status);
+ }
+
private static function getUnitStatusDictionary($status) {
$map = self::getUnitStatusMap();
$default = array();
@@ -55,30 +78,35 @@
private static function getUnitStatusMap() {
return array(
ArcanistUnitTestResult::RESULT_FAIL => array(
+ 'differantial_result' => DifferentialUnitStatus::UNIT_FAIL, // SOMEWHERER, we already making this translation.
'label' => pht('Failed'),
'icon' => 'fa-times',
'color' => 'red',
'sort' => 'A',
),
ArcanistUnitTestResult::RESULT_BROKEN => array(
+ 'differantial_result' => DifferentialUnitStatus::UNIT_WARN,
'label' => pht('Broken'),
'icon' => 'fa-bomb',
'color' => 'indigo',
'sort' => 'B',
),
ArcanistUnitTestResult::RESULT_UNSOUND => array(
+ 'differantial_result' => DifferentialUnitStatus::UNIT_WARN,
'label' => pht('Unsound'),
'icon' => 'fa-exclamation-triangle',
'color' => 'yellow',
'sort' => 'C',
),
ArcanistUnitTestResult::RESULT_PASS => array(
+ 'differantial_result' => DifferentialUnitStatus::UNIT_OKAY,
'label' => pht('Passed'),
'icon' => 'fa-check',
'color' => 'green',
'sort' => 'D',
),
ArcanistUnitTestResult::RESULT_SKIP => array(
+ 'differantial_result' => DifferentialUnitStatus::UNIT_SKIP,
'label' => pht('Skipped'),
'icon' => 'fa-fast-forward',
'color' => 'blue',
diff --git a/src/applications/harbormaster/engine/HarbormasterBuildEngine.php b/src/applications/harbormaster/engine/HarbormasterBuildEngine.php
--- a/src/applications/harbormaster/engine/HarbormasterBuildEngine.php
+++ b/src/applications/harbormaster/engine/HarbormasterBuildEngine.php
@@ -375,7 +375,6 @@
$waiting_targets[$target->getPHID()] = $target;
}
}
-
if (!$waiting_targets) {
return;
}
@@ -386,6 +385,7 @@
->withConsumed(false)
->execute();
+ $updated_targets = array();
foreach ($messages as $message) {
$target = $waiting_targets[$message->getBuildTargetPHID()];
@@ -403,20 +403,106 @@
}
if ($new_status !== null) {
- $message->setIsConsumed(true);
- $message->save();
-
$target->setTargetStatus($new_status);
+
if ($target->isComplete()) {
$target->setDateCompleted(PhabricatorTime::getNow());
}
$target->save();
}
+
+ $updated_targets[] = $message->getBuildTargetPHID();
+ $message->setIsConsumed(true);
+ $message->save();
+ }
+ $updated_targets[] = 'PHID-HMBT-5bhailrqui5kssm67g27'; // -----------------
+ $updated_targets = array_select_keys($waiting_targets, $updated_targets);
+
+ if ($updated_targets) {
+ $this->updateLintAndUnitStatus($updated_targets);
}
}
+ private function updateLintAndUnitStatus(array $targets) { // TODO rename this function, and maybe use it for migration as well.
+ assert_instances_of($targets, 'HarbormasterBuildTarget');
+ $target_phids = mpull($targets, 'getPHID');
+
+ // TODO HarbormasterBuildLintMessageQuery ?
+ $lints = id(new HarbormasterBuildLintMessage())->loadAllWhere(
+ 'buildTargetPHID IN (%Ls)',
+ $target_phids);
+ $lints = mgroup($lints, 'getBuildTargetPHID');
+
+ $units = id(new HarbormasterBuildUnitMessage())->loadAllWhere(
+ 'buildTargetPHID IN (%Ls)',
+ $target_phids);
+ $units = mgroup($units, 'getBuildTargetPHID');
+
+ foreach ($targets as $target) {
+ $target_phid = $target->getPHID();
+ $target_lints = idx($lints, $target_phid);
+ if ($target_lints) {
+ $worst = head(msort($target_lints, 'getSortKey'));
+ $lint_severity = $worst->getSeverity();
+ } else {
+ $lint_severity = null;
+ }
+
+ // TODO also count lint by severity? We don't currently do that
+
+ $target_units = idx($units, $target_phid);
+ phlog($target_units);
+ if ($target_units) {
+ $worst = head(msort($target_units, 'getSortKey'));
+ $unit_result = $worst->getResult();
+
+ $coverage_map = array();
+ foreach ($target_units as $unit) {
+ $coverage = $unit->getProperty('coverage', array());
+ foreach ($coverage as $path => $coverage_data) {
+ $coverage_map[$path][] = $coverage_data;
+ }
+ }
+
+ $groups = mgroup($target_units, 'getResult');
+ $unit_counts = array();
+ foreach ($groups as $status => $group) {
+ $unit_counts[$status] = count($group);
+ }
+
+ foreach ($coverage_map as $path => $coverage_items) {
+ $coverage_map[$path] = ArcanistUnitTestResult::mergeCoverage(
+ $coverage_items);
+ }
+ } else {
+ $unit_result = null;
+ $coverage_map = null;
+ $unit_counts = null;
+ }
+
+ // evil magic: `ORDER BY FIELD(result, 'fail', 'broken', 'skip', 'fail')`, although god knows which versions of mysql allow this.
+
+ $target->setDetail(
+ HarbormasterBuildTarget::DETAIL_LINT_STATUS,
+ $lint_severity);
+
+ $target->setDetail(
+ HarbormasterBuildTarget::DETAIL_UNIT_STATUS,
+ $unit_result);
+
+ $target->setDetail(
+ HarbormasterBuildTarget::DETAIL_UNIT_COUNTS,
+ $unit_counts);
+
+ $target->setDetail(
+ HarbormasterBuildTarget::DETAIL_COVERAGE_MAP,
+ $coverage_map);
+
+ $target->save();
+ }
+ }
/**
* Update the overall status of the buildable this build is attached to.
diff --git a/src/applications/harbormaster/storage/build/HarbormasterBuildTarget.php b/src/applications/harbormaster/storage/build/HarbormasterBuildTarget.php
--- a/src/applications/harbormaster/storage/build/HarbormasterBuildTarget.php
+++ b/src/applications/harbormaster/storage/build/HarbormasterBuildTarget.php
@@ -21,6 +21,11 @@
const STATUS_FAILED = 'target/failed';
const STATUS_ABORTED = 'target/aborted';
+ const DETAIL_LINT_STATUS = 'lint:status';
+ const DETAIL_UNIT_STATUS = 'unit:status';
+ const DETAIL_UNIT_COUNTS = 'unit:counts';
+ const DETAIL_COVERAGE_MAP = 'unit:coverage';
+
private $build = self::ATTACHABLE;
private $buildStep = self::ATTACHABLE;
private $implementation;
diff --git a/src/applications/harbormaster/view/HarbormasterUnitPropertyView.php b/src/applications/harbormaster/view/HarbormasterUnitPropertyView.php
--- a/src/applications/harbormaster/view/HarbormasterUnitPropertyView.php
+++ b/src/applications/harbormaster/view/HarbormasterUnitPropertyView.php
@@ -103,7 +103,7 @@
if ($full_uri && (count($messages) > $limit)) {
$counts = array();
- $groups = mgroup($messages, 'getResult');
+ $groups = mgroup($messages, 'getResult'); // TODO use aggregated info
foreach ($groups as $status => $group) {
$counts[] = HarbormasterUnitStatus::getUnitStatusCountLabel(
$status,
diff --git a/src/applications/harbormaster/view/HarbormasterUnitSummaryView.php b/src/applications/harbormaster/view/HarbormasterUnitSummaryView.php
--- a/src/applications/harbormaster/view/HarbormasterUnitSummaryView.php
+++ b/src/applications/harbormaster/view/HarbormasterUnitSummaryView.php
@@ -40,7 +40,7 @@
$id = $buildable->getID();
$full_uri = "/harbormaster/unit/{$id}/";
- $messages = msort($messages, 'getSortKey');
+ $messages = msort($messages, 'getSortKey'); // TODO avoid msort again, use saved information
$head_unit = head($messages);
if ($head_unit) {
$status = $head_unit->getResult();
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Aug 7, 1:40 AM (3 w, 4 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
8784733
Default Alt Text
D16417.id39485.diff (23 KB)
Attached To
Mode
D16417: Aggregate lint, unit information in HarbormasterBuildable
Attached
Detach File
Event Timeline
Log In to Comment