Page MenuHomePhabricator

D14803.diff
No OneTemporary

D14803.diff

diff --git a/resources/celerity/map.php b/resources/celerity/map.php
--- a/resources/celerity/map.php
+++ b/resources/celerity/map.php
@@ -16,7 +16,7 @@
'diffusion.pkg.js' => '3a9a8bfa',
'maniphest.pkg.css' => '4845691a',
'maniphest.pkg.js' => '949a7498',
- 'rsrc/css/aphront/aphront-bars.css' => '231ac33c',
+ 'rsrc/css/aphront/aphront-bars.css' => '9ce6a9a2',
'rsrc/css/aphront/dark-console.css' => '6378ef3d',
'rsrc/css/aphront/dialog-view.css' => 'be0e3a46',
'rsrc/css/aphront/lightbox-attachment.css' => '7acac05d',
@@ -510,7 +510,7 @@
),
'symbols' => array(
'almanac-css' => 'dbb9b3af',
- 'aphront-bars' => '231ac33c',
+ 'aphront-bars' => '9ce6a9a2',
'aphront-dark-console-css' => '6378ef3d',
'aphront-dialog-view-css' => 'be0e3a46',
'aphront-list-filter-view-css' => '5d6f0526',
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
@@ -584,6 +584,7 @@
'DiffusionCommitTagsController' => 'applications/diffusion/controller/DiffusionCommitTagsController.php',
'DiffusionConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionConduitAPIMethod.php',
'DiffusionController' => 'applications/diffusion/controller/DiffusionController.php',
+ 'DiffusionCoverageBarView' => 'applications/diffusion/view/DiffusionCoverageBarView.php',
'DiffusionCreateCommentConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionCreateCommentConduitAPIMethod.php',
'DiffusionCreateRepositoriesCapability' => 'applications/diffusion/capability/DiffusionCreateRepositoriesCapability.php',
'DiffusionDefaultEditCapability' => 'applications/diffusion/capability/DiffusionDefaultEditCapability.php',
@@ -4607,6 +4608,7 @@
'DiffusionCommitTagsController' => 'DiffusionController',
'DiffusionConduitAPIMethod' => 'ConduitAPIMethod',
'DiffusionController' => 'PhabricatorController',
+ 'DiffusionCoverageBarView' => 'AphrontBarView',
'DiffusionCreateCommentConduitAPIMethod' => 'DiffusionConduitAPIMethod',
'DiffusionCreateRepositoriesCapability' => 'PhabricatorPolicyCapability',
'DiffusionDefaultEditCapability' => 'PhabricatorPolicyCapability',
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
@@ -71,8 +71,44 @@
}
$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);
+ 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');
+ $total = $cov + $uncov;
+ $is_dir = substr($covered_path, strlen($covered_path) - 1, 1) === '/';
+ $coverage[$covered_path] = array(
+ 'cov' => $cov,
+ 'uncov' => $uncov,
+ 'total' => $total,
+ 'is_dir' => $is_dir,
+ );
+ }
+ $largest = max(ipull($coverage, 'total'));
+ foreach ($coverage as $covered_path => $coverage_info) {
+ $coverage[$covered_path]['largest'] = $largest;
+ }
} else {
$lint = array();
+ $coverage = array();
}
$output = array();
@@ -84,7 +120,8 @@
$prequest,
$handles,
$commit,
- idx($lint, $path));
+ idx($lint, $path),
+ idx($coverage, $path));
}
return id(new AphrontAjaxResponse())->setContent($output);
@@ -94,7 +131,8 @@
DiffusionRequest $drequest,
array $handles,
PhabricatorRepositoryCommit $commit = null,
- $lint = null) {
+ $lint = null,
+ $coverage = null) {
assert_instances_of($handles, 'PhabricatorObjectHandle');
$viewer = $this->getRequest()->getUser();
@@ -156,6 +194,14 @@
number_format($lint));
}
+ if ($coverage !== null) {
+ $return['coverage'] = id(new DiffusionCoverageBarView())
+ ->setIsDirectory($coverage['is_dir'])
+ ->setCovered($coverage['cov'])
+ ->setUncovered($coverage['uncov'])
+ ->setLargestNeighbor($coverage['largest']);
+ }
+
// 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,
diff --git a/src/applications/diffusion/view/DiffusionCoverageBarView.php b/src/applications/diffusion/view/DiffusionCoverageBarView.php
new file mode 100644
--- /dev/null
+++ b/src/applications/diffusion/view/DiffusionCoverageBarView.php
@@ -0,0 +1,83 @@
+<?php
+
+final class DiffusionCoverageBarView extends AphrontBarView {
+
+ const MAX_WIDTH = 200;
+ const LOG_SCALE = 3;
+
+ private $isDirectory;
+ private $covered;
+ private $uncovered;
+ private $largestNeighbor;
+
+ protected function getDefaultColor() {
+ return parent::COLOR_AUTO_GOODNESS;
+ }
+
+ public function setIsDirectory($is_dir) {
+ $this->isDirectory = $is_dir;
+ return $this;
+ }
+
+ public function setCovered($covered) {
+ $this->covered = $covered;
+ return $this;
+ }
+
+ public function setUncovered($uncovered) {
+ $this->uncovered = $uncovered;
+ return $this;
+ }
+
+ public function setLargestNeighbor($largest_neighbor) {
+ $this->largestNeighbor = $largest_neighbor;
+ return $this;
+ }
+
+ protected function getTotal() {
+ return $this->covered + $this->uncovered;
+ }
+
+ protected function getRatio() {
+ return min($this->covered, $this->getTotal()) / $this->getTotal();
+ }
+
+ public function render() {
+ $this->initBehavior('phabricator-tooltips');
+ require_celerity_resource('aphront-tooltip-css');
+ require_celerity_resource('aphront-bars');
+ $scaled_total = log($this->getTotal() + 1, self::LOG_SCALE);
+ $scaled_maximum = log($this->largestNeighbor + 1, self::LOG_SCALE);
+ $bar_ratio = $scaled_total / $scaled_maximum;
+ $max_width = self::MAX_WIDTH;
+ $bar_width = $max_width * $bar_ratio;
+ $progress_width = $bar_width * $this->getRatio();
+ $tooltip = hsprintf(
+ '%s/%s (%s%%)',
+ number_format($this->covered),
+ number_format($this->getTotal()),
+ sprintf('% 3d', 100 * $this->getRatio()));
+
+ $color = $this->getColor();
+
+ return javelin_tag(
+ 'div',
+ array(
+ 'class' => "aphront-bar coverage color-{$color}",
+ 'sigil' => 'has-tooltip',
+ 'meta' => array('tip' => $tooltip),
+ ),
+ array(
+ phutil_tag(
+ 'div',
+ array(
+ 'style' => "width: {$bar_width}px;",
+ ),
+ phutil_tag(
+ 'div',
+ array('style' => "width: {$progress_width}px;"),
+ '')),
+ ));
+ }
+
+}
diff --git a/webroot/rsrc/css/aphront/aphront-bars.css b/webroot/rsrc/css/aphront/aphront-bars.css
--- a/webroot/rsrc/css/aphront/aphront-bars.css
+++ b/webroot/rsrc/css/aphront/aphront-bars.css
@@ -71,6 +71,28 @@
color: {$greytext};
}
+/**
+ * Coverage bars
+ */
+
+div.aphront-bar.coverage {
+ border: 0px;
+ width: 200px;
+ height: 20px;
+}
+
+div.aphront-bar.coverage div {
+ border: 1px solid;
+ border-top-color: {$lightgreyborder};
+ border-right-color: {$lightgreyborder};
+ border-bottom-color: {$lightgreyborder};
+ border-left-color: {$greyborder};
+ background: white;
+}
+
+div.aphront-bar.coverage div div {
+ height: 16px;
+}
/**
* Common color classes
@@ -83,6 +105,10 @@
color: {$blue};
}
+div.aphront-bar.coverage.color-default div div {
+ background: {$blue};
+}
+
div.aphront-bar.progress.color-warning div div {
background: {$yellow};
}
@@ -91,6 +117,10 @@
color: {$yellow};
}
+div.aphront-bar.coverage.color-warning div div {
+ background: {$yellow};
+}
+
div.aphront-bar.progress.color-danger div div {
background: {$red};
}
@@ -98,3 +128,7 @@
div.aphront-bar.glyph.color-danger div.glyphs div.fg {
color: {$red};
}
+
+div.aphront-bar.coverage.color-danger div div {
+ background: {$red};
+}

File Metadata

Mime Type
text/plain
Expires
Thu, Mar 20, 5:23 AM (2 d, 19 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7678705
Default Alt Text
D14803.diff (11 KB)

Event Timeline