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

Bring "fixes x as y" parser forward and use new parsers instead of old ones

Summary: Fixes T3872. Ref T1812. Ref T3886. Modernize the "closes x as y" string parser, and use all the new parsers instead of the old ones.

Test Plan: Made a commit full of a pile of these trigger strings, then used `scripts/repository/reparse.php --message` to reparse it. Verified that parses came back as expected using a bunch of `var_dump()`.

Reviewers: btrahan

Reviewed By: btrahan

CC: aran

Maniphest Tasks: T1812, T3872, T3886

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

+149 -73
+4
src/__phutil_library_map__.php
··· 885 885 'ManiphestCreateMailReceiver' => 'applications/maniphest/mail/ManiphestCreateMailReceiver.php', 886 886 'ManiphestCustomField' => 'applications/maniphest/field/ManiphestCustomField.php', 887 887 'ManiphestCustomFieldNumericIndex' => 'applications/maniphest/storage/ManiphestCustomFieldNumericIndex.php', 888 + 'ManiphestCustomFieldStatusParser' => 'applications/maniphest/field/parser/ManiphestCustomFieldStatusParser.php', 889 + 'ManiphestCustomFieldStatusParserTestCase' => 'applications/maniphest/field/parser/__tests__/ManiphestCustomFieldStatusParserTestCase.php', 888 890 'ManiphestCustomFieldStorage' => 'applications/maniphest/storage/ManiphestCustomFieldStorage.php', 889 891 'ManiphestCustomFieldStringIndex' => 'applications/maniphest/storage/ManiphestCustomFieldStringIndex.php', 890 892 'ManiphestDAO' => 'applications/maniphest/storage/ManiphestDAO.php', ··· 3498 3500 'ManiphestCreateMailReceiver' => 'PhabricatorMailReceiver', 3499 3501 'ManiphestCustomField' => 'PhabricatorCustomField', 3500 3502 'ManiphestCustomFieldNumericIndex' => 'PhabricatorCustomFieldNumericIndexStorage', 3503 + 'ManiphestCustomFieldStatusParser' => 'PhabricatorCustomFieldMonogramParser', 3504 + 'ManiphestCustomFieldStatusParserTestCase' => 'PhabricatorTestCase', 3501 3505 'ManiphestCustomFieldStorage' => 'PhabricatorCustomFieldStorage', 3502 3506 'ManiphestCustomFieldStringIndex' => 'PhabricatorCustomFieldStringIndexStorage', 3503 3507 'ManiphestDAO' => 'PhabricatorLiskDAO',
+22 -72
src/applications/differential/field/specification/DifferentialFreeformFieldSpecification.php
··· 44 44 '' => null, 45 45 ); 46 46 47 - $prefix_regex = array(); 48 - foreach ($prefixes as $prefix => $resolution) { 49 - $prefix_regex[] = preg_quote($prefix, '/'); 50 - } 51 - $prefix_regex = implode('|', $prefix_regex); 52 - 53 - $suffix_regex = array(); 54 - foreach ($suffixes as $suffix => $resolution) { 55 - $suffix_regex[] = preg_quote($suffix, '/'); 56 - } 57 - $suffix_regex = implode('|', $suffix_regex); 47 + $matches = id(new ManiphestCustomFieldStatusParser()) 48 + ->parseCorpus($message); 58 49 59 - $matches = null; 60 - preg_match_all( 61 - "/({$prefix_regex})\s+T(\d+)\s*({$suffix_regex})/i", 62 - $message, 63 - $matches, 64 - PREG_SET_ORDER); 65 - 66 - $tasks_statuses = array(); 67 - foreach ($matches as $set) { 68 - $prefix = strtolower($set[1]); 69 - $task_id = (int)$set[2]; 70 - $suffix = strtolower($set[3]); 50 + $task_statuses = array(); 51 + foreach ($matches as $match) { 52 + $prefix = phutil_utf8_strtolower($match['prefix']); 53 + $suffix = phutil_utf8_strtolower($match['suffix']); 71 54 72 55 $status = idx($suffixes, $suffix); 73 56 if (!$status) { 74 57 $status = idx($prefixes, $prefix); 75 58 } 76 59 77 - $tasks_statuses[$task_id] = $status; 60 + foreach ($match['monograms'] as $task_monogram) { 61 + $task_id = (int)trim($task_monogram, 'tT'); 62 + $task_statuses[$task_id] = $status; 63 + } 78 64 } 79 65 80 - return $tasks_statuses; 66 + return $task_statuses; 81 67 } 82 68 83 69 private function findDependentRevisions($message) { 84 - $dependents = array(); 70 + $matches = id(new DifferentialCustomFieldDependsOnParser()) 71 + ->parseCorpus($message); 85 72 86 - $matches = null; 87 - preg_match_all( 88 - '/\b(?i:depends\s+on):?\s+D(\d+(,\s+D\d++)*)\b/', 89 - $message, 90 - $matches); 91 - 92 - foreach ($matches[1] as $revisions) { 93 - foreach (preg_split('/,\s+D/', $revisions) as $id) { 73 + $dependents = array(); 74 + foreach ($matches as $match) { 75 + foreach ($match['monograms'] as $monogram) { 76 + $id = (int)trim($monogram, 'dD'); 94 77 $dependents[$id] = $id; 95 78 } 96 79 } ··· 99 82 } 100 83 101 84 public static function findRevertedCommits($message) { 102 - $reverts = array(); 103 - $matches = null; 104 - 105 - // NOTE: Git language is "This reverts commit X." 106 - // NOTE: Mercurial language is "Backed out changeset Y". 107 - 108 - $prefixes = array( 109 - 'revert' => true, 110 - 'reverts' => true, 111 - 'back\s*out' => true, 112 - 'backs\s*out' => true, 113 - 'backed\s*out' => true, 114 - 'undo' => true, 115 - 'undoes' => true, 116 - ); 117 - 118 - $optional = array( 119 - 'commit' => true, 120 - 'changeset' => true, 121 - 'rev' => true, 122 - 'revision' => true, 123 - 'change' => true, 124 - 'diff' => true, 125 - ); 126 - 127 - $pre_re = implode('|', array_keys($prefixes)); 128 - $opt_re = implode('|', array_keys($optional)); 129 - 130 - $matches = null; 131 - preg_match_all( 132 - '/\b(?i:'.$pre_re.')(?:\s+(?i:'.$opt_re.'))?([rA-Z0-9a-f,\s]+)\b/', 133 - $message, 134 - $matches); 85 + $matches = id(new DifferentialCustomFieldRevertsParser()) 86 + ->parseCorpus($message); 135 87 136 88 $result = array(); 137 - foreach ($matches[1] as $commits) { 138 - $commits = preg_split('/[,\s]+/', $commits); 139 - $commits = array_filter($commits); 140 - foreach ($commits as $commit) { 141 - $result[$commit] = $commit; 89 + foreach ($matches as $match) { 90 + foreach ($match['monograms'] as $monogram) { 91 + $result[$monogram] = $monogram; 142 92 } 143 93 } 144 94
+59
src/applications/maniphest/field/parser/ManiphestCustomFieldStatusParser.php
··· 1 + <?php 2 + 3 + final class ManiphestCustomFieldStatusParser 4 + extends PhabricatorCustomFieldMonogramParser { 5 + 6 + protected function getPrefixes() { 7 + return array( 8 + 'resolve', 9 + 'resolves', 10 + 'resolved', 11 + 'fix', 12 + 'fixes', 13 + 'fixed', 14 + 'wontfix', 15 + 'wontfixes', 16 + 'wontfixed', 17 + 'spite', 18 + 'spites', 19 + 'spited', 20 + 'invalidate', 21 + 'invalidates', 22 + 'invalidated', 23 + 'close', 24 + 'closes', 25 + 'closed', 26 + 'ref', 27 + 'refs', 28 + 'references', 29 + 'cf.', 30 + ); 31 + } 32 + 33 + protected function getInfixes() { 34 + return array( 35 + 'task', 36 + 'tasks', 37 + 'issue', 38 + 'issues', 39 + 'bug', 40 + 'bugs', 41 + ); 42 + } 43 + 44 + protected function getSuffixes() { 45 + return array( 46 + 'as resolved', 47 + 'as fixed', 48 + 'as wontfix', 49 + 'as spite', 50 + 'out of spite', 51 + 'as invalid', 52 + ); 53 + } 54 + 55 + protected function getMonogramPattern() { 56 + return '[tT]\d+'; 57 + } 58 + 59 + }
+63
src/applications/maniphest/field/parser/__tests__/ManiphestCustomFieldStatusParserTestCase.php
··· 1 + <?php 2 + 3 + final class ManiphestCustomFieldStatusParserTestCase 4 + extends PhabricatorTestCase { 5 + 6 + public function testParser() { 7 + $map = array( 8 + 'quack quack quack' => array(), 9 + 'T123' => array(), 10 + 'Fixes T123' => array( 11 + array( 12 + 'match' => 'Fixes T123', 13 + 'prefix' => 'Fixes', 14 + 'infix' => '', 15 + 'monograms' => array('T123'), 16 + 'suffix' => '', 17 + 'offset' => 0, 18 + ), 19 + ), 20 + 'Fixes T123, T124, and also some other bugs.' => array( 21 + array( 22 + 'match' => 'Fixes T123, T124, ', 23 + 'prefix' => 'Fixes', 24 + 'infix' => '', 25 + 'monograms' => array('T123', 'T124'), 26 + 'suffix' => '', 27 + 'offset' => 0, 28 + ), 29 + ), 30 + 'Closes T1 as wontfix' => array( 31 + array( 32 + 'match' => 'Closes T1 as wontfix', 33 + 'prefix' => 'Closes', 34 + 'infix' => '', 35 + 'monograms' => array('T1'), 36 + 'suffix' => 'as wontfix', 37 + 'offset' => 0, 38 + ), 39 + ), 40 + 'Fixes task T9' => array( 41 + array( 42 + 'match' => 'Fixes task T9', 43 + 'prefix' => 'Fixes', 44 + 'infix' => 'task', 45 + 'monograms' => array('T9'), 46 + 'suffix' => '', 47 + 'offset' => 0, 48 + ), 49 + ), 50 + 'Fixes t2apps' => array(), 51 + 'fixes a bug' => array(), 52 + 'Prefixes T2' => array(), 53 + ); 54 + 55 + foreach ($map as $input => $expect) { 56 + $parser = new ManiphestCustomFieldStatusParser(); 57 + $output = $parser->parseCorpus($input); 58 + 59 + $this->assertEqual($expect, $output, $input); 60 + } 61 + } 62 + 63 + }
+1 -1
src/infrastructure/customfield/parser/PhabricatorCustomFieldMonogramParser.php
··· 47 47 'prefix' => $set[1][0], 48 48 'infix' => $set[2][0], 49 49 'monograms' => array_filter(preg_split('/[,\s]+/', $set[3][0])), 50 - 'suffix' => $set[4][0], 50 + 'suffix' => idx(idx($set, 4, array()), 0, ''), 51 51 'offset' => $set[0][1], 52 52 ); 53 53 }