@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 Owners packages to be configured to ignore generated paths in Differential

Summary:
Depends on D19427. Ref T13130. See PHI251. Support configuring owners packages so they ignore generated paths.

This is still a little rough. A couple limitations:

- It's hard to figure out how to use this control if you don't know what it's for, but we don't currently have a "CheckboxesEditField". I may add that soon.
- The attribute ignore list doesn't apply to Diffusion, only Differential, which isn't obvious. I'll either try to make it work in Diffusion or note this somewhere.
- No documentation yet (which could mitigate the other two issues a bit).

But the actual behavior seems to work fine.

Test Plan:
- Set a package to ignore paths with the "generated" attribute. Saw the package stop matching generated paths in Differential.
- Removed the attribute from the ignore list.
- Tried to set invalid attributes, got sensible errors.
- Queried a package with Conduit, got the ignored attribute list.

Reviewers: amckinley

Reviewed By: amckinley

Subscribers: PHID-OPKG-gm6ozazyms6q6i22gyam

Maniphest Tasks: T13130

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

+145 -2
+2
resources/sql/autopatches/20180504.owners.03.properties.sql
··· 1 + ALTER TABLE {$NAMESPACE}_owners.owners_package 2 + ADD properties LONGTEXT NOT NULL COLLATE {$COLLATE_TEXT};
+2
resources/sql/autopatches/20180504.owners.04.default.sql
··· 1 + UPDATE {$NAMESPACE}_owners.owners_package 2 + SET properties = '{}' WHERE properties = '';
+2
src/__phutil_library_map__.php
··· 3572 3572 'PhabricatorOwnersPackageFerretEngine' => 'applications/owners/search/PhabricatorOwnersPackageFerretEngine.php', 3573 3573 'PhabricatorOwnersPackageFulltextEngine' => 'applications/owners/search/PhabricatorOwnersPackageFulltextEngine.php', 3574 3574 'PhabricatorOwnersPackageFunctionDatasource' => 'applications/owners/typeahead/PhabricatorOwnersPackageFunctionDatasource.php', 3575 + 'PhabricatorOwnersPackageIgnoredTransaction' => 'applications/owners/xaction/PhabricatorOwnersPackageIgnoredTransaction.php', 3575 3576 'PhabricatorOwnersPackageNameNgrams' => 'applications/owners/storage/PhabricatorOwnersPackageNameNgrams.php', 3576 3577 'PhabricatorOwnersPackageNameTransaction' => 'applications/owners/xaction/PhabricatorOwnersPackageNameTransaction.php', 3577 3578 'PhabricatorOwnersPackageOwnerDatasource' => 'applications/owners/typeahead/PhabricatorOwnersPackageOwnerDatasource.php', ··· 9321 9322 'PhabricatorOwnersPackageFerretEngine' => 'PhabricatorFerretEngine', 9322 9323 'PhabricatorOwnersPackageFulltextEngine' => 'PhabricatorFulltextEngine', 9323 9324 'PhabricatorOwnersPackageFunctionDatasource' => 'PhabricatorTypeaheadCompositeDatasource', 9325 + 'PhabricatorOwnersPackageIgnoredTransaction' => 'PhabricatorOwnersPackageTransactionType', 9324 9326 'PhabricatorOwnersPackageNameNgrams' => 'PhabricatorSearchNgrams', 9325 9327 'PhabricatorOwnersPackageNameTransaction' => 'PhabricatorOwnersPackageTransactionType', 9326 9328 'PhabricatorOwnersPackageOwnerDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
+10
src/applications/owners/controller/PhabricatorOwnersDetailController.php
··· 201 201 } 202 202 $view->addProperty(pht('Auditing'), $auditing); 203 203 204 + $ignored = $package->getIgnoredPathAttributes(); 205 + $ignored = array_keys($ignored); 206 + if ($ignored) { 207 + $ignored = implode(', ', $ignored); 208 + } else { 209 + $ignored = phutil_tag('em', array(), pht('None')); 210 + } 211 + 212 + $view->addProperty(pht('Ignored Attributes'), $ignored); 213 + 204 214 $description = $package->getDescription(); 205 215 if (strlen($description)) { 206 216 $description = new PHUIRemarkupView($viewer, $description);
+7
src/applications/owners/editor/PhabricatorOwnersPackageEditEngine.php
··· 162 162 ->setIsConduitOnly(true) 163 163 ->setValue($object->getStatus()) 164 164 ->setOptions($object->getStatusNameMap()), 165 + id(new PhabricatorStringListEditField()) 166 + ->setKey('ignored') 167 + ->setLabel(pht('Ignored Attributes')) 168 + ->setDescription(pht('Ignore paths with any of these attributes.')) 169 + ->setTransactionType( 170 + PhabricatorOwnersPackageIgnoredTransaction::TRANSACTIONTYPE) 171 + ->setValue(array_keys($object->getIgnoredPathAttributes())), 165 172 id(new PhabricatorConduitEditField()) 166 173 ->setKey('paths.set') 167 174 ->setLabel(pht('Paths'))
+37 -2
src/applications/owners/storage/PhabricatorOwnersPackage.php
··· 20 20 protected $viewPolicy; 21 21 protected $editPolicy; 22 22 protected $dominion; 23 + protected $properties = array(); 23 24 24 25 private $paths = self::ATTACHABLE; 25 26 private $owners = self::ATTACHABLE; ··· 39 40 40 41 const DOMINION_STRONG = 'strong'; 41 42 const DOMINION_WEAK = 'weak'; 43 + 44 + const PROPERTY_IGNORED = 'ignored'; 42 45 43 46 public static function initializeNewPackage(PhabricatorUser $actor) { 44 47 $app = id(new PhabricatorApplicationQuery()) ··· 117 120 // This information is better available from the history table. 118 121 self::CONFIG_TIMESTAMPS => false, 119 122 self::CONFIG_AUX_PHID => true, 123 + self::CONFIG_SERIALIZATION => array( 124 + 'properties' => self::SERIALIZATION_JSON, 125 + ), 120 126 self::CONFIG_COLUMN_SCHEMA => array( 121 127 'name' => 'sort', 122 128 'description' => 'text', ··· 137 143 } 138 144 139 145 public function getMustMatchUngeneratedPaths() { 140 - // TODO: For now, there's no way to actually configure this. 141 - return false; 146 + $ignore_attributes = $this->getIgnoredPathAttributes(); 147 + return !empty($ignore_attributes['generated']); 148 + } 149 + 150 + public function getPackageProperty($key, $default = null) { 151 + return idx($this->properties, $key, $default); 152 + } 153 + 154 + public function setPackageProperty($key, $value) { 155 + $this->properties[$key] = $value; 156 + return $this; 157 + } 158 + 159 + public function getIgnoredPathAttributes() { 160 + return $this->getPackageProperty(self::PROPERTY_IGNORED, array()); 161 + } 162 + 163 + public function setIgnoredPathAttributes(array $attributes) { 164 + return $this->setPackageProperty(self::PROPERTY_IGNORED, $attributes); 142 165 } 143 166 144 167 public function loadOwners() { ··· 679 702 ->setKey('dominion') 680 703 ->setType('map<string, wild>') 681 704 ->setDescription(pht('Dominion setting information.')), 705 + id(new PhabricatorConduitSearchFieldSpecification()) 706 + ->setKey('ignored') 707 + ->setType('map<string, wild>') 708 + ->setDescription(pht('Ignored attribute information.')), 682 709 ); 683 710 } 684 711 ··· 732 759 'short' => $dominion_short, 733 760 ); 734 761 762 + // Force this to always emit as a JSON object even if empty, never as 763 + // a JSON list. 764 + $ignored = $this->getIgnoredPathAttributes(); 765 + if (!$ignored) { 766 + $ignored = (object)array(); 767 + } 768 + 735 769 return array( 736 770 'name' => $this->getName(), 737 771 'description' => $this->getDescription(), ··· 740 774 'review' => $review, 741 775 'audit' => $audit, 742 776 'dominion' => $dominion, 777 + 'ignored' => $ignored, 743 778 ); 744 779 } 745 780
+85
src/applications/owners/xaction/PhabricatorOwnersPackageIgnoredTransaction.php
··· 1 + <?php 2 + 3 + final class PhabricatorOwnersPackageIgnoredTransaction 4 + extends PhabricatorOwnersPackageTransactionType { 5 + 6 + const TRANSACTIONTYPE = 'owners.ignored'; 7 + 8 + public function generateOldValue($object) { 9 + return $object->getIgnoredPathAttributes(); 10 + } 11 + 12 + public function generateNewValue($object, $value) { 13 + return array_fill_keys($value, true); 14 + } 15 + 16 + public function applyInternalEffects($object, $value) { 17 + $object->setIgnoredPathAttributes($value); 18 + } 19 + 20 + public function getTitle() { 21 + $old = array_keys($this->getOldValue()); 22 + $new = array_keys($this->getNewValue()); 23 + 24 + $add = array_diff($new, $old); 25 + $rem = array_diff($old, $new); 26 + 27 + $all_n = new PhutilNumber(count($add) + count($rem)); 28 + $add_n = phutil_count($add); 29 + $rem_n = phutil_count($rem); 30 + 31 + if ($new && $old) { 32 + return pht( 33 + '%s changed %s ignored attribute(s), added %s: %s; removed %s: %s.', 34 + $this->renderAuthor(), 35 + $all_n, 36 + $add_n, 37 + $this->renderValueList($add), 38 + $rem_n, 39 + $this->renderValueList($rem)); 40 + } else if ($new) { 41 + return pht( 42 + '%s changed %s ignored attribute(s), added %s: %s.', 43 + $this->renderAuthor(), 44 + $all_n, 45 + $add_n, 46 + $this->rendervalueList($add)); 47 + } else { 48 + return pht( 49 + '%s changed %s ignored attribute(s), removed %s: %s.', 50 + $this->renderAuthor(), 51 + $all_n, 52 + $rem_n, 53 + $this->rendervalueList($rem)); 54 + } 55 + } 56 + 57 + public function validateTransactions($object, array $xactions) { 58 + $errors = array(); 59 + 60 + $valid_attributes = array( 61 + 'generated' => true, 62 + ); 63 + 64 + foreach ($xactions as $xaction) { 65 + $new = $xaction->getNewValue(); 66 + 67 + foreach ($new as $attribute) { 68 + if (isset($valid_attributes[$attribute])) { 69 + continue; 70 + } 71 + 72 + $errors[] = $this->newInvalidError( 73 + pht( 74 + 'Changeset attribute "%s" is not valid. Valid changeset '. 75 + 'attributes are: %s.', 76 + $attribute, 77 + implode(', ', array_keys($valid_attributes))), 78 + $xaction); 79 + } 80 + } 81 + 82 + return $errors; 83 + } 84 + 85 + }