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

Improve Diviner handling of paths and remarkup

Summary:
- Currently, the atomizers don't emit atoms with the right file in all cases. Make them always emit it correctly.
- Currently, we use absolute paths in some cases and relative paths in other cases. Use them consistently: relative when storing/presenting, absolute when accessing data.
- Don't preserve linebreaks when marking up documentation (documentation is generally wrapped at 80col, but should not be wrapped in this way when displayed).
- Markup Diviner link rules (albeit uselesly).

Test Plan:
Before:

{F33044}

After:

{F33045}

Reviewers: chad

Reviewed By: chad

CC: aran

Maniphest Tasks: T988

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

+67 -13
+2
src/__phutil_library_map__.php
··· 474 474 'DivinerListController' => 'applications/diviner/controller/DivinerListController.php', 475 475 'DivinerPublishCache' => 'applications/diviner/cache/DivinerPublishCache.php', 476 476 'DivinerPublisher' => 'applications/diviner/publisher/DivinerPublisher.php', 477 + 'DivinerRemarkupRuleSymbol' => 'applications/diviner/markup/DivinerRemarkupRuleSymbol.php', 477 478 'DivinerRenderer' => 'applications/diviner/renderer/DivinerRenderer.php', 478 479 'DivinerStaticPublisher' => 'applications/diviner/publisher/DivinerStaticPublisher.php', 479 480 'DivinerWorkflow' => 'applications/diviner/workflow/DivinerWorkflow.php', ··· 1974 1975 'DivinerGenerateWorkflow' => 'DivinerWorkflow', 1975 1976 'DivinerListController' => 'PhabricatorController', 1976 1977 'DivinerPublishCache' => 'DivinerDiskCache', 1978 + 'DivinerRemarkupRuleSymbol' => 'PhutilRemarkupRule', 1977 1979 'DivinerStaticPublisher' => 'DivinerPublisher', 1978 1980 'DivinerWorkflow' => 'PhutilArgumentWorkflow', 1979 1981 'DrydockAllocatorWorker' => 'PhabricatorWorker',
+1 -1
src/applications/diviner/atomizer/DivinerArticleAtomizer.php
··· 2 2 3 3 final class DivinerArticleAtomizer extends DivinerAtomizer { 4 4 5 - public function atomize($file_name, $file_data) { 5 + protected function executeAtomize($file_name, $file_data) { 6 6 $atom = $this->newAtom(DivinerAtom::TYPE_ARTICLE) 7 7 ->setLine(1) 8 8 ->setLength(count(explode("\n", $file_data)))
+8 -1
src/applications/diviner/atomizer/DivinerAtomizer.php
··· 6 6 abstract class DivinerAtomizer { 7 7 8 8 private $book; 9 + private $fileName; 9 10 10 11 /** 11 12 * If you make a significant change to an atomizer, you can bump this ··· 15 16 return 1; 16 17 } 17 18 18 - abstract public function atomize($file_name, $file_data); 19 + final public function atomize($file_name, $file_data) { 20 + $this->fileName = $file_name; 21 + return $this->executeAtomize($file_name, $file_data); 22 + } 23 + 24 + abstract protected function executeAtomize($file_name, $file_data); 19 25 20 26 final public function setBook($book) { 21 27 $this->book = $book; ··· 29 35 protected function newAtom($type) { 30 36 return id(new DivinerAtom()) 31 37 ->setBook($this->getBook()) 38 + ->setFile($this->fileName) 32 39 ->setType($type); 33 40 } 34 41
+1 -1
src/applications/diviner/atomizer/DivinerFileAtomizer.php
··· 2 2 3 3 final class DivinerFileAtomizer extends DivinerAtomizer { 4 4 5 - public function atomize($file_name, $file_data) { 5 + protected function executeAtomize($file_name, $file_data) { 6 6 $atom = $this->newAtom(DivinerAtom::TYPE_FILE) 7 7 ->setName($file_name) 8 8 ->setFile($file_name)
+36
src/applications/diviner/markup/DivinerRemarkupRuleSymbol.php
··· 1 + <?php 2 + 3 + final class DivinerRemarkupRuleSymbol extends PhutilRemarkupRule { 4 + 5 + public function apply($text) { 6 + return $this->replaceHTML( 7 + '/(?:^|\B)@{(?:(?P<type>[^:]+?):)?(?P<name>[^}]+?)}/', 8 + array($this, 'markupSymbol'), 9 + $text); 10 + } 11 + 12 + public function markupSymbol($matches) { 13 + $type = $matches['type']; 14 + $name = $matches['name']; 15 + 16 + // Collapse sequences of whitespace into a single space. 17 + $name = preg_replace('/\s+/', ' ', $name); 18 + 19 + $book = null; 20 + if (strpos($type, '@') !== false) { 21 + list($type, $book) = explode('@', $type, 2); 22 + } 23 + 24 + // TODO: This doesn't actually do anything useful yet. 25 + 26 + $link = phutil_tag( 27 + 'a', 28 + array( 29 + 'href' => '#', 30 + ), 31 + $name); 32 + 33 + return $this->getEngine()->storeText($link); 34 + } 35 + 36 + }
+4 -1
src/applications/diviner/renderer/DivinerDefaultRenderer.php
··· 172 172 } 173 173 174 174 protected function getBlockMarkupEngine() { 175 - return PhabricatorMarkupEngine::newMarkupEngine(array()); 175 + return PhabricatorMarkupEngine::newMarkupEngine( 176 + array( 177 + 'preserve-linebreaks' => false, 178 + )); 176 179 } 177 180 178 181 protected function getInlineMarkupEngine() {
+6 -5
src/applications/diviner/workflow/DivinerAtomizeWorkflow.php
··· 59 59 60 60 $file_atomizer = new DivinerFileAtomizer(); 61 61 62 + foreach (array($atomizer, $file_atomizer) as $configure) { 63 + $configure->setBook($this->getConfig('name')); 64 + } 65 + 62 66 $all_atoms = array(); 63 67 foreach ($files as $file) { 64 - $data = Filesystem::readFile($file); 68 + $abs_path = Filesystem::resolvePath($file, $this->getConfig('root')); 69 + $data = Filesystem::readFile($abs_path); 65 70 66 71 if (!$this->shouldAtomizeFile($file, $data)) { 67 72 $console->writeLog("Skipping %s...\n", $file); ··· 88 93 } 89 94 90 95 $all_atoms = array_mergev($all_atoms); 91 - 92 - foreach ($all_atoms as $atom) { 93 - $atom->setBook($this->getConfig('name')); 94 - } 95 96 96 97 $all_atoms = mpull($all_atoms, 'toDictionary'); 97 98 $all_atoms = ipull($all_atoms, null, 'hash');
+5 -3
src/applications/diviner/workflow/DivinerGenerateWorkflow.php
··· 198 198 199 199 200 200 private function findFilesInProject() { 201 - $file_hashes = id(new FileFinder($this->getConfig('root'))) 201 + $raw_hashes = id(new FileFinder($this->getConfig('root'))) 202 202 ->excludePath('*/.*') 203 203 ->withType('f') 204 204 ->setGenerateChecksums(true) ··· 206 206 207 207 $version = $this->getDivinerAtomWorldVersion(); 208 208 209 - foreach ($file_hashes as $file => $md5_hash) { 209 + $file_hashes = array(); 210 + foreach ($raw_hashes as $file => $md5_hash) { 211 + $rel_file = Filesystem::readablePath($file, $this->getConfig('root')); 210 212 // We want the hash to change if the file moves or Diviner gets updated, 211 213 // not just if the file content changes. Derive a hash from everything 212 214 // we care about. 213 - $file_hashes[$file] = md5("{$file}\0{$md5_hash}\0{$version}").'F'; 215 + $file_hashes[$rel_file] = md5("{$rel_file}\0{$md5_hash}\0{$version}").'F'; 214 216 } 215 217 216 218 return $file_hashes;
+4 -1
src/infrastructure/markup/PhabricatorMarkupEngine.php
··· 355 355 'uri.allowed-protocols'), 356 356 'syntax-highlighter.engine' => PhabricatorEnv::getEnvConfig( 357 357 'syntax-highlighter.engine'), 358 + 'preserve-linebreaks' => true, 358 359 ); 359 360 } 360 361 ··· 368 369 369 370 $engine = new PhutilRemarkupEngine(); 370 371 371 - $engine->setConfig('preserve-linebreaks', true); 372 + $engine->setConfig('preserve-linebreaks', $options['preserve-linebreaks']); 372 373 $engine->setConfig('pygments.enabled', $options['pygments']); 373 374 $engine->setConfig( 374 375 'uri.allowed-protocols', ··· 421 422 $rules[] = new PhabricatorRemarkupRuleImageMacro(); 422 423 $rules[] = new PhabricatorRemarkupRuleMeme(); 423 424 } 425 + 426 + $rules[] = new DivinerRemarkupRuleSymbol(); 424 427 425 428 $rules[] = new PhabricatorRemarkupRuleMention(); 426 429