Commit 9c9ce298 by Alexander Makarov

Merge pull request #4913 from yiisoft/console-help-refactoring

Console help refactoring
parents 33412c68 da7af423
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\console;
use Yii;
use yii\helpers\Console;
/**
* Action is the base class for all controller action classes.
*
* @inheritdoc
* @property \yii\console\Controller $controller
*
* @author Carsten Brandt <mail@cebe.cc>
* @since 2.0
*/
class Action extends \yii\base\Action
{
/**
* Returns one-line short summary describing this action.
*
* You may override this method to return customized summary.
* The default implementation returns first line from the PHPDoc comment.
*
* @return string
*/
public function getHelpSummary()
{
return HelpParser::getSummary(new \ReflectionClass($this));
}
/**
* Returns help information for this action.
*
* You may override this method to return customized help.
* The default implementation returns help information retrieved from the PHPDoc comment.
* @return string
*/
public function getHelp()
{
return HelpParser::getDescriptionForConsole(new \ReflectionClass($this));
}
}
......@@ -16,7 +16,7 @@ use yii\helpers\Console;
/**
* Controller is the base class of console command classes.
*
* A controller consists of one or several actions known as sub-commands.
* A console controller consists of one or several actions known as sub-commands.
* Users call a console command by specifying the corresponding route which identifies a controller action.
* The `yii` program is used when calling a console command, like the following:
*
......@@ -24,6 +24,9 @@ use yii\helpers\Console;
* yii <route> [--param1=value1 --param2 ...]
* ~~~
*
* where `<route>` is a route to a controller action and the params will be populated as properties of a command.
* See [[options()]] for details.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
......@@ -54,7 +57,7 @@ class Controller extends \yii\base\Controller
*/
public function isColorEnabled($stream = \STDOUT)
{
return $this->color === null ? Console::streamSupportsAnsiColors($stream) : $this->color;
return $this->color === null ? Console::streamSupportsAnsiColors($stream) : $this->color;
}
/**
......@@ -82,7 +85,6 @@ class Controller extends \yii\base\Controller
}
}
}
return parent::runAction($id, $params);
}
......@@ -148,7 +150,6 @@ class Controller extends \yii\base\Controller
array_shift($args);
$string = Console::ansiFormat($string, $args);
}
return $string;
}
......@@ -174,7 +175,6 @@ class Controller extends \yii\base\Controller
array_shift($args);
$string = Console::ansiFormat($string, $args);
}
return Console::stdout($string);
}
......@@ -200,7 +200,6 @@ class Controller extends \yii\base\Controller
array_shift($args);
$string = Console::ansiFormat($string, $args);
}
return fwrite(\STDERR, $string);
}
......@@ -272,7 +271,74 @@ class Controller extends \yii\base\Controller
*/
public function options($actionID)
{
// $id might be used in subclass to provide options specific to action id
// $actionId might be used in subclasses to provide options specific to action id
return ['color', 'interactive'];
}
/**
* Returns one-line short summary describing this controller.
*
* You may override this method to return customized summary.
* The default implementation returns first line from the PHPDoc comment.
*
* @return string
*/
public function getHelpSummary()
{
return HelpParser::getSummary(new \ReflectionClass($this));
}
/**
* Returns one-line short summary describing this controller action.
*
* You may override this method to return customized summary.
* The default implementation returns first line from the PHPDoc comment.
*
* @param string $actionID action to get summary for
* @return string
*/
public function getActionHelpSummary($actionID)
{
$action = $this->createAction($actionID);
if ($action instanceof InlineAction) {
$class = new \ReflectionMethod($this, $action->actionMethod);
} else {
$class = new \ReflectionClass($action);
}
return HelpParser::getSummary($class);
}
/**
* Returns help information for this controller.
*
* You may override this method to return customized help.
* The default implementation returns help information retrieved from the PHPDoc comment.
* @return string
*/
public function getHelp()
{
return HelpParser::getFull(new \ReflectionClass($this));
}
/**
* Returns help information for this controller action.
*
* You may override this method to return customized help.
* The default implementation returns help information retrieved from the PHPDoc comment.
* @param string $actionID action to get help for
* @return string
*/
public function getActionHelp($actionID)
{
$action = $this->createAction($actionID);
if ($action instanceof InlineAction) {
$class = new \ReflectionMethod($this, $action->actionMethod);
} else {
$class = new \ReflectionClass($action);
}
return HelpParser::getFull($class);
}
}
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\console;
use yii\helpers\Console;
/**
* HelpParser contains methods used to get help information from phpDoc.
*
* @author Alexander Makarov <sam@rmcreative.ru>
* @since 2.0
*/
class HelpParser
{
/**
* Returns the first line of docblock.
*
* @param \Reflector $reflector
* @return string
*/
public static function getSummary(\Reflector $reflector)
{
$docLines = preg_split('~\R~', $reflector->getDocComment());
if (isset($docLines[1])) {
return trim($docLines[1], ' *');
}
return '';
}
/**
* Returns full description from the docblock.
*
* @param \Reflector $reflector
* @return string
*/
public static function getFull(\Reflector $reflector)
{
$comment = strtr(trim(preg_replace('/^\s*\**( |\t)?/m', '', trim($reflector->getDocComment(), '/'))), "\r", '');
if (preg_match('/^\s*@\w+/m', $comment, $matches, PREG_OFFSET_CAPTURE)) {
$comment = trim(substr($comment, 0, $matches[0][1]));
}
if ($comment !== '') {
return rtrim(Console::renderColoredString(Console::markdownToAnsi($comment)));
}
return '';
}
}
\ No newline at end of file
......@@ -10,6 +10,7 @@ namespace yii\console\controllers;
use Yii;
use yii\base\Application;
use yii\base\InlineAction;
use yii\console\Action;
use yii\console\Controller;
use yii\console\Exception;
use yii\helpers\Console;
......@@ -40,7 +41,7 @@ class HelpController extends Controller
{
/**
* Displays available commands or the detailed information
* about a particular command. For example,
* about a particular command.
*
* @param string $command The name of the command to show help about.
* If not provided, all available commands will be displayed.
......@@ -61,12 +62,12 @@ class HelpController extends Controller
$actions = $this->getActions($controller);
if ($actionID !== '' || count($actions) === 1 && $actions[0] === $controller->defaultAction) {
$this->getActionHelp($controller, $actionID);
$this->getControllerActionHelp($controller, $actionID);
} else {
$this->getControllerHelp($controller);
}
} else {
$this->getHelp();
$this->getGlobalHelp();
}
}
......@@ -78,7 +79,6 @@ class HelpController extends Controller
{
$commands = $this->getModuleCommands(Yii::$app);
sort($commands);
return array_unique($commands);
}
......@@ -95,12 +95,8 @@ class HelpController extends Controller
$result = Yii::$app->createController($command);
if ($result !== false) {
list($controller, $actionID) = $result;
$class = new \ReflectionClass($controller);
$docLines = preg_split('~(\n|\r|\r\n)~', $class->getDocComment());
if (isset($docLines[1])) {
$description = trim($docLines[1], ' *');
}
/** @var Controller $controller */
$description = $controller->getHelpSummary();
}
$descriptions[$command] = $description;
......@@ -186,7 +182,7 @@ class HelpController extends Controller
/**
* Displays all available commands.
*/
protected function getHelp()
protected function getGlobalHelp()
{
$commands = $this->getCommandDescriptions();
if (!empty($commands)) {
......@@ -217,15 +213,12 @@ class HelpController extends Controller
*/
protected function getControllerHelp($controller)
{
$class = new \ReflectionClass($controller);
$comment = strtr(trim(preg_replace('/^\s*\**( |\t)?/m', '', trim($class->getDocComment(), '/'))), "\r", '');
if (preg_match('/^\s*@\w+/m', $comment, $matches, PREG_OFFSET_CAPTURE)) {
$comment = trim(substr($comment, 0, $matches[0][1]));
}
$controller->color = $this->color;
$this->stdout("\nDESCRIPTION\n", Console::BOLD);
$comment = $controller->getHelp();
if ($comment !== '') {
$this->stdout("\nDESCRIPTION\n", Console::BOLD);
echo "\n" . rtrim(Console::renderColoredString(Console::markdownToAnsi($comment))) . "\n\n";
$this->stdout("\n$comment\n\n");
}
$actions = $this->getActions($controller);
......@@ -258,34 +251,16 @@ class HelpController extends Controller
*/
protected function getActionSummary($controller, $actionID)
{
$description = null;
$action = $controller->createAction($actionID);
if ($action === null) {
return '';
}
if ($action instanceof InlineAction) {
$reflection = new \ReflectionMethod($controller, $action->actionMethod);
} else {
$reflection = new \ReflectionClass($action);
}
$tags = $this->parseComment($reflection->getDocComment());
if ($tags['description'] !== '') {
$limit = 73 - strlen($action->getUniqueId());
if ($actionID === $controller->defaultAction) {
$limit -= 10;
}
if ($limit < 0) {
$limit = 50;
}
$description = $tags['description'];
if (($pos = strpos($tags['description'], "\n")) !== false) {
$description = substr($description, 0, $pos);
}
$text = substr($description, 0, $limit);
return strlen($description) > $limit ? $text . '...' : $text;
} else {
return '';
if ($action instanceof Action) {
$description = $action->getHelpSummary();
}
if ($description === null) {
$description = $controller->getActionHelpSummary($actionID);
}
return $description;
}
/**
......@@ -294,7 +269,7 @@ class HelpController extends Controller
* @param string $actionID action ID
* @throws Exception if the action does not exist
*/
protected function getActionHelp($controller, $actionID)
protected function getControllerActionHelp($controller, $actionID)
{
$action = $controller->createAction($actionID);
if ($action === null) {
......@@ -302,18 +277,24 @@ class HelpController extends Controller
'command' => rtrim($controller->getUniqueId() . '/' . $actionID, '/'),
]));
}
$description = null;
if ($action instanceof InlineAction) {
$method = new \ReflectionMethod($controller, $action->actionMethod);
} else {
/** @var Action $action */
$description = $action->getHelp();
$method = new \ReflectionMethod($action, 'run');
}
$tags = $this->parseComment($method->getDocComment());
$options = $this->getOptionHelps($controller, $actionID);
if ($tags['description'] !== '') {
if ($description === null) {
$description = $controller->getActionHelp($actionID);
}
if ($description !== '') {
$this->stdout("\nDESCRIPTION\n", Console::BOLD);
echo "\n" . rtrim(Console::renderColoredString(Console::markdownToAnsi($tags['description']))) . "\n\n";
$this->stdout("\n$description\n\n");
}
$this->stdout("\nUSAGE\n\n", Console::BOLD);
......@@ -417,6 +398,15 @@ class HelpController extends Controller
$options[$name] = $this->formatOptionHelp($this->ansiFormat('--' . $name, Console::FG_RED), false, null, $defaultValue, '');
}
}
$name = \yii\console\Application::OPTION_APPCONFIG;
$options[$name] = $this->formatOptionHelp(
$this->ansiFormat('--' . $name, Console::FG_RED),
false,
'string',
null,
"custom application configuration file path.\nIf not set, default application configuration is used."
);
ksort($options);
return $options;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment