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

Allow users to manage package dominion rules

Summary: Ref T10939. This adds UI, transactions, etc, to adjust dominion rules.

Test Plan:
- Read documentation.
- Changed dominion rules.
- Created packages on `/` ("A") and `/x` ("B") with "Auto Review: Review".
- Touched `/x`.
- Verified that A and B were added with strong dominion.
- Verified that only B was added when A was set to weak dominion.
- Viewed file in Diffusion, saw correct ownership with strong/weak dominion rules.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T10939

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

+135 -5
+2
resources/sql/autopatches/20160516.owners.01.dominion.sql
··· 1 + ALTER TABLE {$NAMESPACE}_owners.owners_package 2 + ADD dominion VARCHAR(32) NOT NULL COLLATE {$COLLATE_TEXT};
+2
resources/sql/autopatches/20160516.owners.02.dominionstrong.sql
··· 1 + UPDATE {$NAMESPACE}_owners.owners_package 2 + SET dominion = 'strong' WHERE dominion = '';
+4 -3
src/applications/differential/editor/DifferentialTransactionEditor.php
··· 1723 1723 $paths[] = $path_prefix.'/'.$changeset->getFilename(); 1724 1724 } 1725 1725 1726 + // Save the affected paths; we'll use them later to query Owners. This 1727 + // uses the un-expanded paths. 1728 + $this->affectedPaths = $paths; 1729 + 1726 1730 // Mark this as also touching all parent paths, so you can see all pending 1727 1731 // changes to any file within a directory. 1728 1732 $all_paths = array(); ··· 1732 1736 } 1733 1737 } 1734 1738 $all_paths = array_keys($all_paths); 1735 - 1736 - // Save the affected paths; we'll use them later to query Owners. 1737 - $this->affectedPaths = $all_paths; 1738 1739 1739 1740 $path_ids = 1740 1741 PhabricatorRepositoryCommitChangeParserWorker::lookupOrCreatePaths(
+7
src/applications/owners/controller/PhabricatorOwnersDetailController.php
··· 184 184 } 185 185 $view->addProperty(pht('Owners'), $owner_list); 186 186 187 + 188 + $dominion = $package->getDominion(); 189 + $dominion_map = PhabricatorOwnersPackage::getDominionOptionsMap(); 190 + $spec = idx($dominion_map, $dominion, array()); 191 + $name = idx($spec, 'short', $dominion); 192 + $view->addProperty(pht('Dominion'), $name); 193 + 187 194 $auto = $package->getAutoReview(); 188 195 $autoreview_map = PhabricatorOwnersPackage::getAutoreviewOptionsMap(); 189 196 $spec = idx($autoreview_map, $auto, array());
+13
src/applications/owners/editor/PhabricatorOwnersPackageEditEngine.php
··· 87 87 $autoreview_map = PhabricatorOwnersPackage::getAutoreviewOptionsMap(); 88 88 $autoreview_map = ipull($autoreview_map, 'name'); 89 89 90 + $dominion_map = PhabricatorOwnersPackage::getDominionOptionsMap(); 91 + $dominion_map = ipull($dominion_map, 'name'); 92 + 90 93 return array( 91 94 id(new PhabricatorTextEditField()) 92 95 ->setKey('name') ··· 103 106 ->setDatasource(new PhabricatorProjectOrUserDatasource()) 104 107 ->setIsCopyable(true) 105 108 ->setValue($object->getOwnerPHIDs()), 109 + id(new PhabricatorSelectEditField()) 110 + ->setKey('dominion') 111 + ->setLabel(pht('Dominion')) 112 + ->setDescription( 113 + pht('Change package dominion rules.')) 114 + ->setTransactionType( 115 + PhabricatorOwnersPackageTransaction::TYPE_DOMINION) 116 + ->setIsCopyable(true) 117 + ->setValue($object->getDominion()) 118 + ->setOptions($dominion_map), 106 119 id(new PhabricatorSelectEditField()) 107 120 ->setKey('autoReview') 108 121 ->setLabel(pht('Auto Review'))
+28
src/applications/owners/editor/PhabricatorOwnersPackageTransactionEditor.php
··· 21 21 $types[] = PhabricatorOwnersPackageTransaction::TYPE_PATHS; 22 22 $types[] = PhabricatorOwnersPackageTransaction::TYPE_STATUS; 23 23 $types[] = PhabricatorOwnersPackageTransaction::TYPE_AUTOREVIEW; 24 + $types[] = PhabricatorOwnersPackageTransaction::TYPE_DOMINION; 24 25 25 26 $types[] = PhabricatorTransactions::TYPE_VIEW_POLICY; 26 27 $types[] = PhabricatorTransactions::TYPE_EDIT_POLICY; ··· 50 51 return $object->getStatus(); 51 52 case PhabricatorOwnersPackageTransaction::TYPE_AUTOREVIEW: 52 53 return $object->getAutoReview(); 54 + case PhabricatorOwnersPackageTransaction::TYPE_DOMINION: 55 + return $object->getDominion(); 53 56 } 54 57 } 55 58 ··· 62 65 case PhabricatorOwnersPackageTransaction::TYPE_DESCRIPTION: 63 66 case PhabricatorOwnersPackageTransaction::TYPE_STATUS: 64 67 case PhabricatorOwnersPackageTransaction::TYPE_AUTOREVIEW: 68 + case PhabricatorOwnersPackageTransaction::TYPE_DOMINION: 65 69 return $xaction->getNewValue(); 66 70 case PhabricatorOwnersPackageTransaction::TYPE_PATHS: 67 71 $new = $xaction->getNewValue(); ··· 119 123 return; 120 124 case PhabricatorOwnersPackageTransaction::TYPE_AUTOREVIEW: 121 125 $object->setAutoReview($xaction->getNewValue()); 126 + return; 127 + case PhabricatorOwnersPackageTransaction::TYPE_DOMINION: 128 + $object->setDominion($xaction->getNewValue()); 122 129 return; 123 130 } 124 131 ··· 135 142 case PhabricatorOwnersPackageTransaction::TYPE_AUDITING: 136 143 case PhabricatorOwnersPackageTransaction::TYPE_STATUS: 137 144 case PhabricatorOwnersPackageTransaction::TYPE_AUTOREVIEW: 145 + case PhabricatorOwnersPackageTransaction::TYPE_DOMINION: 138 146 return; 139 147 case PhabricatorOwnersPackageTransaction::TYPE_OWNERS: 140 148 $old = $xaction->getOldValue(); ··· 242 250 pht('Invalid'), 243 251 pht( 244 252 'Autoreview setting "%s" is not valid. '. 253 + 'Valid settings are: %s.', 254 + $new, 255 + implode(', ', $valid)), 256 + $xaction); 257 + } 258 + } 259 + break; 260 + case PhabricatorOwnersPackageTransaction::TYPE_DOMINION: 261 + $map = PhabricatorOwnersPackage::getDominionOptionsMap(); 262 + foreach ($xactions as $xaction) { 263 + $new = $xaction->getNewValue(); 264 + 265 + if (empty($map[$new])) { 266 + $valid = array_keys($map); 267 + 268 + $errors[] = new PhabricatorApplicationTransactionValidationError( 269 + $type, 270 + pht('Invalid'), 271 + pht( 272 + 'Dominion setting "%s" is not valid. '. 245 273 'Valid settings are: %s.', 246 274 $new, 247 275 implode(', ', $valid)),
+14
src/applications/owners/query/PhabricatorOwnersPackageQuery.php
··· 351 351 } 352 352 353 353 $packages = $this->controlResults; 354 + $weak_dominion = PhabricatorOwnersPackage::DOMINION_WEAK; 354 355 355 356 $matches = array(); 356 357 foreach ($packages as $package_id => $package) { ··· 373 374 if ($best_match && $include) { 374 375 $matches[$package_id] = array( 375 376 'strength' => $best_match, 377 + 'weak' => ($package->getDominion() == $weak_dominion), 376 378 'package' => $package, 377 379 ); 378 380 } ··· 380 382 381 383 $matches = isort($matches, 'strength'); 382 384 $matches = array_reverse($matches); 385 + 386 + $first_id = null; 387 + foreach ($matches as $package_id => $match) { 388 + if ($first_id === null) { 389 + $first_id = $package_id; 390 + continue; 391 + } 392 + 393 + if ($match['weak']) { 394 + unset($matches[$package_id]); 395 + } 396 + } 383 397 384 398 return array_values(ipull($matches, 'package')); 385 399 }
+17 -1
src/applications/owners/storage/PhabricatorOwnersPackage.php
··· 21 21 protected $status; 22 22 protected $viewPolicy; 23 23 protected $editPolicy; 24 + protected $dominion; 24 25 25 26 private $paths = self::ATTACHABLE; 26 27 private $owners = self::ATTACHABLE; ··· 51 52 return id(new PhabricatorOwnersPackage()) 52 53 ->setAuditingEnabled(0) 53 54 ->setAutoReview(self::AUTOREVIEW_NONE) 55 + ->setDominion(self::DOMINION_STRONG) 54 56 ->setViewPolicy($view_policy) 55 57 ->setEditPolicy($edit_policy) 56 58 ->attachPaths(array()) ··· 83 85 ); 84 86 } 85 87 88 + public static function getDominionOptionsMap() { 89 + return array( 90 + self::DOMINION_STRONG => array( 91 + 'name' => pht('Strong (Control All Paths)'), 92 + 'short' => pht('Strong'), 93 + ), 94 + self::DOMINION_WEAK => array( 95 + 'name' => pht('Weak (Control Unowned Paths)'), 96 + 'short' => pht('Weak'), 97 + ), 98 + ); 99 + } 100 + 86 101 protected function getConfiguration() { 87 102 return array( 88 103 // This information is better available from the history table. ··· 97 112 'mailKey' => 'bytes20', 98 113 'status' => 'text32', 99 114 'autoReview' => 'text32', 115 + 'dominion' => 'text32', 100 116 ), 101 117 ) + parent::getConfiguration(); 102 118 } ··· 193 209 foreach (array_chunk(array_keys($fragments), 128) as $chunk) { 194 210 $rows[] = queryfx_all( 195 211 $conn, 196 - 'SELECT pkg.id, "strong" dominion, p.excluded, p.path 212 + 'SELECT pkg.id, pkg.dominion, p.excluded, p.path 197 213 FROM %T pkg JOIN %T p ON p.packageID = pkg.id 198 214 WHERE p.path IN (%Ls) %Q', 199 215 $package->getTableName(),
+13
src/applications/owners/storage/PhabricatorOwnersPackageTransaction.php
··· 11 11 const TYPE_PATHS = 'owners.paths'; 12 12 const TYPE_STATUS = 'owners.status'; 13 13 const TYPE_AUTOREVIEW = 'owners.autoreview'; 14 + const TYPE_DOMINION = 'owners.dominion'; 14 15 15 16 public function getApplicationName() { 16 17 return 'owners'; ··· 153 154 154 155 return pht( 155 156 '%s adjusted autoreview from "%s" to "%s".', 157 + $this->renderHandleLink($author_phid), 158 + $old, 159 + $new); 160 + case self::TYPE_DOMINION: 161 + $map = PhabricatorOwnersPackage::getDominionOptionsMap(); 162 + $map = ipull($map, 'short'); 163 + 164 + $old = idx($map, $old, $old); 165 + $new = idx($map, $new, $new); 166 + 167 + return pht( 168 + '%s adjusted package dominion rules from "%s" to "%s".', 156 169 $this->renderHandleLink($author_phid), 157 170 $old, 158 171 $new);
+35 -1
src/docs/user/userguide/owners.diviner
··· 45 45 which affect them in Diffusion or Differential. 46 46 47 47 48 + Dominion 49 + ======== 50 + 51 + The **Dominion** option allows you to control how ownership cascades when 52 + multiple packages own a path. The dominion rules are: 53 + 54 + **Strong Dominion.** This is the default. In this mode, the package will always 55 + own all files matching its configured paths, even if another package also owns 56 + them. 57 + 58 + For example, if the package owns `a/`, it will always own `a/b/c.z` even if 59 + another package owns `a/b/`. In this case, both packages will own `a/b/c.z`. 60 + 61 + This mode prevents users from stealing files away from the package by defining 62 + more narrow ownership rules in new packages, but enforces hierarchical 63 + ownership rules. 64 + 65 + **Weak Dominion.** In this mode, the package will only own files which do not 66 + match a more specific path in another package. 67 + 68 + For example, if the package owns `a/` but another package owns `a/b/`, the 69 + package will no longer consider `a/b/c.z` to be a file it owns because another 70 + package matches the path with a more specific rule. 71 + 72 + This mode lets you to define rules without implicit hierarchical ownership, 73 + but allows users to steal files away from a package by defining a more 74 + specific package. 75 + 76 + For more details on files which match multiple packages, see 77 + "Files in Multiple Packages", below. 78 + 79 + 48 80 Auto Review 49 81 =========== 50 82 ··· 93 125 "Android Application", and "Design Assets". 94 126 95 127 (You can use an "exclude" rule if you want to make a different package with a 96 - more specific claim the owner of a file or subdirectory.) 128 + more specific claim the owner of a file or subdirectory. You can also change 129 + the **Dominion** setting for a package to let it give up ownership of paths 130 + owned by another package.)