@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.

Fix diffusion.readmequery to work in a cluster enviroment

Summary:
Ref T2783. This method is kind of goofballs:

- We send a big list of paths to it.
- It sends back a giant blob of HTML.

Instead, just figure out the path we want locally, then fetch the content with `diffusion.filecontentquery`.

Test Plan:
- Viewed main view and directory view, saw a README.
- See screenshots.

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: epriestley

Maniphest Tasks: T2783

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

+227 -200
+2 -2
src/__phutil_library_map__.php
··· 542 542 'DiffusionQueryPathsConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionQueryPathsConduitAPIMethod.php', 543 543 'DiffusionRawDiffQuery' => 'applications/diffusion/query/rawdiff/DiffusionRawDiffQuery.php', 544 544 'DiffusionRawDiffQueryConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionRawDiffQueryConduitAPIMethod.php', 545 - 'DiffusionReadmeQueryConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionReadmeQueryConduitAPIMethod.php', 545 + 'DiffusionReadmeView' => 'applications/diffusion/view/DiffusionReadmeView.php', 546 546 'DiffusionRefNotFoundException' => 'applications/diffusion/exception/DiffusionRefNotFoundException.php', 547 547 'DiffusionRefsQueryConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionRefsQueryConduitAPIMethod.php', 548 548 'DiffusionRenameHistoryQuery' => 'applications/diffusion/query/DiffusionRenameHistoryQuery.php', ··· 3573 3573 'DiffusionQueryPathsConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod', 3574 3574 'DiffusionRawDiffQuery' => 'DiffusionQuery', 3575 3575 'DiffusionRawDiffQueryConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod', 3576 - 'DiffusionReadmeQueryConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod', 3576 + 'DiffusionReadmeView' => 'DiffusionView', 3577 3577 'DiffusionRefNotFoundException' => 'Exception', 3578 3578 'DiffusionRefsQueryConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod', 3579 3579 'DiffusionRepositoryController' => 'DiffusionController',
-167
src/applications/diffusion/conduit/DiffusionReadmeQueryConduitAPIMethod.php
··· 1 - <?php 2 - 3 - final class DiffusionReadmeQueryConduitAPIMethod 4 - extends DiffusionQueryConduitAPIMethod { 5 - 6 - public function getAPIMethodName() { 7 - return 'diffusion.readmequery'; 8 - } 9 - 10 - public function getMethodDescription() { 11 - return 12 - pht('Retrieve any "readme" that can be found for a set of paths in '. 13 - 'repository.'); 14 - } 15 - 16 - public function defineReturnType() { 17 - return 'string'; 18 - } 19 - 20 - protected function defineCustomParamTypes() { 21 - return array( 22 - 'paths' => 'required array <string>', 23 - 'commit' => 'optional string', 24 - ); 25 - } 26 - 27 - protected function getResult(ConduitAPIRequest $request) { 28 - $drequest = $this->getDiffusionRequest(); 29 - $path_dicts = $request->getValue('paths', array()); 30 - $paths = array(); 31 - foreach ($path_dicts as $dict) { 32 - $paths[] = DiffusionRepositoryPath::newFromDictionary($dict); 33 - } 34 - 35 - $best = -1; 36 - $readme = ''; 37 - $best_render_type = 'plain'; 38 - foreach ($paths as $result_path) { 39 - $file_type = $result_path->getFileType(); 40 - if (($file_type != ArcanistDiffChangeType::FILE_NORMAL) && 41 - ($file_type != ArcanistDiffChangeType::FILE_TEXT)) { 42 - // Skip directories, etc. 43 - continue; 44 - } 45 - 46 - $path = strtolower($result_path->getPath()); 47 - 48 - if ($path === 'readme') { 49 - $path .= '.remarkup'; 50 - } 51 - 52 - if (strncmp($path, 'readme.', 7) !== 0) { 53 - continue; 54 - } 55 - 56 - $priority = 0; 57 - switch (substr($path, 7)) { 58 - case 'remarkup': 59 - $priority = 100; 60 - $render_type = 'remarkup'; 61 - break; 62 - case 'rainbow': 63 - $priority = 90; 64 - $render_type = 'rainbow'; 65 - break; 66 - case 'md': 67 - $priority = 50; 68 - $render_type = 'remarkup'; 69 - break; 70 - case 'txt': 71 - $priority = 10; 72 - $render_type = 'plain'; 73 - break; 74 - default: 75 - $priority = 0; 76 - $render_type = 'plain'; 77 - break; 78 - } 79 - 80 - if ($priority > $best) { 81 - $best = $priority; 82 - $readme = $result_path; 83 - $best_render_type = $render_type; 84 - } 85 - } 86 - 87 - if (!$readme) { 88 - return ''; 89 - } 90 - 91 - $readme_request = DiffusionRequest::newFromDictionary( 92 - array( 93 - 'user' => $request->getUser(), 94 - 'repository' => $drequest->getRepository(), 95 - 'commit' => $drequest->getStableCommit(), 96 - 'path' => $readme->getFullPath(), 97 - )); 98 - 99 - $file_content = DiffusionFileContent::newFromConduit( 100 - DiffusionQuery::callConduitWithDiffusionRequest( 101 - $request->getUser(), 102 - $readme_request, 103 - 'diffusion.filecontentquery', 104 - array( 105 - 'commit' => $drequest->getStableCommit(), 106 - 'path' => $readme->getFullPath(), 107 - 'needsBlame' => false, 108 - ))); 109 - $readme_content = $file_content->getCorpus(); 110 - 111 - switch ($best_render_type) { 112 - case 'plain': 113 - $readme_content = phutil_escape_html_newlines($readme_content); 114 - $class = null; 115 - break; 116 - case 'rainbow': 117 - $highlighter = new PhutilRainbowSyntaxHighlighter(); 118 - $readme_content = $highlighter 119 - ->getHighlightFuture($readme_content) 120 - ->resolve(); 121 - $readme_content = phutil_escape_html_newlines($readme_content); 122 - 123 - require_celerity_resource('syntax-highlighting-css'); 124 - $class = 'remarkup-code'; 125 - break; 126 - case 'remarkup': 127 - // TODO: This is sketchy, but make sure we hit the markup cache. 128 - $markup_object = id(new PhabricatorMarkupOneOff()) 129 - ->setEngineRuleset('diffusion-readme') 130 - ->setContent($readme_content); 131 - $markup_field = 'default'; 132 - 133 - $readme_content = id(new PhabricatorMarkupEngine()) 134 - ->setViewer($request->getUser()) 135 - ->addObject($markup_object, $markup_field) 136 - ->process() 137 - ->getOutput($markup_object, $markup_field); 138 - 139 - $engine = $markup_object->newMarkupEngine($markup_field); 140 - $toc = PhutilRemarkupHeaderBlockRule::renderTableOfContents($engine); 141 - if ($toc) { 142 - $toc = phutil_tag_div( 143 - 'phabricator-remarkup-toc', 144 - array( 145 - phutil_tag_div( 146 - 'phabricator-remarkup-toc-header', 147 - pht('Table of Contents')), 148 - $toc, 149 - )); 150 - $readme_content = array($toc, $readme_content); 151 - } 152 - 153 - $class = 'phabricator-remarkup'; 154 - break; 155 - } 156 - 157 - $readme_content = phutil_tag( 158 - 'div', 159 - array( 160 - 'class' => $class, 161 - ), 162 - $readme_content); 163 - 164 - return $readme_content; 165 - } 166 - 167 - }
+14 -15
src/applications/diffusion/controller/DiffusionBrowseDirectoryController.php
··· 66 66 67 67 $content[] = $this->buildOpenRevisions(); 68 68 69 - $readme = $this->callConduitWithDiffusionRequest( 70 - 'diffusion.readmequery', 71 - array( 72 - 'paths' => $results->getPathDicts(), 73 - 'commit' => $drequest->getStableCommit(), 74 - )); 75 - if ($readme) { 76 - $box = new PHUIBoxView(); 77 - $box->appendChild($readme); 78 - $box->addPadding(PHUI::PADDING_LARGE); 79 69 80 - $object_box = id(new PHUIObjectBoxView()) 81 - ->setHeaderText(pht('README')) 82 - ->appendChild($box); 83 - 84 - $content[] = $object_box; 70 + $readme_path = $results->getReadmePath(); 71 + if ($readme_path) { 72 + $readme_content = $this->callConduitWithDiffusionRequest( 73 + 'diffusion.filecontentquery', 74 + array( 75 + 'path' => $readme_path, 76 + 'commit' => $drequest->getStableCommit(), 77 + )); 78 + if ($readme_content) { 79 + $content[] = id(new DiffusionReadmeView()) 80 + ->setUser($this->getViewer()) 81 + ->setPath($readme_path) 82 + ->setContent($readme_content['corpus']); 83 + } 85 84 } 86 85 87 86 $crumbs = $this->buildCrumbs(
+17 -16
src/applications/diffusion/controller/DiffusionRepositoryController.php
··· 151 151 $phids = array_keys($phids); 152 152 $handles = $this->loadViewerHandles($phids); 153 153 154 + $readme = null; 154 155 if ($browse_results) { 155 - $readme = $this->callConduitWithDiffusionRequest( 156 - 'diffusion.readmequery', 157 - array( 158 - 'paths' => $browse_results->getPathDicts(), 159 - 'commit' => $drequest->getStableCommit(), 160 - )); 161 - } else { 162 - $readme = null; 156 + $readme_path = $browse_results->getReadmePath(); 157 + if ($readme_path) { 158 + $readme_content = $this->callConduitWithDiffusionRequest( 159 + 'diffusion.filecontentquery', 160 + array( 161 + 'path' => $readme_path, 162 + 'commit' => $drequest->getStableCommit(), 163 + )); 164 + if ($readme_content) { 165 + $readme = id(new DiffusionReadmeView()) 166 + ->setUser($this->getViewer()) 167 + ->setPath($readme_path) 168 + ->setContent($readme_content['corpus']); 169 + } 170 + } 163 171 } 164 172 165 173 $content[] = $this->buildBrowseTable( ··· 195 203 } 196 204 197 205 if ($readme) { 198 - $box = new PHUIBoxView(); 199 - $box->appendChild($readme); 200 - $box->addPadding(PHUI::PADDING_LARGE); 201 - 202 - $panel = new PHUIObjectBoxView(); 203 - $panel->setHeaderText(pht('README')); 204 - $panel->appendChild($box); 205 - $content[] = $panel; 206 + $content[] = $readme; 206 207 } 207 208 208 209 return $content;
+70
src/applications/diffusion/data/DiffusionBrowseResultSet.php
··· 76 76 return array(); 77 77 } 78 78 79 + /** 80 + * Get the best README file in this result set, if one exists. 81 + * 82 + * Callers should normally use `diffusion.filecontentquery` to pull README 83 + * content. 84 + * 85 + * @return string|null Full path to best README, or null if one does not 86 + * exist. 87 + */ 88 + public function getReadmePath() { 89 + $allowed_types = array( 90 + ArcanistDiffChangeType::FILE_NORMAL => true, 91 + ArcanistDiffChangeType::FILE_TEXT => true, 92 + ); 93 + 94 + $candidates = array(); 95 + foreach ($this->getPaths() as $path_object) { 96 + if (empty($allowed_types[$path_object->getFileType()])) { 97 + // Skip directories, images, etc. 98 + continue; 99 + } 100 + 101 + $local_path = $path_object->getPath(); 102 + if (!preg_match('/^readme(\.|$)/i', $local_path)) { 103 + // Skip files not named "README". 104 + continue; 105 + } 106 + 107 + $full_path = $path_object->getFullPath(); 108 + $candidates[$full_path] = self::getReadmePriority($local_path); 109 + } 110 + 111 + if (!$candidates) { 112 + return null; 113 + } 114 + 115 + arsort($candidates); 116 + return head_key($candidates); 117 + } 118 + 119 + /** 120 + * Get the priority of a README file. 121 + * 122 + * When a directory contains several README files, this function scores them 123 + * so the caller can select a preferred file. See @{method:getReadmePath}. 124 + * 125 + * @param string Local README path, like "README.txt". 126 + * @return int Priority score, with higher being more preferred. 127 + */ 128 + public static function getReadmePriority($path) { 129 + $path = phutil_utf8_strtolower($path); 130 + if ($path == 'readme') { 131 + return 90; 132 + } 133 + 134 + $ext = last(explode('.', $path)); 135 + switch ($ext) { 136 + case 'remarkup': 137 + return 100; 138 + case 'rainbow': 139 + return 80; 140 + case 'md': 141 + return 70; 142 + case 'txt': 143 + return 60; 144 + default: 145 + return 50; 146 + } 147 + } 148 + 79 149 public static function newFromConduit(array $data) { 80 150 $paths = array(); 81 151 $path_dicts = $data['paths'];
+124
src/applications/diffusion/view/DiffusionReadmeView.php
··· 1 + <?php 2 + 3 + final class DiffusionReadmeView extends DiffusionView { 4 + 5 + private $path; 6 + private $content; 7 + 8 + public function setPath($path) { 9 + $this->path = $path; 10 + return $this; 11 + } 12 + 13 + public function getPath() { 14 + return $this->path; 15 + } 16 + 17 + public function setContent($content) { 18 + $this->content = $content; 19 + return $this; 20 + } 21 + 22 + public function getContent() { 23 + return $this->content; 24 + } 25 + 26 + /** 27 + * Get the markup language a README should be interpreted as. 28 + * 29 + * @param string Local README path, like "README.txt". 30 + * @return string Best markup interpreter (like "remarkup") for this file. 31 + */ 32 + private function getReadmeLanguage($path) { 33 + $path = phutil_utf8_strtolower($path); 34 + if ($path == 'readme') { 35 + return 'remarkup'; 36 + } 37 + 38 + $ext = last(explode('.', $path)); 39 + switch ($ext) { 40 + case 'remarkup': 41 + case 'md': 42 + return 'remarkup'; 43 + case 'rainbow': 44 + return 'rainbow'; 45 + case 'txt': 46 + default: 47 + return 'text'; 48 + } 49 + } 50 + 51 + 52 + public function render() { 53 + $readme_path = $this->getPath(); 54 + $readme_name = basename($readme_path); 55 + $interpreter = $this->getReadmeLanguage($readme_name); 56 + 57 + $content = $this->getContent(); 58 + 59 + $class = null; 60 + switch ($interpreter) { 61 + case 'remarkup': 62 + // TODO: This is sketchy, but make sure we hit the markup cache. 63 + $markup_object = id(new PhabricatorMarkupOneOff()) 64 + ->setEngineRuleset('diffusion-readme') 65 + ->setContent($content); 66 + $markup_field = 'default'; 67 + 68 + $content = id(new PhabricatorMarkupEngine()) 69 + ->setViewer($this->getUser()) 70 + ->addObject($markup_object, $markup_field) 71 + ->process() 72 + ->getOutput($markup_object, $markup_field); 73 + 74 + $engine = $markup_object->newMarkupEngine($markup_field); 75 + $toc = PhutilRemarkupHeaderBlockRule::renderTableOfContents($engine); 76 + if ($toc) { 77 + $toc = phutil_tag_div( 78 + 'phabricator-remarkup-toc', 79 + array( 80 + phutil_tag_div( 81 + 'phabricator-remarkup-toc-header', 82 + pht('Table of Contents')), 83 + $toc, 84 + )); 85 + $content = array($toc, $content); 86 + } 87 + 88 + $readme_content = $content; 89 + $class = 'phabricator-remarkup'; 90 + break; 91 + case 'rainbow': 92 + $content = id(new PhutilRainbowSyntaxHighlighter()) 93 + ->getHighlightFuture($content) 94 + ->resolve(); 95 + $readme_content = phutil_escape_html_newlines($content); 96 + 97 + require_celerity_resource('syntax-highlighting-css'); 98 + $class = 'remarkup-code'; 99 + break; 100 + default: 101 + case 'text': 102 + $readme_content = phutil_escape_html_newlines($content); 103 + break; 104 + } 105 + 106 + $readme_content = phutil_tag( 107 + 'div', 108 + array( 109 + 'class' => $class, 110 + ), 111 + $readme_content); 112 + 113 + $box = new PHUIBoxView(); 114 + $box->appendChild($readme_content); 115 + $box->addPadding(PHUI::PADDING_LARGE); 116 + 117 + $object_box = id(new PHUIObjectBoxView()) 118 + ->setHeaderText($readme_name) 119 + ->appendChild($box); 120 + 121 + return $object_box; 122 + } 123 + 124 + }