@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Restore coverage reporting to Diffusion browse UI

Summary:
Depends on D19377. Ref T13125. Ref T13124. Ref T13105. Coverage reporting in Diffusion didn't initially survive the transition to Document Engine; restore it.

This adds some tentative/theoretical support for multiple columns of coverage, but no way to actually produce them in the UI. For now, the labels, codes, and colors are hard coded.

Test Plan:
Added coverage with `diffusion.updatecoverage`, saw coverage in the UI:

{F5525542}

Hovered over coverage, got labels and highlighting.

Double-checked labels for "N" (Not Executable) and "U" (Uncovered). See PHI577.

Faked some multi-column coverage, but you can't currently get this yourself today:

{F5525544}

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13125, T13124, T13105

Differential Revision: https://secure.phabricator.com/D19378

+159 -15
+9 -9
resources/celerity/map.php
··· 119 119 'rsrc/css/font/font-lato.css' => 'c7ccd872', 120 120 'rsrc/css/font/phui-font-icon-base.css' => '870a7360', 121 121 'rsrc/css/layout/phabricator-filetree-view.css' => 'b912ad97', 122 - 'rsrc/css/layout/phabricator-source-code-view.css' => '09368218', 122 + 'rsrc/css/layout/phabricator-source-code-view.css' => 'fdbefca0', 123 123 'rsrc/css/phui/button/phui-button-bar.css' => 'f1ff5494', 124 124 'rsrc/css/phui/button/phui-button-simple.css' => '8e1baf68', 125 125 'rsrc/css/phui/button/phui-button.css' => '1863cc6e', ··· 388 388 'rsrc/js/application/diffusion/behavior-pull-lastmodified.js' => 'f01586dc', 389 389 'rsrc/js/application/doorkeeper/behavior-doorkeeper-tag.js' => '1db13e70', 390 390 'rsrc/js/application/drydock/drydock-live-operation-status.js' => '901935ef', 391 - 'rsrc/js/application/files/behavior-document-engine.js' => '0333c0b6', 391 + 'rsrc/js/application/files/behavior-document-engine.js' => 'ee0deff8', 392 392 'rsrc/js/application/files/behavior-icon-composer.js' => '8499b6ab', 393 393 'rsrc/js/application/files/behavior-launch-icon-composer.js' => '48086888', 394 394 'rsrc/js/application/harbormaster/behavior-harbormaster-log.js' => '191b4909', ··· 600 600 'javelin-behavior-diffusion-commit-graph' => '75b83cbb', 601 601 'javelin-behavior-diffusion-locate-file' => '6d3e1947', 602 602 'javelin-behavior-diffusion-pull-lastmodified' => 'f01586dc', 603 - 'javelin-behavior-document-engine' => '0333c0b6', 603 + 'javelin-behavior-document-engine' => 'ee0deff8', 604 604 'javelin-behavior-doorkeeper-tag' => '1db13e70', 605 605 'javelin-behavior-drydock-live-operation-status' => '901935ef', 606 606 'javelin-behavior-durable-column' => '2ae077e1', ··· 776 776 'phabricator-search-results-css' => '505dd8cf', 777 777 'phabricator-shaped-request' => '7cbe244b', 778 778 'phabricator-slowvote-css' => 'a94b7230', 779 - 'phabricator-source-code-view-css' => '09368218', 779 + 'phabricator-source-code-view-css' => 'fdbefca0', 780 780 'phabricator-standard-page-view' => '34ee718b', 781 781 'phabricator-textareautils' => '320810c8', 782 782 'phabricator-title' => '485aaa6c', ··· 904 904 '0213259f' => array( 905 905 'javelin-behavior', 906 906 'javelin-uri', 907 - ), 908 - '0333c0b6' => array( 909 - 'javelin-behavior', 910 - 'javelin-dom', 911 - 'javelin-stratcom', 912 907 ), 913 908 '040fce04' => array( 914 909 'javelin-behavior', ··· 2109 2104 'edf8a145' => array( 2110 2105 'javelin-behavior', 2111 2106 'javelin-uri', 2107 + ), 2108 + 'ee0deff8' => array( 2109 + 'javelin-behavior', 2110 + 'javelin-dom', 2111 + 'javelin-stratcom', 2112 2112 ), 2113 2113 'efe49472' => array( 2114 2114 'javelin-install',
-2
src/applications/diffusion/controller/DiffusionBrowseController.php
··· 4 4 5 5 private $lintCommit; 6 6 private $lintMessages; 7 - private $coverage; 8 7 private $corpusButtons = array(); 9 8 10 9 public function shouldAllowPublic() { ··· 182 181 183 182 $corpus = $this->buildGitLFSCorpus($lfs_ref); 184 183 } else { 185 - $this->coverage = $drequest->loadCoverage(); 186 184 $show_editor = true; 187 185 188 186 $ref = id(new PhabricatorDocumentRef())
+5
src/applications/diffusion/document/DiffusionDocumentRenderingEngine.php
··· 81 81 $ref 82 82 ->setSymbolMetadata($this->getSymbolMetadata()) 83 83 ->setBlameURI($blame_uri); 84 + 85 + $coverage = $drequest->loadCoverage(); 86 + if (strlen($coverage)) { 87 + $ref->addCoverage($coverage); 88 + } 84 89 } 85 90 86 91 private function getSymbolMetadata() {
+12
src/applications/files/document/PhabricatorDocumentRef.php
··· 10 10 private $snippet; 11 11 private $symbolMetadata = array(); 12 12 private $blameURI; 13 + private $coverage = array(); 13 14 14 15 public function setFile(PhabricatorFile $file) { 15 16 $this->file = $file; ··· 149 150 150 151 public function getBlameURI() { 151 152 return $this->blameURI; 153 + } 154 + 155 + public function addCoverage($coverage) { 156 + $this->coverage[] = array( 157 + 'data' => $coverage, 158 + ); 159 + return $this; 160 + } 161 + 162 + public function getCoverage() { 163 + return $this->coverage; 152 164 } 153 165 154 166 }
+4
src/applications/files/document/PhabricatorSourceDocumentEngine.php
··· 57 57 $options['blame'] = $blame; 58 58 } 59 59 60 + if ($ref->getCoverage()) { 61 + $options['coverage'] = $ref->getCoverage(); 62 + } 63 + 60 64 return array( 61 65 $messages, 62 66 $this->newTextDocumentContent($ref, $content, $options),
+6
src/applications/files/document/PhabricatorTextDocumentEngine.php
··· 22 22 $options, 23 23 array( 24 24 'blame' => 'optional wild', 25 + 'coverage' => 'optional list<wild>', 25 26 )); 26 27 27 28 if (is_array($content)) { ··· 38 39 $blame = idx($options, 'blame'); 39 40 if ($blame !== null) { 40 41 $view->setBlameMap($blame); 42 + } 43 + 44 + $coverage = idx($options, 'coverage'); 45 + if ($coverage !== null) { 46 + $view->setCoverage($coverage); 41 47 } 42 48 43 49 $message = null;
+11
src/applications/files/document/render/PhabricatorDocumentRenderingEngine.php
··· 145 145 'uri' => $ref->getBlameURI(), 146 146 'value' => null, 147 147 ), 148 + 'coverage' => array( 149 + 'labels' => array( 150 + // TODO: Modularize this properly, see T13125. 151 + array( 152 + 'C' => pht('Covered'), 153 + 'U' => pht('Not Covered'), 154 + 'N' => pht('Not Executable'), 155 + 'X' => pht('Not Reachable'), 156 + ), 157 + ), 158 + ), 148 159 ); 149 160 150 161 $view_button = id(new PHUIButtonView())
+44 -1
src/view/layout/PhabricatorSourceCodeView.php
··· 10 10 private $truncatedFirstLines = false; 11 11 private $symbolMetadata; 12 12 private $blameMap; 13 + private $coverage = array(); 13 14 14 15 public function setLines(array $lines) { 15 16 $this->lines = $lines; ··· 59 60 return $this->blameMap; 60 61 } 61 62 63 + public function setCoverage(array $coverage) { 64 + $this->coverage = $coverage; 65 + return $this; 66 + } 67 + 68 + public function getCoverage() { 69 + return $this->coverage; 70 + } 71 + 62 72 public function render() { 63 73 $blame_map = $this->getBlameMap(); 64 74 $has_blame = ($blame_map !== null); ··· 97 107 98 108 $base_uri = (string)$this->uri; 99 109 $wrote_anchor = false; 110 + 111 + $coverage = $this->getCoverage(); 112 + $coverage_count = count($coverage); 113 + $coverage_data = ipull($coverage, 'data'); 114 + 115 + // TODO: Modularize this properly, see T13125. 116 + $coverage_map = array( 117 + 'C' => 'background: #66bbff;', 118 + 'U' => 'background: #dd8866;', 119 + 'N' => 'background: #ddeeff;', 120 + 'X' => 'background: #aa00aa;', 121 + ); 122 + 100 123 foreach ($lines as $line) { 101 124 $row_attributes = array(); 102 125 if (isset($this->highlights[$line_number])) { ··· 157 180 $blame_cells = null; 158 181 } 159 182 183 + $coverage_cells = array(); 184 + foreach ($coverage as $coverage_idx => $coverage_spec) { 185 + if (isset($coverage_spec['data'][$line_number - 1])) { 186 + $coverage_char = $coverage_spec['data'][$line_number - 1]; 187 + } else { 188 + $coverage_char = null; 189 + } 190 + 191 + $coverage_style = idx($coverage_map, $coverage_char, null); 192 + 193 + $coverage_cells[] = phutil_tag( 194 + 'th', 195 + array( 196 + 'class' => 'phabricator-source-coverage', 197 + 'style' => $coverage_style, 198 + 'data-coverage' => $coverage_idx.'/'.$coverage_char, 199 + )); 200 + } 201 + 160 202 $rows[] = phutil_tag( 161 203 'tr', 162 204 $row_attributes, ··· 174 216 'class' => 'phabricator-source-code', 175 217 ), 176 218 $line), 177 - )); 219 + $coverage_cells, 220 + )); 178 221 179 222 $line_number++; 180 223 }
+10 -2
webroot/rsrc/css/layout/phabricator-source-code-view.css
··· 6 6 overflow-x: auto; 7 7 overflow-y: hidden; 8 8 border: 1px solid {$paste.border}; 9 - border-radius: 3px; 10 9 } 11 10 12 11 .phui-oi .phabricator-source-code-container { ··· 47 46 text-decoration: none; 48 47 } 49 48 49 + .phabricator-source-coverage-highlight .phabricator-source-code, 50 50 .phabricator-source-highlight .phabricator-source-code { 51 51 background: {$paste.highlight}; 52 52 } 53 53 54 + .phabricator-source-coverage-highlight .phabricator-source-line, 54 55 .phabricator-source-highlight .phabricator-source-line { 55 56 background: {$paste.border}; 56 57 } ··· 96 97 97 98 .phabricator-source-blame-info a { 98 99 color: {$darkbluetext}; 99 - text-shadow: 1px 1px rgba(0, 0, 0, 0.111); 100 + text-shadow: 1px 1px rgba(0, 0, 0, 0.05); 100 101 } 101 102 102 103 .phabricator-source-blame-skip a { ··· 123 124 background-size: 100% 100%; 124 125 background-repeat: no-repeat; 125 126 } 127 + 128 + th.phabricator-source-coverage { 129 + padding: 0 8px; 130 + border-left: 1px solid {$thinblueborder}; 131 + background: {$lightgreybackground}; 132 + cursor: w-resize; 133 + }
+58 -1
webroot/rsrc/js/application/files/behavior-document-engine.js
··· 322 322 var h_max = 0.44; 323 323 var h = h_min + ((h_max - h_min) * epoch_value); 324 324 325 - var s = 0.44; 325 + var s = 0.25; 326 326 327 327 var v_min = 0.92; 328 328 var v_max = 1.00; ··· 357 357 return 'rgb(' + r + ', ' + g + ', ' + b + ')'; 358 358 } 359 359 360 + function onhovercoverage(data, e) { 361 + if (e.getType() === 'mouseout') { 362 + redraw_coverage(data, null); 363 + return; 364 + } 365 + 366 + var target = e.getNode('tag:th'); 367 + var coverage = target.getAttribute('data-coverage'); 368 + if (!coverage) { 369 + return; 370 + } 371 + 372 + redraw_coverage(data, target); 373 + } 374 + 375 + var coverage_row = null; 376 + function redraw_coverage(data, node) { 377 + if (coverage_row) { 378 + JX.DOM.alterClass( 379 + coverage_row, 380 + 'phabricator-source-coverage-highlight', 381 + false); 382 + coverage_row = null; 383 + } 384 + 385 + if (!node) { 386 + JX.Tooltip.hide(); 387 + return; 388 + } 389 + 390 + var coverage = node.getAttribute('data-coverage'); 391 + coverage = coverage.split('/'); 392 + 393 + var idx = parseInt(coverage[0], 10); 394 + var chr = coverage[1]; 395 + 396 + var map = data.coverage.labels[idx]; 397 + if (map) { 398 + var label = map[chr]; 399 + if (label) { 400 + JX.Tooltip.show(node, 300, 'W', label); 401 + 402 + coverage_row = JX.DOM.findAbove(node, 'tr'); 403 + JX.DOM.alterClass( 404 + coverage_row, 405 + 'phabricator-source-coverage-highlight', 406 + true); 407 + } 408 + } 409 + } 410 + 360 411 if (!statics.initialized) { 361 412 JX.Stratcom.listen('click', 'document-engine-view-dropdown', onmenu); 362 413 statics.initialized = true; ··· 374 425 blame(data); 375 426 break; 376 427 } 428 + 429 + JX.DOM.listen( 430 + JX.$(data.viewportID), 431 + ['mouseover', 'mouseout'], 432 + 'tag:th', 433 + JX.bind(null, onhovercoverage, data)); 377 434 } 378 435 379 436 });