diff --git a/src/applications/diffusion/conduit/DiffusionUpdateCoverageConduitAPIMethod.php b/src/applications/diffusion/conduit/DiffusionUpdateCoverageConduitAPIMethod.php --- a/src/applications/diffusion/conduit/DiffusionUpdateCoverageConduitAPIMethod.php +++ b/src/applications/diffusion/conduit/DiffusionUpdateCoverageConduitAPIMethod.php @@ -70,6 +70,7 @@ $conn = $repository->establishConnection('w'); $sql = array(); + $dir_info = array(); foreach ($coverage as $path => $coverage_info) { $sql[] = qsprintf( $conn, @@ -78,6 +79,34 @@ $path_map[$path], $commit->getID(), $coverage_info); + + // add the coverage info for this file to the aggregate coverage info for + // all of its parent directories + $normal_path = DiffusionPathIDQuery::normalizePath($path); + $path_parts = explode('/', $normal_path); + array_pop($path_parts); + $dir = ''; + foreach ($path_parts as $part) { + $dir .= '/'.$part; + if (isset($dir_info[$dir])) { + $dir_info[$dir] .= $coverage_info; + } else { + $dir_info[$dir] = $coverage_info; + } + } + } + + $dir_map = id(new DiffusionPathIDQuery(array_keys($dir_info))) + ->loadPathIDs(); + + foreach ($dir_info as $dir => $coverage_info) { + $sql[] = qsprintf( + $conn, + '(%d, %d, %d, %s)', + $branch->getID(), + $dir_map[$dir], + $commit->getID(), + $coverage_info); } $table_name = 'repository_coverage'; diff --git a/src/applications/diffusion/controller/DiffusionLastModifiedController.php b/src/applications/diffusion/controller/DiffusionLastModifiedController.php --- a/src/applications/diffusion/controller/DiffusionLastModifiedController.php +++ b/src/applications/diffusion/controller/DiffusionLastModifiedController.php @@ -66,8 +66,50 @@ } $lint = $lint_query->execute(); + + $paths = array_keys($commits); + $path_map = id(new DiffusionPathIDQuery($paths))->loadPathIDs(); + + $commit_id = $drequest->loadCommit()->getID(); + $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(), + $path_map, + $commit_id); + $coverage = array(); + $path_map = array_flip($path_map); + $largest_dir = 0; + $files_total = 0; + foreach ($coverage_rows as $coverage_row) { + $covered_path = $path_map[$coverage_row['pathID']]; + $report = $coverage_row['coverage']; + $cov = substr_count($report, 'C'); + $uncov = substr_count($report, 'U'); + $is_dir = substr($covered_path, strlen($covered_path) - 1, 1) === '/'; + $coverage[$covered_path] = array( + 'cov' => $cov, + 'uncov' => $uncov, + 'is_dir' => $is_dir, + ); + $total = $cov + $uncov; + if ($total > $largest_dir && $is_dir) { + $largest = $total; + } else if (!$is_dir) { + $files_total += $total; + } + } + foreach ($coverage as $covered_path => $coverage_info) { + $coverage[$covered_path]['largest_dir'] = $largest_dir; + $coverage[$covered_path]['files_total'] = $files_total; + } } else { $lint = array(); + $coverage = array(); } $output = array(); @@ -79,7 +121,8 @@ $prequest, $handles, $commit, - idx($lint, $path)); + idx($lint, $path), + idx($coverage, $path)); } return id(new AphrontAjaxResponse())->setContent($output); @@ -89,7 +132,8 @@ DiffusionRequest $drequest, array $handles, PhabricatorRepositoryCommit $commit = null, - $lint = null) { + $lint = null, + $coverage = null) { assert_instances_of($handles, 'PhabricatorObjectHandle'); $viewer = $this->getRequest()->getUser(); @@ -151,6 +195,23 @@ number_format($lint)); } + if ($coverage !== null) { + $cov = $coverage['cov']; + $uncov = $coverage['uncov']; + $total = $cov + $uncov; + $largest = $coverage['largest']; + if ($total) { + $percentage = $cov / ($cov + $uncov); + } else { + $percentage = 0; + } + $width = ($total / $largest) * 100; + $percentage = (int)(100 * $percentage); + $percentage_display = sprintf('% 3d', $percentage); + $return['coverage'] = id(new AphrontProgressBarView()) + ->setAlt(hsprintf('%d%%', $percentage_display)); + } + // The client treats these results as markup, so make sure they have been // escaped correctly. foreach ($return as $key => $value) { diff --git a/src/applications/diffusion/view/DiffusionBrowseTableView.php b/src/applications/diffusion/view/DiffusionBrowseTableView.php --- a/src/applications/diffusion/view/DiffusionBrowseTableView.php +++ b/src/applications/diffusion/view/DiffusionBrowseTableView.php @@ -74,6 +74,7 @@ $dict = array( 'lint' => celerity_generate_unique_node_id(), + 'coverage' => celerity_generate_unique_node_id(), 'commit' => celerity_generate_unique_node_id(), 'date' => celerity_generate_unique_node_id(), 'author' => celerity_generate_unique_node_id(), @@ -89,6 +90,7 @@ $history_link, $browse_link, idx($dict, 'lint'), + $dict['coverage'], $dict['commit'], $dict['author'], $dict['details'], @@ -112,6 +114,7 @@ $branch = $this->getDiffusionRequest()->loadBranch(); $show_lint = ($branch && $branch->getLintCommit()); $lint = $request->getLint(); + $show_coverage = $this->getDiffusionRequest()->loadCoverage(); $view = new AphrontTableView($rows); $view->setHeaders( @@ -119,6 +122,7 @@ null, pht('Path'), ($lint ? $lint : pht('Lint')), + pht('Coverage'), pht('Modified'), pht('Author/Committer'), pht('Details'), @@ -131,6 +135,7 @@ '', '', '', + '', 'wide', '', )); @@ -139,6 +144,7 @@ true, true, $show_lint, + $show_coverage, true, true, true, @@ -150,6 +156,7 @@ true, true, false, + false, true, false, true,