diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
index 898a246470..47484d5de4 100644
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -361,6 +361,7 @@ phutil_register_library_map(array(
'DiffusionLastModifiedController' => 'applications/diffusion/controller/DiffusionLastModifiedController.php',
'DiffusionLastModifiedQuery' => 'applications/diffusion/query/lastmodified/DiffusionLastModifiedQuery.php',
'DiffusionLintController' => 'applications/diffusion/controller/DiffusionLintController.php',
+ 'DiffusionLintDetailsController' => 'applications/diffusion/controller/DiffusionLintDetailsController.php',
'DiffusionMercurialBranchQuery' => 'applications/diffusion/query/branch/DiffusionMercurialBranchQuery.php',
'DiffusionMercurialBrowseQuery' => 'applications/diffusion/query/browse/DiffusionMercurialBrowseQuery.php',
'DiffusionMercurialCommitParentsQuery' => 'applications/diffusion/query/parents/DiffusionMercurialCommitParentsQuery.php',
@@ -1601,6 +1602,7 @@ phutil_register_library_map(array(
'DiffusionLastModifiedController' => 'DiffusionController',
'DiffusionLastModifiedQuery' => 'DiffusionQuery',
'DiffusionLintController' => 'DiffusionController',
+ 'DiffusionLintDetailsController' => 'DiffusionController',
'DiffusionMercurialBranchQuery' => 'DiffusionBranchQuery',
'DiffusionMercurialBrowseQuery' => 'DiffusionBrowseQuery',
'DiffusionMercurialCommitParentsQuery' => 'DiffusionCommitParentsQuery',
diff --git a/src/applications/diffusion/controller/DiffusionBrowseFileController.php b/src/applications/diffusion/controller/DiffusionBrowseFileController.php
index f89543e50e..be92f51533 100644
--- a/src/applications/diffusion/controller/DiffusionBrowseFileController.php
+++ b/src/applications/diffusion/controller/DiffusionBrowseFileController.php
@@ -343,7 +343,7 @@ final class DiffusionBrowseFileController extends DiffusionController {
$href = null;
if ($this->getRequest()->getStr('lint') !== null) {
- $lint_text = pht('Hide %d Lint Messages', count($this->lintMessages));
+ $lint_text = pht('Hide %d Lint Message(s)', count($this->lintMessages));
$href = $base_uri->alter('lint', null);
} else if ($this->lintCommit === null) {
@@ -359,7 +359,7 @@ final class DiffusionBrowseFileController extends DiffusionController {
))->alter('lint', '');
} else if (!$this->lintMessages) {
- $lint_text = pht('0 Lint Messages');
+ $lint_text = pht('No Lint Messages');
} else {
$lint_text = pht('Show %d Lint Message(s)', count($this->lintMessages));
@@ -573,7 +573,9 @@ final class DiffusionBrowseFileController extends DiffusionController {
foreach ($this->lintMessages as $message) {
$inline = id(new PhabricatorAuditInlineComment())
- ->setSyntheticAuthor($message['code'].' ('.$message['name'].')')
+ ->setSyntheticAuthor(
+ ArcanistLintSeverity::getStringForSeverity($message['severity']).
+ ' '.$message['code'].' ('.$message['name'].')')
->setLineNumber($message['line'])
->setContent($message['description']);
$inlines[$message['line']][] = $inline;
diff --git a/src/applications/diffusion/controller/DiffusionLintController.php b/src/applications/diffusion/controller/DiffusionLintController.php
index 0dc0a784af..9ace062608 100644
--- a/src/applications/diffusion/controller/DiffusionLintController.php
+++ b/src/applications/diffusion/controller/DiffusionLintController.php
@@ -6,13 +6,25 @@ final class DiffusionLintController extends DiffusionController {
public function processRequest() {
$drequest = $this->getDiffusionRequest();
+ if ($this->getRequest()->getStr('lint')) {
+ $controller = new DiffusionLintDetailsController($this->getRequest());
+ $controller->setDiffusionRequest($drequest);
+ return $this->delegateToController($controller);
+ }
+
$codes = $this->loadLintCodes();
$codes = array_reverse(isort($codes, 'n'));
$rows = array();
foreach ($codes as $code) {
$rows[] = array(
- $code['n'],
+ hsprintf(
+ '%s',
+ $drequest->generateURI(array(
+ 'action' => 'lint',
+ 'lint' => $code['code'],
+ )),
+ $code['n']),
hsprintf(
'%s',
$drequest->generateURI(array(
@@ -56,7 +68,7 @@ final class DiffusionLintController extends DiffusionController {
));
$content[] = id(new AphrontPanelView())
- ->setHeader(array_sum(ipull($codes, 'n')).' Lint Messages')
+ ->setHeader(pht('%d Lint Message(s)', array_sum(ipull($codes, 'n'))))
->appendChild($table);
$nav = $this->buildSideNav('lint', false);
diff --git a/src/applications/diffusion/controller/DiffusionLintDetailsController.php b/src/applications/diffusion/controller/DiffusionLintDetailsController.php
new file mode 100644
index 0000000000..17c0d28889
--- /dev/null
+++ b/src/applications/diffusion/controller/DiffusionLintDetailsController.php
@@ -0,0 +1,131 @@
+getRequest()->getInt('offset', 0);
+
+ $drequest = $this->getDiffusionRequest();
+ $messages = $this->loadLintMessages($limit, $offset);
+ $is_dir = (substr('/'.$drequest->getPath(), -1) == '/');
+
+ $rows = array();
+ foreach ($messages as $message) {
+ $path = hsprintf(
+ '%s',
+ $drequest->generateURI(array(
+ 'action' => 'lint',
+ 'path' => $message['path'],
+ )),
+ substr($message['path'], strlen($drequest->getPath()) + 1));
+
+ $line = hsprintf(
+ '%s',
+ $drequest->generateURI(array(
+ 'action' => 'browse',
+ 'path' => $message['path'],
+ 'line' => $message['line'],
+ )),
+ $message['line']);
+
+ $rows[] = array(
+ $path,
+ $line,
+ phutil_escape_html(ArcanistLintSeverity::getStringForSeverity(
+ $message['severity'])),
+ phutil_escape_html($message['code']),
+ phutil_escape_html($message['name']),
+ phutil_escape_html($message['description']),
+ );
+ }
+
+ $table = id(new AphrontTableView($rows))
+ ->setHeaders(array(
+ 'Path',
+ 'Line',
+ 'Severity',
+ 'Code',
+ 'Name',
+ 'Example',
+ ))
+ ->setColumnClasses(array(
+ '',
+ 'n',
+ '',
+ 'pri',
+ '',
+ '',
+ ))
+ ->setColumnVisibility(array(
+ $is_dir,
+ ));
+
+ $content = array();
+
+ $content[] = $this->buildCrumbs(
+ array(
+ 'branch' => true,
+ 'path' => true,
+ 'view' => 'lint',
+ ));
+
+ $pager = id(new AphrontPagerView())
+ ->setPageSize($limit)
+ ->setOffset($offset)
+ ->setHasMorePages(count($messages) >= $limit)
+ ->setURI($this->getRequest()->getRequestURI(), 'offset');
+
+ $content[] = id(new AphrontPanelView())
+ ->setHeader(pht('%d Lint Message(s)', count($messages)))
+ ->appendChild($table)
+ ->appendChild($pager);
+
+ $nav = $this->buildSideNav('lint', false);
+ $nav->appendChild($content);
+
+ return $this->buildStandardPageResponse(
+ $nav,
+ array('title' => array(
+ 'Lint',
+ $drequest->getRepository()->getCallsign(),
+ )));
+ }
+
+ private function loadLintMessages($limit, $offset) {
+ $drequest = $this->getDiffusionRequest();
+ $branch = $drequest->loadBranch();
+ if (!$branch) {
+ return array();
+ }
+
+ $conn = $branch->establishConnection('r');
+
+ $where = '';
+ if ($drequest->getPath() != '') {
+ $is_dir = (substr($drequest->getPath(), -1) == '/');
+ $where = qsprintf(
+ $conn,
+ 'AND path '.($is_dir ? 'LIKE %>' : '= %s'),
+ '/'.$drequest->getPath());
+ }
+
+ return queryfx_all(
+ $conn,
+ 'SELECT *
+ FROM %T
+ WHERE branchID = %d
+ AND code = %s
+ %Q
+ LIMIT %d OFFSET %d',
+ // 'ORDER BY path, code, line' is disabled for performance reasons.
+ PhabricatorRepository::TABLE_LINTMESSAGE,
+ $branch->getID(),
+ $drequest->getLint(),
+ $where,
+ $limit,
+ $offset);
+ }
+
+}
diff --git a/src/infrastructure/internationalization/PhabricatorBaseEnglishTranslation.php b/src/infrastructure/internationalization/PhabricatorBaseEnglishTranslation.php
index eb2fb02e7e..21fe6fd640 100644
--- a/src/infrastructure/internationalization/PhabricatorBaseEnglishTranslation.php
+++ b/src/infrastructure/internationalization/PhabricatorBaseEnglishTranslation.php
@@ -154,16 +154,18 @@ abstract class PhabricatorBaseEnglishTranslation
'Show %d Lint Message',
'Show %d Lint Messages',
),
-
'Hide %d Lint Message(s)' => array(
'Hide %d Lint Message',
'Hide %d Lint Messages',
),
-
'Switch for %d Lint Message(s)' => array(
'Switch for %d Lint Message',
'Switch for %d Lint Messages',
),
+ '%d Lint Message(s)' => array(
+ '%d Lint Message',
+ '%d Lint Messages',
+ ),
);
}