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

Treat Owners paths like "/src/backend" and "/src/backend/" identically

Summary:
Depends on D19183. Ref T11015. Currently, adding a trailing slash works great and omitting it mysteriously doesn't work.

Store a normalized version with an unconditional trailing slash for the lookup logic to operate on, and a separate display version which tracks what the user actually typed.

Test Plan:
- Entered "/src/main.c", "/src/main.c/", saw them de-duplicate.
- Entered "/src/main.c", saw it stay that way in the UI but appear as "/src/main.c/" internally.
- Added a rule for "/src/applications/owners" (no slash), created a revision touching paths in that directory, saw Owners fire for it.
- Changed the display value of a path only ("/src/main.c" to "/src/main.c/"), saw the update reflected in the UI without any beahvioral change.

Maniphest Tasks: T11015

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

+47 -14
+10 -10
resources/celerity/map.php
··· 424 424 'rsrc/js/application/maniphest/behavior-line-chart.js' => 'e4232876', 425 425 'rsrc/js/application/maniphest/behavior-list-edit.js' => 'a9f88de2', 426 426 'rsrc/js/application/maniphest/behavior-subpriorityeditor.js' => '71237763', 427 - 'rsrc/js/application/owners/OwnersPathEditor.js' => 'aa1733d0', 427 + 'rsrc/js/application/owners/OwnersPathEditor.js' => '996d62b9', 428 428 'rsrc/js/application/owners/owners-path-editor.js' => '7a68dda3', 429 429 'rsrc/js/application/passphrase/passphrase-credential-control.js' => '3cb0b2fc', 430 430 'rsrc/js/application/pholio/behavior-pholio-mock-edit.js' => 'bee502c8', ··· 764 764 'maniphest-task-edit-css' => 'fda62a9b', 765 765 'maniphest-task-summary-css' => '11cc5344', 766 766 'multirow-row-manager' => 'b5d57730', 767 - 'owners-path-editor' => 'aa1733d0', 767 + 'owners-path-editor' => '996d62b9', 768 768 'owners-path-editor-css' => '2f00933b', 769 769 'paste-css' => '9fcc9773', 770 770 'path-typeahead' => 'f7fc67ec', ··· 1676 1676 'javelin-mask', 1677 1677 'phabricator-drag-and-drop-file-upload', 1678 1678 ), 1679 + '996d62b9' => array( 1680 + 'multirow-row-manager', 1681 + 'javelin-install', 1682 + 'path-typeahead', 1683 + 'javelin-dom', 1684 + 'javelin-util', 1685 + 'phabricator-prefab', 1686 + ), 1679 1687 '9a6dd75c' => array( 1680 1688 'javelin-behavior', 1681 1689 'javelin-stratcom', ··· 1765 1773 'javelin-workflow', 1766 1774 'javelin-fx', 1767 1775 'javelin-util', 1768 - ), 1769 - 'aa1733d0' => array( 1770 - 'multirow-row-manager', 1771 - 'javelin-install', 1772 - 'path-typeahead', 1773 - 'javelin-dom', 1774 - 'javelin-util', 1775 - 'phabricator-prefab', 1776 1776 ), 1777 1777 'ab2f381b' => array( 1778 1778 'javelin-request',
+2 -2
src/applications/owners/controller/PhabricatorOwnersDetailController.php
··· 279 279 $href = $repo->generateURI( 280 280 array( 281 281 'branch' => $repo->getDefaultBranch(), 282 - 'path' => $path->getPath(), 282 + 'path' => $path->getPathDisplay(), 283 283 'action' => 'browse', 284 284 )); 285 285 ··· 288 288 array( 289 289 'href' => (string)$href, 290 290 ), 291 - $path->getPath()); 291 + $path->getPathDisplay()); 292 292 293 293 $rows[] = array( 294 294 ($path->getExcluded() ? '-' : '+'),
+1 -1
src/applications/owners/engineextension/PhabricatorOwnersPathsSearchEngineAttachment.php
··· 22 22 foreach ($paths as $path) { 23 23 $list[] = array( 24 24 'repositoryPHID' => $path->getRepositoryPHID(), 25 - 'path' => $path->getPath(), 25 + 'path' => $path->getPathDisplay(), 26 26 'excluded' => (bool)$path->getExcluded(), 27 27 ); 28 28 }
+1
src/applications/owners/storage/PhabricatorOwnersPath.php
··· 49 49 return array( 50 50 'repositoryPHID' => $this->getRepositoryPHID(), 51 51 'path' => $this->getPath(), 52 + 'display' => $this->getPathDisplay(), 52 53 'excluded' => (int)$this->getExcluded(), 53 54 ); 54 55 }
+32
src/applications/owners/xaction/PhabricatorOwnersPackagePathsTransaction.php
··· 103 103 104 104 $paths = $object->getPaths(); 105 105 106 + // We store paths in a normalized format with a trailing slash, regardless 107 + // of whether the user enters "path/to/file.c" or "src/backend/". Normalize 108 + // paths now. 109 + 110 + $display_map = array(); 111 + foreach ($new as $key => $spec) { 112 + $display_path = $spec['path']; 113 + $raw_path = rtrim($display_path, '/').'/'; 114 + 115 + // If the user entered two paths which normalize to the same value 116 + // (like "src/main.c" and "src/main.c/"), discard the duplicates. 117 + if (isset($display_map[$raw_path])) { 118 + unset($new[$key]); 119 + continue; 120 + } 121 + 122 + $new[$key]['path'] = $raw_path; 123 + $display_map[$raw_path] = $display_path; 124 + } 125 + 106 126 $diffs = PhabricatorOwnersPath::getTransactionValueChanges($old, $new); 107 127 list($rem, $add) = $diffs; 108 128 ··· 111 131 $ref = $path->getRef(); 112 132 if (PhabricatorOwnersPath::isRefInSet($ref, $set)) { 113 133 $path->delete(); 134 + continue; 135 + } 136 + 137 + // If the user has changed the display value for a path but the raw 138 + // storage value hasn't changed, update the display value. 139 + 140 + if (isset($display_map[$path->getPath()])) { 141 + $path 142 + ->setPathDisplay($display_map[$path->getPath()]) 143 + ->save(); 144 + continue; 114 145 } 115 146 } 116 147 117 148 foreach ($add as $ref) { 118 149 $path = PhabricatorOwnersPath::newFromRef($ref) 119 150 ->setPackageID($object->getID()) 151 + ->setPathDisplay($display_map[$ref['path']]) 120 152 ->save(); 121 153 } 122 154 }
+1 -1
webroot/rsrc/js/application/owners/OwnersPathEditor.js
··· 115 115 JX.copy( 116 116 path_input, 117 117 { 118 - value : path_ref.path || '', 118 + value : path_ref.display || '', 119 119 name : 'path[' + this._count + ']' 120 120 }); 121 121