mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-19 13:22:42 +01:00
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
This commit is contained in:
parent
6f59b2ab87
commit
6f95b325c6
13 changed files with 260 additions and 2 deletions
|
@ -1291,6 +1291,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorApplicationDatasource' => 'applications/meta/typeahead/PhabricatorApplicationDatasource.php',
|
'PhabricatorApplicationDatasource' => 'applications/meta/typeahead/PhabricatorApplicationDatasource.php',
|
||||||
'PhabricatorApplicationDetailViewController' => 'applications/meta/controller/PhabricatorApplicationDetailViewController.php',
|
'PhabricatorApplicationDetailViewController' => 'applications/meta/controller/PhabricatorApplicationDetailViewController.php',
|
||||||
'PhabricatorApplicationEditController' => 'applications/meta/controller/PhabricatorApplicationEditController.php',
|
'PhabricatorApplicationEditController' => 'applications/meta/controller/PhabricatorApplicationEditController.php',
|
||||||
|
'PhabricatorApplicationEmailCommandsController' => 'applications/meta/controller/PhabricatorApplicationEmailCommandsController.php',
|
||||||
'PhabricatorApplicationLaunchView' => 'applications/meta/view/PhabricatorApplicationLaunchView.php',
|
'PhabricatorApplicationLaunchView' => 'applications/meta/view/PhabricatorApplicationLaunchView.php',
|
||||||
'PhabricatorApplicationPanelController' => 'applications/meta/controller/PhabricatorApplicationPanelController.php',
|
'PhabricatorApplicationPanelController' => 'applications/meta/controller/PhabricatorApplicationPanelController.php',
|
||||||
'PhabricatorApplicationQuery' => 'applications/meta/query/PhabricatorApplicationQuery.php',
|
'PhabricatorApplicationQuery' => 'applications/meta/query/PhabricatorApplicationQuery.php',
|
||||||
|
@ -4562,6 +4563,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorApplicationDatasource' => 'PhabricatorTypeaheadDatasource',
|
'PhabricatorApplicationDatasource' => 'PhabricatorTypeaheadDatasource',
|
||||||
'PhabricatorApplicationDetailViewController' => 'PhabricatorApplicationsController',
|
'PhabricatorApplicationDetailViewController' => 'PhabricatorApplicationsController',
|
||||||
'PhabricatorApplicationEditController' => 'PhabricatorApplicationsController',
|
'PhabricatorApplicationEditController' => 'PhabricatorApplicationsController',
|
||||||
|
'PhabricatorApplicationEmailCommandsController' => 'PhabricatorApplicationsController',
|
||||||
'PhabricatorApplicationLaunchView' => 'AphrontTagView',
|
'PhabricatorApplicationLaunchView' => 'AphrontTagView',
|
||||||
'PhabricatorApplicationPanelController' => 'PhabricatorApplicationsController',
|
'PhabricatorApplicationPanelController' => 'PhabricatorApplicationsController',
|
||||||
'PhabricatorApplicationQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
'PhabricatorApplicationQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||||
|
|
|
@ -189,6 +189,10 @@ abstract class PhabricatorApplication implements PhabricatorPolicyInterface {
|
||||||
return array();
|
return array();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getMailCommandObjects() {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -( URI Routing )-------------------------------------------------------- */
|
/* -( URI Routing )-------------------------------------------------------- */
|
||||||
|
|
||||||
|
|
|
@ -186,4 +186,12 @@ EOTEXT
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getMailCommandObjects() {
|
||||||
|
return array(
|
||||||
|
'revision' => array(
|
||||||
|
'object' => new DifferentialRevision(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,8 @@ final class DifferentialActionEmailCommand
|
||||||
private $command;
|
private $command;
|
||||||
private $action;
|
private $action;
|
||||||
private $aliases;
|
private $aliases;
|
||||||
|
private $commandSummary;
|
||||||
|
private $commandDescription;
|
||||||
|
|
||||||
public function getCommand() {
|
public function getCommand() {
|
||||||
return $this->command;
|
return $this->command;
|
||||||
|
@ -34,13 +36,31 @@ final class DifferentialActionEmailCommand
|
||||||
return $this->aliases;
|
return $this->aliases;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setCommandSummary($command_summary) {
|
||||||
|
$this->commandSummary = $command_summary;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCommandSummary() {
|
||||||
|
return $this->commandSummary;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setCommandDescription($command_description) {
|
||||||
|
$this->commandDescription = $command_description;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCommandDescription() {
|
||||||
|
return $this->commandDescription;
|
||||||
|
}
|
||||||
|
|
||||||
public function getCommandObjects() {
|
public function getCommandObjects() {
|
||||||
$actions = array(
|
$actions = array(
|
||||||
DifferentialAction::ACTION_REJECT => 'request',
|
DifferentialAction::ACTION_REJECT => 'request',
|
||||||
DifferentialAction::ACTION_ABANDON => 'abandon',
|
DifferentialAction::ACTION_ABANDON => 'abandon',
|
||||||
DifferentialAction::ACTION_RECLAIM => 'reclaim',
|
DifferentialAction::ACTION_RECLAIM => 'reclaim',
|
||||||
DifferentialAction::ACTION_RESIGN => 'resign',
|
DifferentialAction::ACTION_RESIGN => 'resign',
|
||||||
DifferentialAction::ACTION_RETHINK => 'rethink',
|
DifferentialAction::ACTION_RETHINK => 'planchanges',
|
||||||
DifferentialAction::ACTION_CLAIM => 'commandeer',
|
DifferentialAction::ACTION_CLAIM => 'commandeer',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -51,21 +71,49 @@ final class DifferentialActionEmailCommand
|
||||||
$aliases = array(
|
$aliases = array(
|
||||||
DifferentialAction::ACTION_REJECT => array('reject'),
|
DifferentialAction::ACTION_REJECT => array('reject'),
|
||||||
DifferentialAction::ACTION_CLAIM => array('claim'),
|
DifferentialAction::ACTION_CLAIM => array('claim'),
|
||||||
|
DifferentialAction::ACTION_RETHINK => array('rethink'),
|
||||||
|
);
|
||||||
|
|
||||||
|
$summaries = array(
|
||||||
|
DifferentialAction::ACTION_REJECT =>
|
||||||
|
pht('Request changes to a revision.'),
|
||||||
|
DifferentialAction::ACTION_ABANDON =>
|
||||||
|
pht('Abandon a revision.'),
|
||||||
|
DifferentialAction::ACTION_RECLAIM =>
|
||||||
|
pht('Reclaim a revision.'),
|
||||||
|
DifferentialAction::ACTION_RESIGN =>
|
||||||
|
pht('Resign from a revision.'),
|
||||||
|
DifferentialAction::ACTION_RETHINK =>
|
||||||
|
pht('Plan changes to a revision.'),
|
||||||
|
DifferentialAction::ACTION_CLAIM =>
|
||||||
|
pht('Commandeer a revision.'),
|
||||||
|
DifferentialAction::ACTION_ACCEPT =>
|
||||||
|
pht('Accept a revision.'),
|
||||||
|
);
|
||||||
|
|
||||||
|
$descriptions = array(
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
$objects = array();
|
$objects = array();
|
||||||
foreach ($actions as $action => $keyword) {
|
foreach ($actions as $action => $keyword) {
|
||||||
$object = id(new DifferentialActionEmailCommand())
|
$object = id(new DifferentialActionEmailCommand())
|
||||||
->setCommand($keyword)
|
->setCommand($keyword)
|
||||||
->setAction($action);
|
->setAction($action)
|
||||||
|
->setCommandSummary($summaries[$action]);
|
||||||
|
|
||||||
if (isset($aliases[$action])) {
|
if (isset($aliases[$action])) {
|
||||||
$object->setCommandAliases($aliases[$action]);
|
$object->setCommandAliases($aliases[$action]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isset($descriptions[$action])) {
|
||||||
|
$object->setCommandDescription($descriptions[$action]);
|
||||||
|
}
|
||||||
|
|
||||||
$objects[] = $object;
|
$objects[] = $object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return $objects;
|
return $objects;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -143,4 +143,12 @@ final class PhabricatorManiphestApplication extends PhabricatorApplication {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getMailCommandObjects() {
|
||||||
|
return array(
|
||||||
|
'task' => array(
|
||||||
|
'object' => new ManiphestTask(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,23 @@ final class ManiphestAssignEmailCommand
|
||||||
return 'assign';
|
return 'assign';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getCommandSyntax() {
|
||||||
|
return '**!assign** //username//';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCommandSummary() {
|
||||||
|
return pht('Assign a task to a specific user.');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCommandDescription() {
|
||||||
|
return pht(
|
||||||
|
'To assign a task to another user, provide their username. For example, '.
|
||||||
|
'to assign a task to `alincoln`, write `!assign alincoln`.'.
|
||||||
|
"\n\n".
|
||||||
|
'If you omit the username or the username is not valid, this behaves '.
|
||||||
|
'like `!claim` and assigns the task to you instead.');
|
||||||
|
}
|
||||||
|
|
||||||
public function buildTransactions(
|
public function buildTransactions(
|
||||||
PhabricatorUser $viewer,
|
PhabricatorUser $viewer,
|
||||||
PhabricatorApplicationTransactionInterface $object,
|
PhabricatorApplicationTransactionInterface $object,
|
||||||
|
|
|
@ -7,6 +7,10 @@ final class ManiphestClaimEmailCommand
|
||||||
return 'claim';
|
return 'claim';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getCommandSummary() {
|
||||||
|
return pht('Assign yourself as the owner of a task.');
|
||||||
|
}
|
||||||
|
|
||||||
public function buildTransactions(
|
public function buildTransactions(
|
||||||
PhabricatorUser $viewer,
|
PhabricatorUser $viewer,
|
||||||
PhabricatorApplicationTransactionInterface $object,
|
PhabricatorApplicationTransactionInterface $object,
|
||||||
|
|
|
@ -7,6 +7,10 @@ final class ManiphestCloseEmailCommand
|
||||||
return 'close';
|
return 'close';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getCommandSummary() {
|
||||||
|
return pht('Close a task.');
|
||||||
|
}
|
||||||
|
|
||||||
public function buildTransactions(
|
public function buildTransactions(
|
||||||
PhabricatorUser $viewer,
|
PhabricatorUser $viewer,
|
||||||
PhabricatorApplicationTransactionInterface $object,
|
PhabricatorApplicationTransactionInterface $object,
|
||||||
|
|
|
@ -41,6 +41,8 @@ final class PhabricatorApplicationsApplication extends PhabricatorApplication {
|
||||||
=> 'PhabricatorApplicationDetailViewController',
|
=> 'PhabricatorApplicationDetailViewController',
|
||||||
'edit/(?P<application>\w+)/'
|
'edit/(?P<application>\w+)/'
|
||||||
=> 'PhabricatorApplicationEditController',
|
=> 'PhabricatorApplicationEditController',
|
||||||
|
'mailcommands/(?P<application>\w+)/(?P<type>\w+)/'
|
||||||
|
=> 'PhabricatorApplicationEmailCommandsController',
|
||||||
'(?P<application>\w+)/(?P<action>install|uninstall)/'
|
'(?P<application>\w+)/(?P<action>install|uninstall)/'
|
||||||
=> 'PhabricatorApplicationUninstallController',
|
=> 'PhabricatorApplicationUninstallController',
|
||||||
'panel/(?P<application>\w+)/(?P<panel>\w+)/(?P<path>.*)'
|
'panel/(?P<application>\w+)/(?P<panel>\w+)/(?P<path>.*)'
|
||||||
|
|
|
@ -0,0 +1,109 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorApplicationEmailCommandsController
|
||||||
|
extends PhabricatorApplicationsController {
|
||||||
|
|
||||||
|
public function shouldAllowPublic() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleRequest(AphrontRequest $request) {
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
$application = $request->getURIData('application');
|
||||||
|
|
||||||
|
$selected = id(new PhabricatorApplicationQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withClasses(array($application))
|
||||||
|
->executeOne();
|
||||||
|
if (!$selected) {
|
||||||
|
return new Aphront404Response();
|
||||||
|
}
|
||||||
|
|
||||||
|
$specs = $selected->getMailCommandObjects();
|
||||||
|
$type = $request->getURIData('type');
|
||||||
|
if (empty($specs[$type])) {
|
||||||
|
return new Aphront404Response();
|
||||||
|
}
|
||||||
|
|
||||||
|
$spec = $specs[$type];
|
||||||
|
$commands = MetaMTAEmailTransactionCommand::getAllCommandsForObject(
|
||||||
|
$spec['object']);
|
||||||
|
|
||||||
|
$commands = msort($commands, 'getCommand');
|
||||||
|
|
||||||
|
$content = array();
|
||||||
|
|
||||||
|
$content[] = '= '.pht('Quick Reference');
|
||||||
|
$table = array();
|
||||||
|
$table[] = '| '.pht('Command').' | '.pht('Summary').' |';
|
||||||
|
$table[] = '|---|---|';
|
||||||
|
foreach ($commands as $command) {
|
||||||
|
$summary = $command->getCommandSummary();
|
||||||
|
$table[] = '| '.$command->getCommandSyntax().' | '.$summary;
|
||||||
|
}
|
||||||
|
$table = implode("\n", $table);
|
||||||
|
$content[] = $table;
|
||||||
|
|
||||||
|
foreach ($commands as $command) {
|
||||||
|
$content[] = '== !'.$command->getCommand().' ==';
|
||||||
|
$content[] = $command->getCommandSummary();
|
||||||
|
|
||||||
|
$aliases = $command->getCommandAliases();
|
||||||
|
if ($aliases) {
|
||||||
|
foreach ($aliases as $key => $alias) {
|
||||||
|
$aliases[$key] = '!'.$alias;
|
||||||
|
}
|
||||||
|
$aliases = implode(', ', $aliases);
|
||||||
|
} else {
|
||||||
|
$aliases = '//None//';
|
||||||
|
}
|
||||||
|
|
||||||
|
$syntax = $command->getCommandSyntax();
|
||||||
|
|
||||||
|
$table = array();
|
||||||
|
$table[] = '| '.pht('Property').' | '.pht('Value');
|
||||||
|
$table[] = '|---|---|';
|
||||||
|
$table[] = '| **'.pht('Syntax').'** | '.$syntax;
|
||||||
|
$table[] = '| **'.pht('Aliases').'** | '.$aliases;
|
||||||
|
$table[] = '| **'.pht('Class').'** | `'.get_class($command).'`';
|
||||||
|
$table = implode("\n", $table);
|
||||||
|
|
||||||
|
$content[] = $table;
|
||||||
|
|
||||||
|
$description = $command->getCommandDescription();
|
||||||
|
if ($description) {
|
||||||
|
$content[] = $description;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$content = implode("\n\n", $content);
|
||||||
|
|
||||||
|
$crumbs = $this->buildApplicationCrumbs();
|
||||||
|
$this->addApplicationCrumb($crumbs, $selected);
|
||||||
|
$crumbs->addTextCrumb(pht('Mail Commands'));
|
||||||
|
|
||||||
|
$content_box = id(new PHUIBoxView())
|
||||||
|
->addMargin(PHUI::MARGIN_LARGE)
|
||||||
|
->appendChild(
|
||||||
|
PhabricatorMarkupEngine::renderOneObject(
|
||||||
|
id(new PhabricatorMarkupOneOff())->setContent($content),
|
||||||
|
'default',
|
||||||
|
$viewer));
|
||||||
|
|
||||||
|
$box = id(new PHUIObjectBoxView())
|
||||||
|
->setHeaderText(pht('Mail Commands'))
|
||||||
|
->appendChild($content_box);
|
||||||
|
|
||||||
|
return $this->buildApplicationPage(
|
||||||
|
array(
|
||||||
|
$crumbs,
|
||||||
|
$box,
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'title' => 'asdf',
|
||||||
|
));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -21,4 +21,13 @@ abstract class PhabricatorApplicationsController extends PhabricatorController {
|
||||||
return $this->buildSideNavView(true)->getMenu();
|
return $this->buildSideNavView(true)->getMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function addApplicationCrumb(
|
||||||
|
PHUICrumbsView $crumbs,
|
||||||
|
PhabricatorApplication $application) {
|
||||||
|
|
||||||
|
$crumbs->addTextCrumb(
|
||||||
|
$application->getName(),
|
||||||
|
'/applications/view/'.get_class($application).'/');
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,49 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @task docs Command Documentation
|
||||||
|
*/
|
||||||
abstract class MetaMTAEmailTransactionCommand extends Phobject {
|
abstract class MetaMTAEmailTransactionCommand extends Phobject {
|
||||||
|
|
||||||
abstract public function getCommand();
|
abstract public function getCommand();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a brief human-readable description of the command effect.
|
||||||
|
*
|
||||||
|
* This should normally be one or two sentences briefly describing the
|
||||||
|
* command behavior.
|
||||||
|
*
|
||||||
|
* @return string Brief human-readable remarkup.
|
||||||
|
* @task docs
|
||||||
|
*/
|
||||||
|
abstract public function getCommandSummary();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a one-line Remarkup description of command syntax for documentation.
|
||||||
|
*
|
||||||
|
* @return string Brief human-readable remarkup.
|
||||||
|
* @task docs
|
||||||
|
*/
|
||||||
|
public function getCommandSyntax() {
|
||||||
|
return '**!'.$this->getCommand().'**';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a longer human-readable description of the command effect.
|
||||||
|
*
|
||||||
|
* This can be as long as necessary to explain the command.
|
||||||
|
*
|
||||||
|
* @return string Human-readable remarkup of whatever length is desired.
|
||||||
|
* @task docs
|
||||||
|
*/
|
||||||
|
public function getCommandDescription() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
abstract public function isCommandSupportedForObject(
|
abstract public function isCommandSupportedForObject(
|
||||||
PhabricatorApplicationTransactionInterface $object);
|
PhabricatorApplicationTransactionInterface $object);
|
||||||
|
|
||||||
abstract public function buildTransactions(
|
abstract public function buildTransactions(
|
||||||
PhabricatorUser $viewer,
|
PhabricatorUser $viewer,
|
||||||
PhabricatorApplicationTransactionInterface $object,
|
PhabricatorApplicationTransactionInterface $object,
|
||||||
|
|
|
@ -7,6 +7,10 @@ final class PhabricatorSubscriptionsUnsubscribeEmailCommand
|
||||||
return 'unsubscribe';
|
return 'unsubscribe';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getCommandSummary() {
|
||||||
|
return pht('Remove yourself as a subscriber.');
|
||||||
|
}
|
||||||
|
|
||||||
public function isCommandSupportedForObject(
|
public function isCommandSupportedForObject(
|
||||||
PhabricatorApplicationTransactionInterface $object) {
|
PhabricatorApplicationTransactionInterface $object) {
|
||||||
return ($object instanceof PhabricatorSubscribableInterface);
|
return ($object instanceof PhabricatorSubscribableInterface);
|
||||||
|
|
Loading…
Reference in a new issue