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

Generate mail command documentation from active commands

Summary: Ref T7199. This needs some polish and isn't reachable from the UI, but technically has all of the information.

Test Plan:
{F355899}

{F355900}

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: epriestley

Maniphest Tasks: T7199

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

+260 -2
+2
src/__phutil_library_map__.php
··· 1291 1291 'PhabricatorApplicationDatasource' => 'applications/meta/typeahead/PhabricatorApplicationDatasource.php', 1292 1292 'PhabricatorApplicationDetailViewController' => 'applications/meta/controller/PhabricatorApplicationDetailViewController.php', 1293 1293 'PhabricatorApplicationEditController' => 'applications/meta/controller/PhabricatorApplicationEditController.php', 1294 + 'PhabricatorApplicationEmailCommandsController' => 'applications/meta/controller/PhabricatorApplicationEmailCommandsController.php', 1294 1295 'PhabricatorApplicationLaunchView' => 'applications/meta/view/PhabricatorApplicationLaunchView.php', 1295 1296 'PhabricatorApplicationPanelController' => 'applications/meta/controller/PhabricatorApplicationPanelController.php', 1296 1297 'PhabricatorApplicationQuery' => 'applications/meta/query/PhabricatorApplicationQuery.php', ··· 4562 4563 'PhabricatorApplicationDatasource' => 'PhabricatorTypeaheadDatasource', 4563 4564 'PhabricatorApplicationDetailViewController' => 'PhabricatorApplicationsController', 4564 4565 'PhabricatorApplicationEditController' => 'PhabricatorApplicationsController', 4566 + 'PhabricatorApplicationEmailCommandsController' => 'PhabricatorApplicationsController', 4565 4567 'PhabricatorApplicationLaunchView' => 'AphrontTagView', 4566 4568 'PhabricatorApplicationPanelController' => 'PhabricatorApplicationsController', 4567 4569 'PhabricatorApplicationQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
+4
src/applications/base/PhabricatorApplication.php
··· 189 189 return array(); 190 190 } 191 191 192 + public function getMailCommandObjects() { 193 + return array(); 194 + } 195 + 192 196 193 197 /* -( URI Routing )-------------------------------------------------------- */ 194 198
+8
src/applications/differential/application/PhabricatorDifferentialApplication.php
··· 186 186 ); 187 187 } 188 188 189 + public function getMailCommandObjects() { 190 + return array( 191 + 'revision' => array( 192 + 'object' => new DifferentialRevision(), 193 + ), 194 + ); 195 + } 196 + 189 197 }
+50 -2
src/applications/differential/command/DifferentialActionEmailCommand.php
··· 6 6 private $command; 7 7 private $action; 8 8 private $aliases; 9 + private $commandSummary; 10 + private $commandDescription; 9 11 10 12 public function getCommand() { 11 13 return $this->command; ··· 34 36 return $this->aliases; 35 37 } 36 38 39 + public function setCommandSummary($command_summary) { 40 + $this->commandSummary = $command_summary; 41 + return $this; 42 + } 43 + 44 + public function getCommandSummary() { 45 + return $this->commandSummary; 46 + } 47 + 48 + public function setCommandDescription($command_description) { 49 + $this->commandDescription = $command_description; 50 + return $this; 51 + } 52 + 53 + public function getCommandDescription() { 54 + return $this->commandDescription; 55 + } 56 + 37 57 public function getCommandObjects() { 38 58 $actions = array( 39 59 DifferentialAction::ACTION_REJECT => 'request', 40 60 DifferentialAction::ACTION_ABANDON => 'abandon', 41 61 DifferentialAction::ACTION_RECLAIM => 'reclaim', 42 62 DifferentialAction::ACTION_RESIGN => 'resign', 43 - DifferentialAction::ACTION_RETHINK => 'rethink', 63 + DifferentialAction::ACTION_RETHINK => 'planchanges', 44 64 DifferentialAction::ACTION_CLAIM => 'commandeer', 45 65 ); 46 66 ··· 51 71 $aliases = array( 52 72 DifferentialAction::ACTION_REJECT => array('reject'), 53 73 DifferentialAction::ACTION_CLAIM => array('claim'), 74 + DifferentialAction::ACTION_RETHINK => array('rethink'), 75 + ); 76 + 77 + $summaries = array( 78 + DifferentialAction::ACTION_REJECT => 79 + pht('Request changes to a revision.'), 80 + DifferentialAction::ACTION_ABANDON => 81 + pht('Abandon a revision.'), 82 + DifferentialAction::ACTION_RECLAIM => 83 + pht('Reclaim a revision.'), 84 + DifferentialAction::ACTION_RESIGN => 85 + pht('Resign from a revision.'), 86 + DifferentialAction::ACTION_RETHINK => 87 + pht('Plan changes to a revision.'), 88 + DifferentialAction::ACTION_CLAIM => 89 + pht('Commandeer a revision.'), 90 + DifferentialAction::ACTION_ACCEPT => 91 + pht('Accept a revision.'), 92 + ); 93 + 94 + $descriptions = array( 95 + 54 96 ); 55 97 56 98 $objects = array(); 57 99 foreach ($actions as $action => $keyword) { 58 100 $object = id(new DifferentialActionEmailCommand()) 59 101 ->setCommand($keyword) 60 - ->setAction($action); 102 + ->setAction($action) 103 + ->setCommandSummary($summaries[$action]); 61 104 62 105 if (isset($aliases[$action])) { 63 106 $object->setCommandAliases($aliases[$action]); 64 107 } 65 108 109 + if (isset($descriptions[$action])) { 110 + $object->setCommandDescription($descriptions[$action]); 111 + } 112 + 66 113 $objects[] = $object; 67 114 } 115 + 68 116 69 117 return $objects; 70 118 }
+8
src/applications/maniphest/application/PhabricatorManiphestApplication.php
··· 143 143 ); 144 144 } 145 145 146 + public function getMailCommandObjects() { 147 + return array( 148 + 'task' => array( 149 + 'object' => new ManiphestTask(), 150 + ), 151 + ); 152 + } 153 + 146 154 }
+17
src/applications/maniphest/command/ManiphestAssignEmailCommand.php
··· 7 7 return 'assign'; 8 8 } 9 9 10 + public function getCommandSyntax() { 11 + return '**!assign** //username//'; 12 + } 13 + 14 + public function getCommandSummary() { 15 + return pht('Assign a task to a specific user.'); 16 + } 17 + 18 + public function getCommandDescription() { 19 + return pht( 20 + 'To assign a task to another user, provide their username. For example, '. 21 + 'to assign a task to `alincoln`, write `!assign alincoln`.'. 22 + "\n\n". 23 + 'If you omit the username or the username is not valid, this behaves '. 24 + 'like `!claim` and assigns the task to you instead.'); 25 + } 26 + 10 27 public function buildTransactions( 11 28 PhabricatorUser $viewer, 12 29 PhabricatorApplicationTransactionInterface $object,
+4
src/applications/maniphest/command/ManiphestClaimEmailCommand.php
··· 7 7 return 'claim'; 8 8 } 9 9 10 + public function getCommandSummary() { 11 + return pht('Assign yourself as the owner of a task.'); 12 + } 13 + 10 14 public function buildTransactions( 11 15 PhabricatorUser $viewer, 12 16 PhabricatorApplicationTransactionInterface $object,
+4
src/applications/maniphest/command/ManiphestCloseEmailCommand.php
··· 7 7 return 'close'; 8 8 } 9 9 10 + public function getCommandSummary() { 11 + return pht('Close a task.'); 12 + } 13 + 10 14 public function buildTransactions( 11 15 PhabricatorUser $viewer, 12 16 PhabricatorApplicationTransactionInterface $object,
+2
src/applications/meta/application/PhabricatorApplicationsApplication.php
··· 41 41 => 'PhabricatorApplicationDetailViewController', 42 42 'edit/(?P<application>\w+)/' 43 43 => 'PhabricatorApplicationEditController', 44 + 'mailcommands/(?P<application>\w+)/(?P<type>\w+)/' 45 + => 'PhabricatorApplicationEmailCommandsController', 44 46 '(?P<application>\w+)/(?P<action>install|uninstall)/' 45 47 => 'PhabricatorApplicationUninstallController', 46 48 'panel/(?P<application>\w+)/(?P<panel>\w+)/(?P<path>.*)'
+109
src/applications/meta/controller/PhabricatorApplicationEmailCommandsController.php
··· 1 + <?php 2 + 3 + final class PhabricatorApplicationEmailCommandsController 4 + extends PhabricatorApplicationsController { 5 + 6 + public function shouldAllowPublic() { 7 + return true; 8 + } 9 + 10 + public function handleRequest(AphrontRequest $request) { 11 + $viewer = $this->getViewer(); 12 + $application = $request->getURIData('application'); 13 + 14 + $selected = id(new PhabricatorApplicationQuery()) 15 + ->setViewer($viewer) 16 + ->withClasses(array($application)) 17 + ->executeOne(); 18 + if (!$selected) { 19 + return new Aphront404Response(); 20 + } 21 + 22 + $specs = $selected->getMailCommandObjects(); 23 + $type = $request->getURIData('type'); 24 + if (empty($specs[$type])) { 25 + return new Aphront404Response(); 26 + } 27 + 28 + $spec = $specs[$type]; 29 + $commands = MetaMTAEmailTransactionCommand::getAllCommandsForObject( 30 + $spec['object']); 31 + 32 + $commands = msort($commands, 'getCommand'); 33 + 34 + $content = array(); 35 + 36 + $content[] = '= '.pht('Quick Reference'); 37 + $table = array(); 38 + $table[] = '| '.pht('Command').' | '.pht('Summary').' |'; 39 + $table[] = '|---|---|'; 40 + foreach ($commands as $command) { 41 + $summary = $command->getCommandSummary(); 42 + $table[] = '| '.$command->getCommandSyntax().' | '.$summary; 43 + } 44 + $table = implode("\n", $table); 45 + $content[] = $table; 46 + 47 + foreach ($commands as $command) { 48 + $content[] = '== !'.$command->getCommand().' =='; 49 + $content[] = $command->getCommandSummary(); 50 + 51 + $aliases = $command->getCommandAliases(); 52 + if ($aliases) { 53 + foreach ($aliases as $key => $alias) { 54 + $aliases[$key] = '!'.$alias; 55 + } 56 + $aliases = implode(', ', $aliases); 57 + } else { 58 + $aliases = '//None//'; 59 + } 60 + 61 + $syntax = $command->getCommandSyntax(); 62 + 63 + $table = array(); 64 + $table[] = '| '.pht('Property').' | '.pht('Value'); 65 + $table[] = '|---|---|'; 66 + $table[] = '| **'.pht('Syntax').'** | '.$syntax; 67 + $table[] = '| **'.pht('Aliases').'** | '.$aliases; 68 + $table[] = '| **'.pht('Class').'** | `'.get_class($command).'`'; 69 + $table = implode("\n", $table); 70 + 71 + $content[] = $table; 72 + 73 + $description = $command->getCommandDescription(); 74 + if ($description) { 75 + $content[] = $description; 76 + } 77 + } 78 + 79 + $content = implode("\n\n", $content); 80 + 81 + $crumbs = $this->buildApplicationCrumbs(); 82 + $this->addApplicationCrumb($crumbs, $selected); 83 + $crumbs->addTextCrumb(pht('Mail Commands')); 84 + 85 + $content_box = id(new PHUIBoxView()) 86 + ->addMargin(PHUI::MARGIN_LARGE) 87 + ->appendChild( 88 + PhabricatorMarkupEngine::renderOneObject( 89 + id(new PhabricatorMarkupOneOff())->setContent($content), 90 + 'default', 91 + $viewer)); 92 + 93 + $box = id(new PHUIObjectBoxView()) 94 + ->setHeaderText(pht('Mail Commands')) 95 + ->appendChild($content_box); 96 + 97 + return $this->buildApplicationPage( 98 + array( 99 + $crumbs, 100 + $box, 101 + ), 102 + array( 103 + 'title' => 'asdf', 104 + )); 105 + 106 + } 107 + 108 + 109 + }
+9
src/applications/meta/controller/PhabricatorApplicationsController.php
··· 21 21 return $this->buildSideNavView(true)->getMenu(); 22 22 } 23 23 24 + protected function addApplicationCrumb( 25 + PHUICrumbsView $crumbs, 26 + PhabricatorApplication $application) { 27 + 28 + $crumbs->addTextCrumb( 29 + $application->getName(), 30 + '/applications/view/'.get_class($application).'/'); 31 + } 32 + 24 33 }
+39
src/applications/metamta/command/MetaMTAEmailTransactionCommand.php
··· 1 1 <?php 2 2 3 + /** 4 + * @task docs Command Documentation 5 + */ 3 6 abstract class MetaMTAEmailTransactionCommand extends Phobject { 4 7 5 8 abstract public function getCommand(); 9 + 10 + /** 11 + * Return a brief human-readable description of the command effect. 12 + * 13 + * This should normally be one or two sentences briefly describing the 14 + * command behavior. 15 + * 16 + * @return string Brief human-readable remarkup. 17 + * @task docs 18 + */ 19 + abstract public function getCommandSummary(); 20 + 21 + 22 + /** 23 + * Return a one-line Remarkup description of command syntax for documentation. 24 + * 25 + * @return string Brief human-readable remarkup. 26 + * @task docs 27 + */ 28 + public function getCommandSyntax() { 29 + return '**!'.$this->getCommand().'**'; 30 + } 31 + 32 + /** 33 + * Return a longer human-readable description of the command effect. 34 + * 35 + * This can be as long as necessary to explain the command. 36 + * 37 + * @return string Human-readable remarkup of whatever length is desired. 38 + * @task docs 39 + */ 40 + public function getCommandDescription() { 41 + return null; 42 + } 43 + 6 44 abstract public function isCommandSupportedForObject( 7 45 PhabricatorApplicationTransactionInterface $object); 46 + 8 47 abstract public function buildTransactions( 9 48 PhabricatorUser $viewer, 10 49 PhabricatorApplicationTransactionInterface $object,
+4
src/applications/subscriptions/command/PhabricatorSubscriptionsUnsubscribeEmailCommand.php
··· 7 7 return 'unsubscribe'; 8 8 } 9 9 10 + public function getCommandSummary() { 11 + return pht('Remove yourself as a subscriber.'); 12 + } 13 + 10 14 public function isCommandSupportedForObject( 11 15 PhabricatorApplicationTransactionInterface $object) { 12 16 return ($object instanceof PhabricatorSubscribableInterface);