Differential D15287 Diff 36882 src/applications/diffusion/controller/DiffusionLastModifiedController.php
Changeset View
Changeset View
Standalone View
Standalone View
src/applications/diffusion/controller/DiffusionLastModifiedController.php
Show First 20 Lines • Show All 65 Lines • ▼ Show 20 Lines | if ($branch && $commits) { | ||||
->withBranchIDs(array($branch->getID())) | ->withBranchIDs(array($branch->getID())) | ||||
->withPaths(array_keys($commits)); | ->withPaths(array_keys($commits)); | ||||
if ($drequest->getLint()) { | if ($drequest->getLint()) { | ||||
$lint_query->withCodes(array($drequest->getLint())); | $lint_query->withCodes(array($drequest->getLint())); | ||||
} | } | ||||
$lint = $lint_query->execute(); | $lint = $lint_query->execute(); | ||||
$coverage = $this->loadCoverageForPaths($branch, array_keys($commits)); | |||||
} else { | } else { | ||||
$lint = array(); | $lint = array(); | ||||
$coverage = array(); | |||||
} | } | ||||
$output = array(); | $output = array(); | ||||
foreach ($commits as $path => $commit) { | foreach ($commits as $path => $commit) { | ||||
$prequest = clone $drequest; | $prequest = clone $drequest; | ||||
$prequest->setPath($path); | $prequest->setPath($path); | ||||
$output[$path] = $this->renderColumns( | $output[$path] = $this->renderColumns( | ||||
$prequest, | $prequest, | ||||
$handles, | $handles, | ||||
$commit, | $commit, | ||||
idx($lint, $path)); | idx($lint, $path), | ||||
idx($coverage, $path)); | |||||
} | } | ||||
return id(new AphrontAjaxResponse())->setContent($output); | return id(new AphrontAjaxResponse())->setContent($output); | ||||
} | } | ||||
private function renderColumns( | private function renderColumns( | ||||
DiffusionRequest $drequest, | DiffusionRequest $drequest, | ||||
array $handles, | array $handles, | ||||
PhabricatorRepositoryCommit $commit = null, | PhabricatorRepositoryCommit $commit = null, | ||||
$lint = null) { | $lint = null, | ||||
$coverage = null) { | |||||
assert_instances_of($handles, 'PhabricatorObjectHandle'); | assert_instances_of($handles, 'PhabricatorObjectHandle'); | ||||
$viewer = $this->getRequest()->getUser(); | $viewer = $this->getRequest()->getUser(); | ||||
if ($commit) { | if ($commit) { | ||||
$epoch = $commit->getEpoch(); | $epoch = $commit->getEpoch(); | ||||
$modified = DiffusionView::linkCommit( | $modified = DiffusionView::linkCommit( | ||||
$drequest->getRepository(), | $drequest->getRepository(), | ||||
$commit->getCommitIdentifier()); | $commit->getCommitIdentifier()); | ||||
▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | if ($lint !== null) { | ||||
'href' => $drequest->generateURI(array( | 'href' => $drequest->generateURI(array( | ||||
'action' => 'lint', | 'action' => 'lint', | ||||
'lint' => null, | 'lint' => null, | ||||
)), | )), | ||||
), | ), | ||||
number_format($lint)); | number_format($lint)); | ||||
} | } | ||||
if ($coverage !== null) { | |||||
$return['coverage'] = $coverage; | |||||
} | |||||
// The client treats these results as markup, so make sure they have been | // The client treats these results as markup, so make sure they have been | ||||
// escaped correctly. | // escaped correctly. | ||||
foreach ($return as $key => $value) { | foreach ($return as $key => $value) { | ||||
$return[$key] = hsprintf('%s', $value); | $return[$key] = hsprintf('%s', $value); | ||||
} | } | ||||
return $return; | return $return; | ||||
} | } | ||||
private function loadCoverageForPaths($branch, array $paths) { | |||||
if (!$paths) { | |||||
return array(); | |||||
} | |||||
$drequest = $this->getDiffusionRequest(); | |||||
$commit = $drequest->loadCommit(); | |||||
$path_map = id(new DiffusionPathIDQuery($paths)) | |||||
->loadPathIDs(); | |||||
$path_map = array_flip($path_map); | |||||
$coverage_rows = queryfx_all( | |||||
id(new PhabricatorRepository())->establishConnection('r'), | |||||
'SELECT * FROM %T | |||||
WHERE branchID = %d | |||||
AND pathID IN (%Ld) | |||||
AND commitID = %d', | |||||
PhabricatorRepository::TABLE_COVERAGE, | |||||
$branch->getID(), | |||||
array_keys($path_map), | |||||
$commit->getID()); | |||||
$coverage_map = array(); | |||||
foreach ($coverage_rows as $coverage_row) { | |||||
if (empty($path_map[$coverage_row['pathID']])) { | |||||
continue; | |||||
} | |||||
$covered_path = $path_map[$coverage_row['pathID']]; | |||||
$coverage_map[$covered_path] = $coverage_row['coverage']; | |||||
} | |||||
if (!$coverage_map) { | |||||
return array(); | |||||
} | |||||
$maximum = 0; | |||||
$grand_total = 0; | |||||
foreach ($coverage_map as $path => $coverage) { | |||||
$stats = $this->getCoverageStatistics($coverage); | |||||
$maximum = max($maximum, $stats['U'] + $stats['C']); | |||||
$grand_total += $stats['U'] + $stats['C']; | |||||
$coverage_map[$path] = $stats; | |||||
} | |||||
$log_base = 3; | |||||
$log_maximum = log($maximum + 1, $log_base); | |||||
$coverage_bars = array(); | |||||
foreach ($coverage_map as $path => $stats) { | |||||
$total = $stats['U'] + $stats['C']; | |||||
$log_total = log($total + 1, $log_base); | |||||
$bar_size = $log_total / $log_maximum; | |||||
$bar_full = $stats['C'] / $total; | |||||
$tip = pht( | |||||
"%s / %s Lines\n%s of Total Lines\n%s Covered", | |||||
new PhutilNumber($stats['C']), | |||||
new PhutilNumber($total), | |||||
sprintf('%.1f%%', 100 * ($total / $grand_total)), | |||||
sprintf('%.1f%%', 100 * $bar_full)); | |||||
$bar = new PHUISegmentBarView(); | |||||
$bar->newSegment() | |||||
->setWidth($bar_full) | |||||
->setColor('blue'); | |||||
$coverage_bars[$path] = javelin_tag( | |||||
'div', | |||||
array( | |||||
'class' => 'diffusion-coverage', | |||||
'style' => sprintf('width: %.2f%%', 100 * $bar_size), | |||||
'sigil' => 'has-tooltip', | |||||
'meta' => array( | |||||
'tip' => $tip, | |||||
'align' => 'E', | |||||
'size' => 300, | |||||
), | |||||
), | |||||
$bar); | |||||
} | |||||
return $coverage_bars; | |||||
} | |||||
private function getCoverageStatistics($coverage) { | |||||
$defaults = array( | |||||
'U' => 0, | |||||
'C' => 0, | |||||
); | |||||
// If this is JSON-encoded aggregate data, we're just going to decode it. | |||||
if (!strncmp($coverage, '+J', 2)) { | |||||
$stats = phutil_json_decode(substr($coverage, 2)); | |||||
return $stats + $defaults; | |||||
} | |||||
// Otherwise, count the lines. | |||||
$map = array(); | |||||
foreach ($defaults as $char => $count) { | |||||
$map[$char] = substr_count($coverage, $char); | |||||
} | |||||
return $map; | |||||
} | |||||
} | } |