public function renderLintResult(ArcanistLintResult $result) { $messages = $result->getMessages(); $path = $result->getPath(); $lines = explode("\n", $result->getData()); $text = array(); foreach ($messages as $message) { if (!$this->showAutofixPatches && $message->isAutofix()) { continue; } if ($message->isError()) { $color = 'red'; } else { $color = 'yellow'; } $severity = ArcanistLintSeverity::getStringForSeverity($message->getSeverity()); $code = $message->getCode(); $name = $message->getName(); $description = phutil_console_wrap($message->getDescription(), 4); $text[] = phutil_console_format(" **<bg:{$color}> %s </bg>** (%s) __%s__\n%s\n", $severity, $code, $name, $description); if ($message->hasFileContext()) { $text[] = $this->renderContext($message, $lines); } } if ($text) { $prefix = phutil_console_format("**>>>** Lint for __%s__:\n\n\n", $path); return $prefix . implode("\n", $text); } else { return null; } }
protected function processDiffusionRequest(AphrontRequest $request) { $limit = 500; $offset = $request->getInt('offset', 0); $drequest = $this->getDiffusionRequest(); $branch = $drequest->loadBranch(); $messages = $this->loadLintMessages($branch, $limit, $offset); $is_dir = substr('/' . $drequest->getPath(), -1) == '/'; $authors = $this->loadViewerHandles(ipull($messages, 'authorPHID')); $rows = array(); foreach ($messages as $message) { $path = phutil_tag('a', array('href' => $drequest->generateURI(array('action' => 'lint', 'path' => $message['path']))), substr($message['path'], strlen($drequest->getPath()) + 1)); $line = phutil_tag('a', array('href' => $drequest->generateURI(array('action' => 'browse', 'path' => $message['path'], 'line' => $message['line'], 'commit' => $branch->getLintCommit()))), $message['line']); $author = $message['authorPHID']; if ($author && $authors[$author]) { $author = $authors[$author]->renderLink(); } $rows[] = array($path, $line, $author, ArcanistLintSeverity::getStringForSeverity($message['severity']), $message['name'], $message['description']); } $table = id(new AphrontTableView($rows))->setHeaders(array(pht('Path'), pht('Line'), pht('Author'), pht('Severity'), pht('Name'), pht('Description')))->setColumnClasses(array('', 'n'))->setColumnVisibility(array($is_dir)); $content = array(); $pager = id(new AphrontPagerView())->setPageSize($limit)->setOffset($offset)->setHasMorePages(count($messages) >= $limit)->setURI($request->getRequestURI(), 'offset'); $content[] = id(new PHUIObjectBoxView())->setHeaderText(pht('Lint Details'))->appendChild($table); $crumbs = $this->buildCrumbs(array('branch' => true, 'path' => true, 'view' => 'lint')); return $this->buildApplicationPage(array($crumbs, $content, $pager), array('title' => array(pht('Lint'), $drequest->getRepository()->getCallsign()))); }
public function renderLintResult(ArcanistLintResult $result) { $messages = $result->getMessages(); $path = $result->getPath(); $text = array(); foreach ($messages as $message) { $name = $message->getName(); $severity = ArcanistLintSeverity::getStringForSeverity($message->getSeverity()); $line = $message->getLine(); $text[] = "{$path}:{$line}:{$severity}: {$name}\n"; } return implode('', $text); }
public function renderLintResult(ArcanistLintResult $result) { $lines = array(); $messages = $result->getMessages(); $path = $result->getPath(); foreach ($messages as $message) { $severity = ArcanistLintSeverity::getStringForSeverity($message->getSeverity()); $line = $message->getLine(); $code = $message->getCode(); $description = $message->getDescription(); $lines[] = sprintf("%s:%d:%s (%s) %s\n", $path, $line, $severity, $code, $description); } return implode('', $lines); }
public function renderLintResult(ArcanistLintResult $result) { $this->writer->startElement('file'); $this->writer->writeAttribute('name', $result->getPath()); foreach ($result->getMessages() as $message) { $this->writer->startElement('error'); $this->writer->writeAttribute('line', $message->getLine()); $this->writer->writeAttribute('column', $message->getChar()); $this->writer->writeAttribute('severity', ArcanistLintSeverity::getStringForSeverity($message->getSeverity())); $this->writer->writeAttribute('message', $message->getDescription()); $this->writer->writeAttribute('source', $message->getCode()); $this->writer->endElement(); } $this->writer->endElement(); return $this->writer->flush(); }
public function renderLintResult(ArcanistLintResult $result) { $messages = $result->getMessages(); $path = $result->getPath(); $lines = explode("\n", $result->getData()); $text = array(); foreach ($messages as $message) { if (!$this->showAutofixPatches && $message->isAutofix()) { continue; } if ($message->isError()) { $color = 'red'; } else { $color = 'yellow'; } $severity = ArcanistLintSeverity::getStringForSeverity($message->getSeverity()); $code = $message->getCode(); $name = $message->getName(); $description = $message->getDescription(); if ($message->getOtherLocations()) { $locations = array(); foreach ($message->getOtherLocations() as $location) { $locations[] = idx($location, 'path', $path) . (!empty($location['line']) ? ":{$location['line']}" : ''); } $description .= "\n" . pht('Other locations: %s', implode(', ', $locations)); } $text[] = phutil_console_format(" **<bg:{$color}> %s </bg>** (%s) __%s__\n%s\n", $severity, $code, $name, phutil_console_wrap($description, 4)); if ($message->hasFileContext()) { $text[] = $this->renderContext($message, $lines); } } if ($text) { $prefix = phutil_console_format("**>>>** %s\n\n\n", pht('Lint for %s:', phutil_console_format('__%s__', $path))); return $prefix . implode("\n", $text); } else { return null; } }
protected function processDiffusionRequest(AphrontRequest $request) { $user = $request->getUser(); $drequest = $this->diffusionRequest; if ($request->getStr('lint') !== null) { $controller = new DiffusionLintDetailsController(); $controller->setDiffusionRequest($drequest); $controller->setCurrentApplication($this->getCurrentApplication()); return $this->delegateToController($controller); } $owners = array(); if (!$drequest) { if (!$request->getArr('owner')) { $owners = array($user->getPHID()); } else { $owners = array(head($request->getArr('owner'))); } } $codes = $this->loadLintCodes($owners); if ($codes && !$drequest) { // TODO: Build some real Query classes for this stuff. $branches = id(new PhabricatorRepositoryBranch())->loadAllWhere('id IN (%Ld)', array_unique(ipull($codes, 'branchID'))); $repositories = id(new PhabricatorRepositoryQuery())->setViewer($user)->withIDs(mpull($branches, 'getRepositoryID'))->execute(); $drequests = array(); foreach ($branches as $id => $branch) { if (empty($repositories[$branch->getRepositoryID()])) { continue; } $drequests[$id] = DiffusionRequest::newFromDictionary(array('user' => $user, 'repository' => $repositories[$branch->getRepositoryID()], 'branch' => $branch->getName())); } } $rows = array(); $total = 0; foreach ($codes as $code) { if (!$this->diffusionRequest) { $drequest = idx($drequests, $code['branchID']); } if (!$drequest) { continue; } $total += $code['n']; $href_lint = $drequest->generateURI(array('action' => 'lint', 'lint' => $code['code'])); $href_browse = $drequest->generateURI(array('action' => 'browse', 'lint' => $code['code'])); $href_repo = $drequest->generateURI(array('action' => 'lint')); $rows[] = array(phutil_tag('a', array('href' => $href_lint), $code['n']), phutil_tag('a', array('href' => $href_browse), $code['files']), phutil_tag('a', array('href' => $href_repo), $drequest->getRepository()->getDisplayName()), ArcanistLintSeverity::getStringForSeverity($code['maxSeverity']), $code['code'], $code['maxName'], $code['maxDescription']); } $table = id(new AphrontTableView($rows))->setHeaders(array(pht('Problems'), pht('Files'), pht('Repository'), pht('Severity'), pht('Code'), pht('Name'), pht('Example')))->setColumnVisibility(array(true, true, !$this->diffusionRequest))->setColumnClasses(array('n', 'n', '', '', 'pri', '', '')); $content = array(); if (!$this->diffusionRequest) { $form = id(new AphrontFormView())->setUser($user)->setMethod('GET')->appendControl(id(new AphrontFormTokenizerControl())->setDatasource(new PhabricatorPeopleDatasource())->setLimit(1)->setName('owner')->setLabel(pht('Owner'))->setValue($owners))->appendChild(id(new AphrontFormSubmitControl())->setValue(pht('Filter'))); $content[] = id(new AphrontListFilterView())->appendChild($form); } $content[] = id(new PHUIObjectBoxView())->setHeaderText(pht('Lint'))->setTable($table); $title = array('Lint'); $crumbs = $this->buildCrumbs(array('branch' => true, 'path' => true, 'view' => 'lint')); if ($this->diffusionRequest) { $title[] = $drequest->getRepository()->getDisplayName(); } else { $crumbs->addTextCrumb(pht('All Lint')); } if ($this->diffusionRequest) { $branch = $drequest->loadBranch(); $header = id(new PHUIHeaderView())->setHeader($this->renderPathLinks($drequest, 'lint'))->setUser($user)->setPolicyObject($drequest->getRepository()); $actions = $this->buildActionView($drequest); $properties = $this->buildPropertyView($drequest, $branch, $total, $actions); $object_box = id(new PHUIObjectBoxView())->setHeader($header)->addPropertyList($properties); } else { $object_box = null; } return $this->buildApplicationPage(array($crumbs, $object_box, $content), array('title' => $title)); }
private function buildDisplayRows(array $lines, array $blame_list, array $blame_commits, $show_color, $show_blame) { $request = $this->getRequest(); $viewer = $this->getViewer(); $drequest = $this->getDiffusionRequest(); $repository = $drequest->getRepository(); $revision_map = array(); $revisions = array(); if ($blame_commits) { $commit_map = mpull($blame_commits, 'getCommitIdentifier', 'getPHID'); $revision_ids = id(new DifferentialRevision())->loadIDsByCommitPHIDs(array_keys($commit_map)); if ($revision_ids) { $revisions = id(new DifferentialRevisionQuery())->setViewer($viewer)->withIDs($revision_ids)->execute(); $revisions = mpull($revisions, null, 'getID'); } foreach ($revision_ids as $commit_phid => $revision_id) { $revision_map[$commit_map[$commit_phid]] = $revision_id; } } $phids = array(); foreach ($blame_commits as $commit) { $author_phid = $commit->getAuthorPHID(); if ($author_phid === null) { continue; } $phids[$author_phid] = $author_phid; } foreach ($revisions as $revision) { $author_phid = $revision->getAuthorPHID(); if ($author_phid === null) { continue; } $phids[$author_phid] = $author_phid; } $handles = $viewer->loadHandles($phids); $colors = array(); if ($blame_commits) { $epochs = array(); foreach ($blame_commits as $identifier => $commit) { $epochs[$identifier] = $commit->getEpoch(); } $epoch_list = array_filter($epochs); $epoch_list = array_unique($epoch_list); $epoch_list = array_values($epoch_list); $epoch_min = min($epoch_list); $epoch_max = max($epoch_list); $epoch_range = $epoch_max - $epoch_min + 1; foreach ($blame_commits as $identifier => $commit) { $epoch = $epochs[$identifier]; if (!$epoch) { $color = '#ffffdd'; // Warning color, missing data. } else { $color_ratio = ($epoch - $epoch_min) / $epoch_range; $color_value = 0xe6 * (1.0 - $color_ratio); $color = sprintf('#%02x%02x%02x', $color_value, 0xf6, $color_value); } $colors[$identifier] = $color; } } $display = array(); $last_identifier = null; $last_color = null; foreach ($lines as $line_index => $line) { $color = '#f6f6f6'; $duplicate = false; if (isset($blame_list[$line_index])) { $identifier = $blame_list[$line_index]; if (isset($colors[$identifier])) { $color = $colors[$identifier]; } if ($identifier === $last_identifier) { $duplicate = true; } else { $last_identifier = $identifier; } } $display[$line_index] = array('data' => $line, 'target' => false, 'highlighted' => false, 'color' => $color, 'duplicate' => $duplicate); } $line_arr = array(); $line_str = $drequest->getLine(); $ranges = explode(',', $line_str); foreach ($ranges as $range) { if (strpos($range, '-') !== false) { list($min, $max) = explode('-', $range, 2); $line_arr[] = array('min' => min($min, $max), 'max' => max($min, $max)); } else { if (strlen($range)) { $line_arr[] = array('min' => $range, 'max' => $range); } } } // Mark the first highlighted line as the target line. if ($line_arr) { $target_line = $line_arr[0]['min']; if (isset($display[$target_line - 1])) { $display[$target_line - 1]['target'] = true; } } // Mark all other highlighted lines as highlighted. foreach ($line_arr as $range) { for ($ii = $range['min']; $ii <= $range['max']; $ii++) { if (isset($display[$ii - 1])) { $display[$ii - 1]['highlighted'] = true; } } } $engine = null; $inlines = array(); if ($this->getRequest()->getStr('lint') !== null && $this->lintMessages) { $engine = new PhabricatorMarkupEngine(); $engine->setViewer($viewer); foreach ($this->lintMessages as $message) { $inline = id(new PhabricatorAuditInlineComment())->setSyntheticAuthor(ArcanistLintSeverity::getStringForSeverity($message['severity']) . ' ' . $message['code'] . ' (' . $message['name'] . ')')->setLineNumber($message['line'])->setContent($message['description']); $inlines[$message['line']][] = $inline; $engine->addObject($inline, PhabricatorInlineCommentInterface::MARKUP_FIELD_BODY); } $engine->process(); require_celerity_resource('differential-changeset-view-css'); } $rows = $this->renderInlines(idx($inlines, 0, array()), $show_blame, (bool) $this->coverage, $engine); // NOTE: We're doing this manually because rendering is otherwise // dominated by URI generation for very large files. $line_base = (string) $drequest->generateURI(array('action' => 'browse', 'stable' => true)); require_celerity_resource('aphront-tooltip-css'); Javelin::initBehavior('phabricator-oncopy'); Javelin::initBehavior('phabricator-tooltips'); Javelin::initBehavior('phabricator-line-linker'); // Render these once, since they tend to get repeated many times in large // blame outputs. $commit_links = $this->renderCommitLinks($blame_commits, $handles); $revision_links = $this->renderRevisionLinks($revisions, $handles); $skip_text = pht('Skip Past This Commit'); foreach ($display as $line_index => $line) { $row = array(); $line_number = $line_index + 1; $line_href = $line_base . '$' . $line_number; if (isset($blame_list[$line_index])) { $identifier = $blame_list[$line_index]; } else { $identifier = null; } $revision_link = null; $commit_link = null; $before_link = null; $style = 'background: ' . $line['color'] . ';'; if ($identifier && !$line['duplicate']) { if (isset($commit_links[$identifier])) { $commit_link = $commit_links[$identifier]; } if (isset($revision_map[$identifier])) { $revision_id = $revision_map[$identifier]; if (isset($revision_links[$revision_id])) { $revision_link = $revision_links[$revision_id]; } } $skip_href = $line_href . '?before=' . $identifier . '&view=blame'; $before_link = javelin_tag('a', array('href' => $skip_href, 'sigil' => 'has-tooltip', 'meta' => array('tip' => $skip_text, 'align' => 'E', 'size' => 300)), "«"); } $row[] = phutil_tag('th', array('class' => 'diffusion-blame-link'), $before_link); $object_links = array(); $object_links[] = $commit_link; if ($revision_link) { $object_links[] = phutil_tag('span', array(), '/'); $object_links[] = $revision_link; } $row[] = phutil_tag('th', array('class' => 'diffusion-rev-link'), $object_links); $line_link = phutil_tag('a', array('href' => $line_href, 'style' => $style), $line_number); $row[] = javelin_tag('th', array('class' => 'diffusion-line-link', 'sigil' => 'phabricator-source-line', 'style' => $style), $line_link); if ($line['target']) { Javelin::initBehavior('diffusion-jump-to', array('target' => 'scroll_target')); $anchor_text = phutil_tag('a', array('id' => 'scroll_target'), ''); } else { $anchor_text = null; } $row[] = phutil_tag('td', array(), array($anchor_text, "", phutil_safe_html(str_replace("\t", ' ', $line['data'])))); if ($this->coverage) { require_celerity_resource('differential-changeset-view-css'); $cov_index = $line_index; if (isset($this->coverage[$cov_index])) { $cov_class = $this->coverage[$cov_index]; } else { $cov_class = 'N'; } $row[] = phutil_tag('td', array('class' => 'cov cov-' . $cov_class), ''); } $rows[] = phutil_tag('tr', array('class' => $line['highlighted'] ? 'phabricator-source-highlight' : null), $row); $cur_inlines = $this->renderInlines(idx($inlines, $line_number, array()), $show_blame, $this->coverage, $engine); foreach ($cur_inlines as $cur_inline) { $rows[] = $cur_inline; } } return $rows; }
private function buildDisplayRows(array $text_list, array $rev_list, array $blame_dict, $needs_blame, DiffusionRequest $drequest, $show_blame, $show_color) { $handles = array(); if ($blame_dict) { $epoch_list = ipull(ifilter($blame_dict, 'epoch'), 'epoch'); $epoch_min = min($epoch_list); $epoch_max = max($epoch_list); $epoch_range = $epoch_max - $epoch_min + 1; $author_phids = ipull(ifilter($blame_dict, 'authorPHID'), 'authorPHID'); $handles = $this->loadViewerHandles($author_phids); } $line_arr = array(); $line_str = $drequest->getLine(); $ranges = explode(',', $line_str); foreach ($ranges as $range) { if (strpos($range, '-') !== false) { list($min, $max) = explode('-', $range, 2); $line_arr[] = array('min' => min($min, $max), 'max' => max($min, $max)); } else { if (strlen($range)) { $line_arr[] = array('min' => $range, 'max' => $range); } } } $display = array(); $line_number = 1; $last_rev = null; $color = null; foreach ($text_list as $k => $line) { $display_line = array('epoch' => null, 'commit' => null, 'author' => null, 'target' => null, 'highlighted' => null, 'line' => $line_number, 'data' => $line); if ($show_blame) { // If the line's rev is same as the line above, show empty content // with same color; otherwise generate blame info. The newer a change // is, the more saturated the color. $rev = idx($rev_list, $k, $last_rev); if ($last_rev == $rev) { $display_line['color'] = $color; } else { $blame = $blame_dict[$rev]; if (!isset($blame['epoch'])) { $color = '#ffd'; // Render as warning. } else { $color_ratio = ($blame['epoch'] - $epoch_min) / $epoch_range; $color_value = 0xe6 * (1.0 - $color_ratio); $color = sprintf('#%02x%02x%02x', $color_value, 0xf6, $color_value); } $display_line['epoch'] = idx($blame, 'epoch'); $display_line['color'] = $color; $display_line['commit'] = $rev; $author_phid = idx($blame, 'authorPHID'); if ($author_phid && $handles[$author_phid]) { $author_link = $handles[$author_phid]->renderLink(); } else { $author_link = $blame['author']; } $display_line['author'] = $author_link; $last_rev = $rev; } } if ($line_arr) { if ($line_number == $line_arr[0]['min']) { $display_line['target'] = true; } foreach ($line_arr as $range) { if ($line_number >= $range['min'] && $line_number <= $range['max']) { $display_line['highlighted'] = true; } } } $display[] = $display_line; ++$line_number; } $request = $this->getRequest(); $viewer = $request->getUser(); $commits = array_filter(ipull($display, 'commit')); if ($commits) { $commits = id(new DiffusionCommitQuery())->setViewer($viewer)->withRepository($drequest->getRepository())->withIdentifiers($commits)->execute(); $commits = mpull($commits, null, 'getCommitIdentifier'); } $revision_ids = id(new DifferentialRevision())->loadIDsByCommitPHIDs(mpull($commits, 'getPHID')); $revisions = array(); if ($revision_ids) { $revisions = id(new DifferentialRevisionQuery())->setViewer($viewer)->withIDs($revision_ids)->execute(); } $phids = array(); foreach ($commits as $commit) { if ($commit->getAuthorPHID()) { $phids[] = $commit->getAuthorPHID(); } } foreach ($revisions as $revision) { if ($revision->getAuthorPHID()) { $phids[] = $revision->getAuthorPHID(); } } $handles = $this->loadViewerHandles($phids); Javelin::initBehavior('phabricator-oncopy', array()); $engine = null; $inlines = array(); if ($this->getRequest()->getStr('lint') !== null && $this->lintMessages) { $engine = new PhabricatorMarkupEngine(); $engine->setViewer($viewer); foreach ($this->lintMessages as $message) { $inline = id(new PhabricatorAuditInlineComment())->setSyntheticAuthor(ArcanistLintSeverity::getStringForSeverity($message['severity']) . ' ' . $message['code'] . ' (' . $message['name'] . ')')->setLineNumber($message['line'])->setContent($message['description']); $inlines[$message['line']][] = $inline; $engine->addObject($inline, PhabricatorInlineCommentInterface::MARKUP_FIELD_BODY); } $engine->process(); require_celerity_resource('differential-changeset-view-css'); } $rows = $this->renderInlines(idx($inlines, 0, array()), $show_blame, (bool) $this->coverage, $engine); foreach ($display as $line) { $line_href = $drequest->generateURI(array('action' => 'browse', 'line' => $line['line'], 'stable' => true)); $blame = array(); $style = null; if (array_key_exists('color', $line)) { if ($line['color']) { $style = 'background: ' . $line['color'] . ';'; } $before_link = null; $commit_link = null; $revision_link = null; if (idx($line, 'commit')) { $commit = $line['commit']; if (idx($commits, $commit)) { $tooltip = $this->renderCommitTooltip($commits[$commit], $handles, $line['author']); } else { $tooltip = null; } Javelin::initBehavior('phabricator-tooltips', array()); require_celerity_resource('aphront-tooltip-css'); $commit_link = javelin_tag('a', array('href' => $drequest->generateURI(array('action' => 'commit', 'commit' => $line['commit'])), 'sigil' => 'has-tooltip', 'meta' => array('tip' => $tooltip, 'align' => 'E', 'size' => 600)), id(new PhutilUTF8StringTruncator())->setMaximumGlyphs(9)->setTerminator('')->truncateString($line['commit'])); $revision_id = null; if (idx($commits, $commit)) { $revision_id = idx($revision_ids, $commits[$commit]->getPHID()); } if ($revision_id) { $revision = idx($revisions, $revision_id); if ($revision) { $tooltip = $this->renderRevisionTooltip($revision, $handles); $revision_link = javelin_tag('a', array('href' => '/D' . $revision->getID(), 'sigil' => 'has-tooltip', 'meta' => array('tip' => $tooltip, 'align' => 'E', 'size' => 600)), 'D' . $revision->getID()); } } $uri = $line_href->alter('before', $commit); $before_link = javelin_tag('a', array('href' => $uri->setQueryParam('view', 'blame'), 'sigil' => 'has-tooltip', 'meta' => array('tip' => pht('Skip Past This Commit'), 'align' => 'E', 'size' => 300)), "«"); } $blame[] = phutil_tag('th', array('class' => 'diffusion-blame-link'), $before_link); $object_links = array(); $object_links[] = $commit_link; if ($revision_link) { $object_links[] = phutil_tag('span', array(), '/'); $object_links[] = $revision_link; } $blame[] = phutil_tag('th', array('class' => 'diffusion-rev-link'), $object_links); } $line_link = phutil_tag('a', array('href' => $line_href, 'style' => $style), $line['line']); $blame[] = javelin_tag('th', array('class' => 'diffusion-line-link', 'sigil' => 'phabricator-source-line', 'style' => $style), $line_link); Javelin::initBehavior('phabricator-line-linker'); if ($line['target']) { Javelin::initBehavior('diffusion-jump-to', array('target' => 'scroll_target')); $anchor_text = phutil_tag('a', array('id' => 'scroll_target'), ''); } else { $anchor_text = null; } $blame[] = phutil_tag('td', array(), array($anchor_text, "", phutil_safe_html(str_replace("\t", ' ', $line['data'])))); if ($this->coverage) { require_celerity_resource('differential-changeset-view-css'); $cov_index = $line['line'] - 1; if (isset($this->coverage[$cov_index])) { $cov_class = $this->coverage[$cov_index]; } else { $cov_class = 'N'; } $blame[] = phutil_tag('td', array('class' => 'cov cov-' . $cov_class), ''); } $rows[] = phutil_tag('tr', array('class' => $line['highlighted'] ? 'phabricator-source-highlight' : null), $blame); $cur_inlines = $this->renderInlines(idx($inlines, $line['line'], array()), $show_blame, $this->coverage, $engine); foreach ($cur_inlines as $cur_inline) { $rows[] = $cur_inline; } } return $rows; }
private function buildDetailsResponse() { $request = $this->getRequest(); $limit = 500; $pager = id(new PHUIPagerView())->readFromRequest($request)->setPageSize($limit); $offset = $pager->getOffset(); $drequest = $this->getDiffusionRequest(); $branch = $drequest->loadBranch(); $messages = $this->loadLintMessages($branch, $limit, $offset); $is_dir = substr('/' . $drequest->getPath(), -1) == '/'; $pager->setHasMorePages(count($messages) >= $limit); $authors = $this->loadViewerHandles(ipull($messages, 'authorPHID')); $rows = array(); foreach ($messages as $message) { $path = phutil_tag('a', array('href' => $drequest->generateURI(array('action' => 'lint', 'path' => $message['path']))), substr($message['path'], strlen($drequest->getPath()) + 1)); $line = phutil_tag('a', array('href' => $drequest->generateURI(array('action' => 'browse', 'path' => $message['path'], 'line' => $message['line'], 'commit' => $branch->getLintCommit()))), $message['line']); $author = $message['authorPHID']; if ($author && $authors[$author]) { $author = $authors[$author]->renderLink(); } $rows[] = array($path, $line, $author, ArcanistLintSeverity::getStringForSeverity($message['severity']), $message['name'], $message['description']); } $table = id(new AphrontTableView($rows))->setHeaders(array(pht('Path'), pht('Line'), pht('Author'), pht('Severity'), pht('Name'), pht('Description')))->setColumnClasses(array('', 'n'))->setColumnVisibility(array($is_dir)); $content = array(); $content[] = id(new PHUIObjectBoxView())->setHeaderText(pht('Lint Details'))->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)->setTable($table); $crumbs = $this->buildCrumbs(array('branch' => true, 'path' => true, 'view' => 'lint')); $pager_box = $this->renderTablePagerBox($pager); $header = id(new PHUIHeaderView())->setHeader(pht('Lint: %s', $drequest->getRepository()->getDisplayName()))->setHeaderIcon('fa-code'); $view = id(new PHUITwoColumnView())->setHeader($header)->setFooter(array($content, $pager_box)); return $this->newPage()->setTitle(array(pht('Lint'), $drequest->getRepository()->getDisplayName()))->setCrumbs($crumbs)->appendChild(array($view)); }