Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F14853690
D13407.id32468.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
22 KB
Referenced Files
None
Subscribers
None
D13407.id32468.diff
View Options
diff --git a/resources/celerity/map.php b/resources/celerity/map.php
--- a/resources/celerity/map.php
+++ b/resources/celerity/map.php
@@ -10,7 +10,7 @@
'core.pkg.css' => 'eb51e6dc',
'core.pkg.js' => '711e63c0',
'darkconsole.pkg.js' => 'e7393ebb',
- 'differential.pkg.css' => '1ca3c116',
+ 'differential.pkg.css' => '7b52b9be',
'differential.pkg.js' => 'ebef29b1',
'diffusion.pkg.css' => '591664fa',
'diffusion.pkg.js' => '0115b37c',
@@ -64,7 +64,7 @@
'rsrc/css/application/differential/revision-comment.css' => '14b8565a',
'rsrc/css/application/differential/revision-history.css' => '0e8eb855',
'rsrc/css/application/differential/revision-list.css' => 'f3c47d33',
- 'rsrc/css/application/differential/table-of-contents.css' => '63f3ef4a',
+ 'rsrc/css/application/differential/table-of-contents.css' => 'ae4b7a55',
'rsrc/css/application/diffusion/diffusion-icons.css' => '9c5828da',
'rsrc/css/application/diffusion/diffusion-readme.css' => '2106ea08',
'rsrc/css/application/diffusion/diffusion-source.css' => '66fdf661',
@@ -515,7 +515,7 @@
'differential-revision-comment-css' => '14b8565a',
'differential-revision-history-css' => '0e8eb855',
'differential-revision-list-css' => 'f3c47d33',
- 'differential-table-of-contents-css' => '63f3ef4a',
+ 'differential-table-of-contents-css' => 'ae4b7a55',
'diffusion-icons-css' => '9c5828da',
'diffusion-readme-css' => '2106ea08',
'diffusion-source-css' => '66fdf661',
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
@@ -891,6 +891,7 @@
'HarbormasterDAO' => 'applications/harbormaster/storage/HarbormasterDAO.php',
'HarbormasterHTTPRequestBuildStepImplementation' => 'applications/harbormaster/step/HarbormasterHTTPRequestBuildStepImplementation.php',
'HarbormasterLeaseHostBuildStepImplementation' => 'applications/harbormaster/step/HarbormasterLeaseHostBuildStepImplementation.php',
+ 'HarbormasterLintMessagesController' => 'applications/harbormaster/controller/HarbormasterLintMessagesController.php',
'HarbormasterLintPropertyView' => 'applications/harbormaster/view/HarbormasterLintPropertyView.php',
'HarbormasterManagePlansCapability' => 'applications/harbormaster/capability/HarbormasterManagePlansCapability.php',
'HarbormasterManagementBuildWorkflow' => 'applications/harbormaster/management/HarbormasterManagementBuildWorkflow.php',
@@ -919,6 +920,7 @@
'HarbormasterTargetWorker' => 'applications/harbormaster/worker/HarbormasterTargetWorker.php',
'HarbormasterThrowExceptionBuildStep' => 'applications/harbormaster/step/HarbormasterThrowExceptionBuildStep.php',
'HarbormasterUIEventListener' => 'applications/harbormaster/event/HarbormasterUIEventListener.php',
+ 'HarbormasterUnitMessagesController' => 'applications/harbormaster/controller/HarbormasterUnitMessagesController.php',
'HarbormasterUnitPropertyView' => 'applications/harbormaster/view/HarbormasterUnitPropertyView.php',
'HarbormasterUploadArtifactBuildStepImplementation' => 'applications/harbormaster/step/HarbormasterUploadArtifactBuildStepImplementation.php',
'HarbormasterWaitForPreviousBuildStepImplementation' => 'applications/harbormaster/step/HarbormasterWaitForPreviousBuildStepImplementation.php',
@@ -4353,6 +4355,7 @@
'HarbormasterDAO' => 'PhabricatorLiskDAO',
'HarbormasterHTTPRequestBuildStepImplementation' => 'HarbormasterBuildStepImplementation',
'HarbormasterLeaseHostBuildStepImplementation' => 'HarbormasterBuildStepImplementation',
+ 'HarbormasterLintMessagesController' => 'HarbormasterController',
'HarbormasterLintPropertyView' => 'AphrontView',
'HarbormasterManagePlansCapability' => 'PhabricatorPolicyCapability',
'HarbormasterManagementBuildWorkflow' => 'HarbormasterManagementWorkflow',
@@ -4381,6 +4384,7 @@
'HarbormasterTargetWorker' => 'HarbormasterWorker',
'HarbormasterThrowExceptionBuildStep' => 'HarbormasterBuildStepImplementation',
'HarbormasterUIEventListener' => 'PhabricatorEventListener',
+ 'HarbormasterUnitMessagesController' => 'HarbormasterController',
'HarbormasterUnitPropertyView' => 'AphrontView',
'HarbormasterUploadArtifactBuildStepImplementation' => 'HarbormasterBuildStepImplementation',
'HarbormasterWaitForPreviousBuildStepImplementation' => 'HarbormasterBuildStepImplementation',
diff --git a/src/applications/differential/customfield/DifferentialHarbormasterField.php b/src/applications/differential/customfield/DifferentialHarbormasterField.php
--- a/src/applications/differential/customfield/DifferentialHarbormasterField.php
+++ b/src/applications/differential/customfield/DifferentialHarbormasterField.php
@@ -81,12 +81,23 @@
$path_map[$path] = $href;
}
- $view = $this->newHarbormasterMessageView($messages)
- ->setPathURIMap($path_map);
+ $view = $this->newHarbormasterMessageView($messages);
+ if ($view) {
+ $view->setPathURIMap($path_map);
+ }
} else {
$view = null;
}
+ if ($view) {
+ $view = phutil_tag(
+ 'div',
+ array(
+ 'class' => 'differential-harbormaster-table-view',
+ ),
+ $view);
+ }
+
return array(
$status,
$view,
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
@@ -50,6 +50,7 @@
protected function newHarbormasterMessageView(array $messages) {
return id(new HarbormasterLintPropertyView())
+ ->setLimit(25)
->setLintMessages($messages);
}
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
@@ -44,7 +44,7 @@
protected function loadHarbormasterTargetMessages(array $target_phids) {
return id(new HarbormasterBuildUnitMessage())->loadAllWhere(
- 'buildTargetPHID IN (%Ls) LIMIT 25',
+ 'buildTargetPHID IN (%Ls)',
$target_phids);
}
@@ -55,7 +55,19 @@
}
protected function newHarbormasterMessageView(array $messages) {
+ foreach ($messages as $key => $message) {
+ if ($message->getResult() == ArcanistUnitTestResult::RESULT_PASS) {
+ unset($messages[$key]);
+ }
+ }
+
+ if (!$messages) {
+ return null;
+ }
+
return id(new HarbormasterUnitPropertyView())
+ ->setLimit(10)
+ ->setHidePassingTests(true)
->setUnitMessages($messages);
}
@@ -97,6 +109,55 @@
$message = DifferentialRevisionUpdateHistoryView::getDiffUnitMessage($diff);
+ $note = array();
+
+ $groups = mgroup($messages, 'getResult');
+
+ $groups = array_select_keys(
+ $groups,
+ array(
+ ArcanistUnitTestResult::RESULT_FAIL,
+ ArcanistUnitTestResult::RESULT_BROKEN,
+ ArcanistUnitTestResult::RESULT_UNSOUND,
+ ArcanistUnitTestResult::RESULT_SKIP,
+ ArcanistUnitTestResult::RESULT_PASS,
+ )) + $groups;
+
+ foreach ($groups as $result => $group) {
+ $count = new PhutilNumber(count($group));
+ switch ($result) {
+ case ArcanistUnitTestResult::RESULT_PASS:
+ $note[] = pht('%s Passed Test(s)', $count);
+ break;
+ case ArcanistUnitTestResult::RESULT_FAIL:
+ $note[] = pht('%s Failed Test(s)', $count);
+ break;
+ case ArcanistUnitTestResult::RESULT_SKIP:
+ $note[] = pht('%s Skipped Test(s)', $count);
+ break;
+ case ArcanistUnitTestResult::RESULT_BROKEN:
+ $note[] = pht('%s Broken Test(s)', $count);
+ break;
+ case ArcanistUnitTestResult::RESULT_UNSOUND:
+ $note[] = pht('%s Unsound Test(s)', $count);
+ break;
+ default:
+ $note[] = pht('%s Other Test(s)', $count);
+ break;
+ }
+ }
+
+ $buildable = $diff->getBuildable();
+ if ($buildable) {
+ $full_results = '/harbormaster/unit/'.$buildable->getID().'/';
+ $note[] = phutil_tag(
+ 'a',
+ array(
+ 'href' => $full_results,
+ ),
+ pht('View Full Results'));
+ }
+
$excuse = $diff->getProperty('arc:unit-excuse');
if (strlen($excuse)) {
$excuse = array(
@@ -104,14 +165,17 @@
' ',
phutil_escape_html_newlines($excuse),
);
+ $note[] = $excuse;
}
+ $note = phutil_implode_html(" \xC2\xB7 ", $note);
+
$status = id(new PHUIStatusListView())
->addItem(
id(new PHUIStatusItemView())
->setIcon(PHUIStatusItemView::ICON_STAR, $icon_color)
->setTarget($message)
- ->setNote($excuse));
+ ->setNote($note));
return $status;
}
diff --git a/src/applications/harbormaster/application/PhabricatorHarbormasterApplication.php b/src/applications/harbormaster/application/PhabricatorHarbormasterApplication.php
--- a/src/applications/harbormaster/application/PhabricatorHarbormasterApplication.php
+++ b/src/applications/harbormaster/application/PhabricatorHarbormasterApplication.php
@@ -77,6 +77,12 @@
'run/(?P<id>\d+)/' => 'HarbormasterPlanRunController',
'(?P<id>\d+)/' => 'HarbormasterPlanViewController',
),
+ 'unit/' => array(
+ '(?P<id>\d+)/' => 'HarbormasterUnitMessagesController',
+ ),
+ 'lint/' => array(
+ '(?P<id>\d+)/' => 'HarbormasterLintMessagesController',
+ ),
),
);
}
diff --git a/src/applications/harbormaster/controller/HarbormasterBuildableViewController.php b/src/applications/harbormaster/controller/HarbormasterBuildableViewController.php
--- a/src/applications/harbormaster/controller/HarbormasterBuildableViewController.php
+++ b/src/applications/harbormaster/controller/HarbormasterBuildableViewController.php
@@ -25,7 +25,7 @@
->needBuildTargets(true)
->execute();
- list($lint, $unit) = $this->renderLintAndUnit($builds);
+ list($lint, $unit) = $this->renderLintAndUnit($buildable, $builds);
$buildable->attachBuilds($builds);
$object = $buildable->getBuildableObject();
@@ -255,7 +255,10 @@
return $box;
}
- private function renderLintAndUnit(array $builds) {
+ private function renderLintAndUnit(
+ HarbormasterBuildable $buildable,
+ array $builds) {
+
$viewer = $this->getViewer();
$targets = array();
@@ -272,20 +275,32 @@
$target_phids = mpull($targets, 'getPHID');
$lint_data = id(new HarbormasterBuildLintMessage())->loadAllWhere(
- 'buildTargetPHID IN (%Ls) LIMIT 25',
+ 'buildTargetPHID IN (%Ls)',
$target_phids);
$unit_data = id(new HarbormasterBuildUnitMessage())->loadAllWhere(
- 'buildTargetPHID IN (%Ls) LIMIT 25',
+ 'buildTargetPHID IN (%Ls)',
$target_phids);
if ($lint_data) {
$lint_table = id(new HarbormasterLintPropertyView())
->setUser($viewer)
+ ->setLimit(10)
->setLintMessages($lint_data);
+ $lint_href = $this->getApplicationURI('lint/'.$buildable->getID().'/');
+
+ $lint_header = id(new PHUIHeaderView())
+ ->setHeader(pht('Lint Messages'))
+ ->addActionLink(
+ id(new PHUIButtonView())
+ ->setTag('a')
+ ->setHref($lint_href)
+ ->setIconFont('fa-list-ul')
+ ->setText('View All'));
+
$lint = id(new PHUIObjectBoxView())
- ->setHeaderText(pht('Lint Messages'))
+ ->setHeader($lint_header)
->appendChild($lint_table);
} else {
$lint = null;
@@ -294,10 +309,22 @@
if ($unit_data) {
$unit_table = id(new HarbormasterUnitPropertyView())
->setUser($viewer)
+ ->setLimit(25)
->setUnitMessages($unit_data);
+ $unit_href = $this->getApplicationURI('unit/'.$buildable->getID().'/');
+
+ $unit_header = id(new PHUIHeaderView())
+ ->setHeader(pht('Unit Tests'))
+ ->addActionLink(
+ id(new PHUIButtonView())
+ ->setTag('a')
+ ->setHref($unit_href)
+ ->setIconFont('fa-list-ul')
+ ->setText('View All'));
+
$unit = id(new PHUIObjectBoxView())
- ->setHeaderText(pht('Unit Tests'))
+ ->setHeader($unit_header)
->appendChild($unit_table);
} else {
$unit = null;
diff --git a/src/applications/harbormaster/controller/HarbormasterLintMessagesController.php b/src/applications/harbormaster/controller/HarbormasterLintMessagesController.php
new file mode 100644
--- /dev/null
+++ b/src/applications/harbormaster/controller/HarbormasterLintMessagesController.php
@@ -0,0 +1,64 @@
+<?php
+
+final class HarbormasterLintMessagesController
+ extends HarbormasterController {
+
+ public function handleRequest(AphrontRequest $request) {
+ $viewer = $this->getViewer();
+
+ $buildable = id(new HarbormasterBuildableQuery())
+ ->setViewer($viewer)
+ ->withIDs(array($request->getURIData('id')))
+ ->needBuilds(true)
+ ->needTargets(true)
+ ->executeOne();
+ if (!$buildable) {
+ return new Aphront404Response();
+ }
+
+ $id = $buildable->getID();
+
+ $target_phids = array();
+ foreach ($buildable->getBuilds() as $build) {
+ foreach ($build->getBuildTargets() as $target) {
+ $target_phids[] = $target->getPHID();
+ }
+ }
+
+ $lint_data = array();
+ if ($target_phids) {
+ $lint_data = id(new HarbormasterBuildLintMessage())->loadAllWhere(
+ 'buildTargetPHID IN (%Ls)',
+ $target_phids);
+ } else {
+ $lint_data = array();
+ }
+
+ $lint_table = id(new HarbormasterLintPropertyView())
+ ->setUser($viewer)
+ ->setLintMessages($lint_data);
+
+ $lint = id(new PHUIObjectBoxView())
+ ->setHeaderText(pht('Lint Messages'))
+ ->appendChild($lint_table);
+
+ $crumbs = $this->buildApplicationCrumbs();
+ $this->addBuildableCrumb($crumbs, $buildable);
+ $crumbs->addTextCrumb(pht('Lint'));
+
+ $title = array(
+ $buildable->getMonogram(),
+ pht('Lint'),
+ );
+
+ return $this->buildApplicationPage(
+ array(
+ $crumbs,
+ $lint,
+ ),
+ array(
+ 'title' => $title,
+ ));
+ }
+
+}
diff --git a/src/applications/harbormaster/controller/HarbormasterUnitMessagesController.php b/src/applications/harbormaster/controller/HarbormasterUnitMessagesController.php
new file mode 100644
--- /dev/null
+++ b/src/applications/harbormaster/controller/HarbormasterUnitMessagesController.php
@@ -0,0 +1,64 @@
+<?php
+
+final class HarbormasterUnitMessagesController
+ extends HarbormasterController {
+
+ public function handleRequest(AphrontRequest $request) {
+ $viewer = $this->getViewer();
+
+ $buildable = id(new HarbormasterBuildableQuery())
+ ->setViewer($viewer)
+ ->withIDs(array($request->getURIData('id')))
+ ->needBuilds(true)
+ ->needTargets(true)
+ ->executeOne();
+ if (!$buildable) {
+ return new Aphront404Response();
+ }
+
+ $id = $buildable->getID();
+
+ $target_phids = array();
+ foreach ($buildable->getBuilds() as $build) {
+ foreach ($build->getBuildTargets() as $target) {
+ $target_phids[] = $target->getPHID();
+ }
+ }
+
+ $unit_data = array();
+ if ($target_phids) {
+ $unit_data = id(new HarbormasterBuildUnitMessage())->loadAllWhere(
+ 'buildTargetPHID IN (%Ls)',
+ $target_phids);
+ } else {
+ $unit_data = array();
+ }
+
+ $unit_table = id(new HarbormasterUnitPropertyView())
+ ->setUser($viewer)
+ ->setUnitMessages($unit_data);
+
+ $unit = id(new PHUIObjectBoxView())
+ ->setHeaderText(pht('Unit Tests'))
+ ->appendChild($unit_table);
+
+ $crumbs = $this->buildApplicationCrumbs();
+ $this->addBuildableCrumb($crumbs, $buildable);
+ $crumbs->addTextCrumb(pht('Unit Tests'));
+
+ $title = array(
+ $buildable->getMonogram(),
+ pht('Unit Tests'),
+ );
+
+ return $this->buildApplicationPage(
+ array(
+ $crumbs,
+ $unit,
+ ),
+ array(
+ 'title' => $title,
+ ));
+ }
+
+}
diff --git a/src/applications/harbormaster/storage/build/HarbormasterBuildLintMessage.php b/src/applications/harbormaster/storage/build/HarbormasterBuildLintMessage.php
--- a/src/applications/harbormaster/storage/build/HarbormasterBuildLintMessage.php
+++ b/src/applications/harbormaster/storage/build/HarbormasterBuildLintMessage.php
@@ -95,4 +95,26 @@
return $this;
}
+ public function getSortKey() {
+ // TODO: Maybe use more numeric values after T6861.
+ $map = array(
+ ArcanistLintSeverity::SEVERITY_ERROR => 'A',
+ ArcanistLintSeverity::SEVERITY_WARNING => 'B',
+ ArcanistLintSeverity::SEVERITY_AUTOFIX => 'C',
+ ArcanistLintSeverity::SEVERITY_ADVICE => 'Y',
+ ArcanistLintSeverity::SEVERITY_DISABLED => 'Z',
+ );
+
+ $severity = idx($map, $this->getSeverity(), 'N');
+
+ $parts = array(
+ $severity,
+ $this->getPath(),
+ sprintf('%08d', $this->getLine()),
+ $this->getCode(),
+ );
+
+ return implode("\0", $parts);
+ }
+
}
diff --git a/src/applications/harbormaster/storage/build/HarbormasterBuildUnitMessage.php b/src/applications/harbormaster/storage/build/HarbormasterBuildUnitMessage.php
--- a/src/applications/harbormaster/storage/build/HarbormasterBuildUnitMessage.php
+++ b/src/applications/harbormaster/storage/build/HarbormasterBuildUnitMessage.php
@@ -97,4 +97,26 @@
return $this;
}
+ public function getSortKey() {
+ // TODO: Maybe use more numeric values after T6861.
+ $map = array(
+ ArcanistUnitTestResult::RESULT_FAIL => 'A',
+ ArcanistUnitTestResult::RESULT_BROKEN => 'B',
+ ArcanistUnitTestResult::RESULT_UNSOUND => 'C',
+ ArcanistUnitTestResult::RESULT_PASS => 'Z',
+ );
+
+ $result = idx($map, $this->getResult(), 'N');
+
+ $parts = array(
+ $result,
+ $this->getEngine(),
+ $this->getNamespace(),
+ $this->getName(),
+ $this->getID(),
+ );
+
+ return implode("\0", $parts);
+ }
+
}
diff --git a/src/applications/harbormaster/view/HarbormasterLintPropertyView.php b/src/applications/harbormaster/view/HarbormasterLintPropertyView.php
--- a/src/applications/harbormaster/view/HarbormasterLintPropertyView.php
+++ b/src/applications/harbormaster/view/HarbormasterLintPropertyView.php
@@ -4,6 +4,7 @@
private $pathURIMap = array();
private $lintMessages = array();
+ private $limit;
public function setPathURIMap(array $map) {
$this->pathURIMap = $map;
@@ -16,9 +17,21 @@
return $this;
}
+ public function setLimit($limit) {
+ $this->limit = $limit;
+ return $this;
+ }
+
public function render() {
+ $messages = $this->lintMessages;
+ $messages = msort($messages, 'getSortKey');
+
+ if ($this->limit) {
+ $messages = array_slice($messages, 0, $this->limit);
+ }
+
$rows = array();
- foreach ($this->lintMessages as $message) {
+ foreach ($messages as $message) {
$path = $message->getPath();
$line = $message->getLine();
@@ -40,8 +53,8 @@
}
$rows[] = array(
- $location,
$severity,
+ $location,
$message->getCode(),
$message->getName(),
);
@@ -50,15 +63,15 @@
$table = id(new AphrontTableView($rows))
->setHeaders(
array(
- pht('Location'),
pht('Severity'),
+ pht('Location'),
pht('Code'),
pht('Message'),
))
->setColumnClasses(
array(
- 'pri',
null,
+ 'pri',
null,
'wide',
));
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
@@ -4,6 +4,7 @@
private $pathURIMap = array();
private $unitMessages = array();
+ private $limit;
public function setPathURIMap(array $map) {
$this->pathURIMap = $map;
@@ -16,11 +17,22 @@
return $this;
}
+ public function setLimit($limit) {
+ $this->limit = $limit;
+ return $this;
+ }
+
public function render() {
+ $messages = $this->unitMessages;
+ $messages = msort($messages, 'getSortKey');
+
+ if ($this->limit) {
+ $messages = array_slice($messages, 0, $this->limit);
+ }
$rows = array();
$any_duration = false;
- foreach ($this->unitMessages as $message) {
+ foreach ($messages as $message) {
$result = $this->renderResult($message->getResult());
$duration = $message->getDuration();
@@ -48,7 +60,6 @@
);
}
-
$table = id(new AphrontTableView($rows))
->setHeaders(
array(
diff --git a/src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php b/src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php
--- a/src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php
+++ b/src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php
@@ -1170,6 +1170,13 @@
'This call takes %s parameters, but only %s are documented.',
),
),
+
+ '%s Passed Test(s)' => '%s Passed',
+ '%s Failed Test(s)' => '%s Failed',
+ '%s Skipped Test(s)' => '%s Skipped',
+ '%s Broken Test(s)' => '%s Broken',
+ '%s Unsound Test(s)' => '%s Unsound',
+ '%s Other Test(s)' => '%s Other',
);
}
diff --git a/webroot/rsrc/css/application/differential/table-of-contents.css b/webroot/rsrc/css/application/differential/table-of-contents.css
--- a/webroot/rsrc/css/application/differential/table-of-contents.css
+++ b/webroot/rsrc/css/application/differential/table-of-contents.css
@@ -83,3 +83,8 @@
border-top: 1px solid {$thinblueborder};
padding: 8px;
}
+
+.differential-harbormaster-table-view {
+ margin: 4px 0;
+ border: 1px solid {$thinblueborder};
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Feb 6, 4:11 AM (18 h, 24 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7094208
Default Alt Text
D13407.id32468.diff (22 KB)
Attached To
Mode
D13407: Improve lint/unit limit, sort, view all, collapse behaviors
Attached
Detach File
Event Timeline
Log In to Comment