@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 Harbormaster build plans to be disabled

Summary: Fixes T4187. Ref T1049. Allows build plans to be enabled or disabled.

Test Plan: Enabled and disabled build plans.

Reviewers: btrahan

Reviewed By: btrahan

CC: aran

Maniphest Tasks: T4187, T1049

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

+214 -14
+2
src/__phutil_library_map__.php
··· 726 726 'HarbormasterPHIDTypeBuildTarget' => 'applications/harbormaster/phid/HarbormasterPHIDTypeBuildTarget.php', 727 727 'HarbormasterPHIDTypeBuildable' => 'applications/harbormaster/phid/HarbormasterPHIDTypeBuildable.php', 728 728 'HarbormasterPlanController' => 'applications/harbormaster/controller/HarbormasterPlanController.php', 729 + 'HarbormasterPlanDisableController' => 'applications/harbormaster/controller/HarbormasterPlanDisableController.php', 729 730 'HarbormasterPlanEditController' => 'applications/harbormaster/controller/HarbormasterPlanEditController.php', 730 731 'HarbormasterPlanListController' => 'applications/harbormaster/controller/HarbormasterPlanListController.php', 731 732 'HarbormasterPlanOrderController' => 'applications/harbormaster/controller/HarbormasterPlanOrderController.php', ··· 3155 3156 'HarbormasterPHIDTypeBuildTarget' => 'PhabricatorPHIDType', 3156 3157 'HarbormasterPHIDTypeBuildable' => 'PhabricatorPHIDType', 3157 3158 'HarbormasterPlanController' => 'PhabricatorController', 3159 + 'HarbormasterPlanDisableController' => 'HarbormasterPlanController', 3158 3160 'HarbormasterPlanEditController' => 'HarbormasterPlanController', 3159 3161 'HarbormasterPlanListController' => 3160 3162 array(
+1
src/applications/harbormaster/application/PhabricatorApplicationHarbormaster.php
··· 66 66 => 'HarbormasterPlanListController', 67 67 'edit/(?:(?P<id>\d+)/)?' => 'HarbormasterPlanEditController', 68 68 'order/(?:(?P<id>\d+)/)?' => 'HarbormasterPlanOrderController', 69 + 'disable/(?P<id>\d+)/' => 'HarbormasterPlanDisableController', 69 70 '(?P<id>\d+)/' => 'HarbormasterPlanViewController', 70 71 ), 71 72 ),
+76
src/applications/harbormaster/controller/HarbormasterPlanDisableController.php
··· 1 + <?php 2 + 3 + final class HarbormasterPlanDisableController 4 + extends HarbormasterPlanController { 5 + 6 + private $id; 7 + 8 + public function willProcessRequest(array $data) { 9 + $this->id = $data['id']; 10 + } 11 + 12 + public function processRequest() { 13 + $request = $this->getRequest(); 14 + $viewer = $request->getUser(); 15 + 16 + $this->requireApplicationCapability( 17 + HarbormasterCapabilityManagePlans::CAPABILITY); 18 + 19 + $plan = id(new HarbormasterBuildPlanQuery()) 20 + ->setViewer($viewer) 21 + ->withIDs(array($this->id)) 22 + ->executeOne(); 23 + if (!$plan) { 24 + return new Aphront404Response(); 25 + } 26 + 27 + $plan_uri = $this->getApplicationURI('plan/'.$plan->getID().'/'); 28 + 29 + if ($request->isFormPost()) { 30 + 31 + $type_status = HarbormasterBuildPlanTransaction::TYPE_STATUS; 32 + 33 + $v_status = $plan->isDisabled() 34 + ? HarbormasterBuildPlan::STATUS_ACTIVE 35 + : HarbormasterBuildPlan::STATUS_DISABLED; 36 + 37 + $xactions = array(); 38 + 39 + $xactions[] = id(new HarbormasterBuildPlanTransaction()) 40 + ->setTransactionType($type_status) 41 + ->setNewValue($v_status); 42 + 43 + $editor = id(new HarbormasterBuildPlanEditor()) 44 + ->setActor($viewer) 45 + ->setContinueOnNoEffect(true) 46 + ->setContinueOnMissingFields(true) 47 + ->setContentSourceFromRequest($request); 48 + 49 + $editor->applyTransactions($plan, $xactions); 50 + 51 + return id(new AphrontRedirectResponse())->setURI($plan_uri); 52 + } 53 + 54 + if ($plan->isDisabled()) { 55 + $title = pht('Enable Build Plan'); 56 + $body = pht('Enable this build plan?'); 57 + $button = pht('Enable Plan'); 58 + } else { 59 + $title = pht('Disable Build Plan'); 60 + $body = pht( 61 + 'Disable this build plan? It will no longer be executed '. 62 + 'automatically.'); 63 + $button = pht('Disable Plan'); 64 + } 65 + 66 + $dialog = id(new AphrontDialogView()) 67 + ->setUser($viewer) 68 + ->setTitle($title) 69 + ->appendChild($body) 70 + ->addSubmitButton($button) 71 + ->addCancelButton($plan_uri); 72 + 73 + return id(new AphrontDialogResponse())->setDialog($dialog); 74 + } 75 + 76 + }
+4
src/applications/harbormaster/controller/HarbormasterPlanListController.php
··· 39 39 ->setObjectName(pht('Plan %d', $plan->getID())) 40 40 ->setHeader($plan->getName()); 41 41 42 + if ($plan->isDisabled()) { 43 + $item->setDisabled(true); 44 + } 45 + 42 46 $item->setHref($this->getApplicationURI("plan/{$id}/")); 43 47 44 48 $list->addItem($item);
+18
src/applications/harbormaster/controller/HarbormasterPlanViewController.php
··· 178 178 ->setDisabled(!$can_edit) 179 179 ->setIcon('edit')); 180 180 181 + if ($plan->isDisabled()) { 182 + $list->addAction( 183 + id(new PhabricatorActionView()) 184 + ->setName(pht('Enable Plan')) 185 + ->setHref($this->getApplicationURI("plan/disable/{$id}/")) 186 + ->setWorkflow(true) 187 + ->setDisabled(!$can_edit) 188 + ->setIcon('enable')); 189 + } else { 190 + $list->addAction( 191 + id(new PhabricatorActionView()) 192 + ->setName(pht('Disable Plan')) 193 + ->setHref($this->getApplicationURI("plan/disable/{$id}/")) 194 + ->setWorkflow(true) 195 + ->setDisabled(!$can_edit) 196 + ->setIcon('disable')); 197 + } 198 + 181 199 $list->addAction( 182 200 id(new PhabricatorActionView()) 183 201 ->setName(pht('Add Build Step'))
+9
src/applications/harbormaster/editor/HarbormasterBuildPlanEditor.php
··· 6 6 public function getTransactionTypes() { 7 7 $types = parent::getTransactionTypes(); 8 8 $types[] = HarbormasterBuildPlanTransaction::TYPE_NAME; 9 + $types[] = HarbormasterBuildPlanTransaction::TYPE_STATUS; 9 10 $types[] = PhabricatorTransactions::TYPE_COMMENT; 10 11 return $types; 11 12 } ··· 19 20 return null; 20 21 } 21 22 return $object->getName(); 23 + case HarbormasterBuildPlanTransaction::TYPE_STATUS: 24 + return $object->getPlanStatus(); 22 25 } 23 26 24 27 return parent::getCustomTransactionOldValue($object, $xaction); ··· 29 32 PhabricatorApplicationTransaction $xaction) { 30 33 switch ($xaction->getTransactionType()) { 31 34 case HarbormasterBuildPlanTransaction::TYPE_NAME: 35 + return $xaction->getNewValue(); 36 + case HarbormasterBuildPlanTransaction::TYPE_STATUS: 32 37 return $xaction->getNewValue(); 33 38 } 34 39 return parent::getCustomTransactionNewValue($object, $xaction); ··· 41 46 case HarbormasterBuildPlanTransaction::TYPE_NAME: 42 47 $object->setName($xaction->getNewValue()); 43 48 return; 49 + case HarbormasterBuildPlanTransaction::TYPE_STATUS: 50 + $object->setPlanStatus($xaction->getNewValue()); 51 + return; 44 52 } 45 53 return parent::applyCustomInternalTransaction($object, $xaction); 46 54 } ··· 50 58 PhabricatorApplicationTransaction $xaction) { 51 59 switch ($xaction->getTransactionType()) { 52 60 case HarbormasterBuildPlanTransaction::TYPE_NAME: 61 + case HarbormasterBuildPlanTransaction::TYPE_STATUS: 53 62 return; 54 63 } 55 64 return parent::applyCustomExternalTransaction($object, $xaction);
+13
src/applications/harbormaster/query/HarbormasterBuildPlanQuery.php
··· 5 5 6 6 private $ids; 7 7 private $phids; 8 + private $statuses; 8 9 9 10 public function withIDs(array $ids) { 10 11 $this->ids = $ids; ··· 13 14 14 15 public function withPHIDs(array $phids) { 15 16 $this->phids = $phids; 17 + return $this; 18 + } 19 + 20 + public function withStatuses(array $statuses) { 21 + $this->statuses = $statuses; 16 22 return $this; 17 23 } 18 24 ··· 47 53 $conn_r, 48 54 'phid IN (%Ls)', 49 55 $this->phids); 56 + } 57 + 58 + if ($this->statuses) { 59 + $where[] = qsprintf( 60 + $conn_r, 61 + 'planStatus IN (%Ls)', 62 + $this->statuses); 50 63 } 51 64 52 65 $where[] = $this->buildPagingClause($conn_r);
+33
src/applications/harbormaster/query/HarbormasterBuildPlanSearchEngine.php
··· 6 6 public function buildSavedQueryFromRequest(AphrontRequest $request) { 7 7 $saved = new PhabricatorSavedQuery(); 8 8 9 + $saved->setParameter( 10 + 'status', 11 + $this->readListFromRequest($request, 'status')); 12 + 9 13 return $saved; 10 14 } 11 15 12 16 public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) { 13 17 $query = id(new HarbormasterBuildPlanQuery()); 18 + 19 + $status = $saved->getParameter('status', array()); 20 + if ($status) { 21 + $query->withStatuses($status); 22 + } 14 23 15 24 return $query; 16 25 } ··· 19 28 AphrontFormView $form, 20 29 PhabricatorSavedQuery $saved_query) { 21 30 31 + $status = $saved_query->getParameter('status', array()); 32 + 33 + $form 34 + ->appendChild( 35 + id(new AphrontFormCheckboxControl()) 36 + ->setLabel('Status') 37 + ->addCheckbox( 38 + 'status[]', 39 + HarbormasterBuildPlan::STATUS_ACTIVE, 40 + pht('Active'), 41 + in_array(HarbormasterBuildPlan::STATUS_ACTIVE, $status)) 42 + ->addCheckbox( 43 + 'status[]', 44 + HarbormasterBuildPlan::STATUS_DISABLED, 45 + pht('Disabled'), 46 + in_array(HarbormasterBuildPlan::STATUS_DISABLED, $status))); 47 + 22 48 } 23 49 24 50 protected function getURI($path) { ··· 27 53 28 54 public function getBuiltinQueryNames() { 29 55 $names = array( 56 + 'active' => pht('Active Plans'), 30 57 'all' => pht('All Plans'), 31 58 ); 32 59 ··· 39 66 $query->setQueryKey($query_key); 40 67 41 68 switch ($query_key) { 69 + case 'active': 70 + return $query->setParameter( 71 + 'status', 72 + array( 73 + HarbormasterBuildPlan::STATUS_ACTIVE, 74 + )); 42 75 case 'all': 43 76 return $query; 44 77 }
+6
src/applications/harbormaster/storage/HarbormasterBuildable.php
··· 77 77 ->withPHIDs($plan_phids) 78 78 ->execute(); 79 79 foreach ($plans as $plan) { 80 + if ($plan->isDisabled()) { 81 + // TODO: This should be communicated more clearly -- maybe we should 82 + // create the build but set the status to "disabled" or "derelict". 83 + continue; 84 + } 85 + 80 86 $build = HarbormasterBuild::initializeNewBuild( 81 87 PhabricatorUser::getOmnipotentUser()); 82 88 $build->setBuildablePHID($buildable->getPHID());
+8 -1
src/applications/harbormaster/storage/configuration/HarbormasterBuildPlan.php
··· 8 8 protected $name; 9 9 protected $planStatus; 10 10 11 + const STATUS_ACTIVE = 'active'; 12 + const STATUS_DISABLED = 'disabled'; 13 + 11 14 private $buildSteps = self::ATTACHABLE; 12 15 13 16 public static function initializeNewBuildPlan(PhabricatorUser $actor) { 14 17 return id(new HarbormasterBuildPlan()) 15 - ->setPlanStatus('active'); // TODO: Figure this out. 18 + ->setPlanStatus(self::STATUS_ACTIVE); 16 19 } 17 20 18 21 public function getConfiguration() { ··· 47 50 ->setViewer(PhabricatorUser::getOmnipotentUser()) 48 51 ->withBuildPlanPHIDs(array($this->getPHID())) 49 52 ->execute(); 53 + } 54 + 55 + public function isDisabled() { 56 + return ($this->getPlanStatus() == self::STATUS_DISABLED); 50 57 } 51 58 52 59
+11 -1
src/applications/harbormaster/storage/configuration/HarbormasterBuildPlanTransaction.php
··· 4 4 extends PhabricatorApplicationTransaction { 5 5 6 6 const TYPE_NAME = 'harbormaster:name'; 7 + const TYPE_STATUS = 'harbormaster:status'; 7 8 8 9 public function getApplicationName() { 9 10 return 'harbormaster'; ··· 65 66 $old, 66 67 $new); 67 68 } 68 - break; 69 + case self::TYPE_STATUS: 70 + if ($new == HarbormasterBuildPlan::STATUS_DISABLED) { 71 + return pht( 72 + '%s disabled this build plan.', 73 + $author_handle); 74 + } else { 75 + return pht( 76 + '%s enabled this build plan.', 77 + $author_handle); 78 + } 69 79 } 70 80 71 81 return parent::getTitle();
+33 -12
src/applications/search/engine/PhabricatorApplicationSearchEngine.php
··· 263 263 AphrontRequest $request, 264 264 $key, 265 265 array $allow_types = array()) { 266 - $list = $request->getArr($key, null); 267 - if ($list === null) { 268 - $list = $request->getStrList($key); 269 - } 266 + 267 + $list = $this->readListFromRequest($request, $key); 270 268 271 269 $phids = array(); 272 270 $names = array(); ··· 316 314 $key, 317 315 array $allow_types = array()) { 318 316 319 - $list = $request->getArr($key, null); 320 - if ($list === null) { 321 - $list = $request->getStrList($key); 322 - } 323 - 324 - if (!$list) { 325 - return array(); 326 - } 317 + $list = $this->readListFromRequest($request, $key); 327 318 328 319 $objects = id(new PhabricatorObjectQuery()) 329 320 ->setViewer($this->requireViewer()) ··· 343 334 unset($list[$key]); 344 335 } 345 336 } 337 + } 338 + 339 + return $list; 340 + } 341 + 342 + 343 + /** 344 + * Read a list of items from the request, in either array format or string 345 + * format: 346 + * 347 + * list[]=item1&list[]=item2 348 + * list=item1,item2 349 + * 350 + * This provides flexibility when constructing URIs, especially from external 351 + * sources. 352 + * 353 + * @param AphrontRequest Request to read PHIDs from. 354 + * @param string Key to read in the request. 355 + * @return list<string> List of values. 356 + */ 357 + protected function readListFromRequest( 358 + AphrontRequest $request, 359 + $key) { 360 + $list = $request->getArr($key, null); 361 + if ($list === null) { 362 + $list = $request->getStrList($key); 363 + } 364 + 365 + if (!$list) { 366 + return array(); 346 367 } 347 368 348 369 return $list;