Commit 69cad905 by Carsten Brandt

Refactoring Console commands

added method wrappers in console/Controller issue #33
parent 55cc8813
...@@ -11,6 +11,7 @@ use Yii; ...@@ -11,6 +11,7 @@ use Yii;
use yii\base\Action; use yii\base\Action;
use yii\base\InlineAction; use yii\base\InlineAction;
use yii\base\InvalidRouteException; use yii\base\InvalidRouteException;
use yii\helpers\Console;
/** /**
* Controller is the base class of console command classes. * Controller is the base class of console command classes.
...@@ -35,6 +36,12 @@ class Controller extends \yii\base\Controller ...@@ -35,6 +36,12 @@ class Controller extends \yii\base\Controller
public $interactive = true; public $interactive = true;
/** /**
* @var bool whether to enable ANSI style in output. If not set it will be auto detected.
* Default is disabled on Windows systems and enabled on linux.
*/
public $ansi;
/**
* Runs an action with the specified action ID and parameters. * Runs an action with the specified action ID and parameters.
* If the action ID is empty, the method will use [[defaultAction]]. * If the action ID is empty, the method will use [[defaultAction]].
* @param string $id the ID of the action to be executed. * @param string $id the ID of the action to be executed.
...@@ -115,6 +122,136 @@ class Controller extends \yii\base\Controller ...@@ -115,6 +122,136 @@ class Controller extends \yii\base\Controller
} }
/** /**
* Formats a string with ANSI codes
*
* You may pass additional parameters using the constants defined in [[yii\helpers\base\Console]].
*
* Example:
* ~~~
* $this->formatString('This will be red and underlined.', Console::FG_RED, Console::UNDERLINE);
* ~~~
*
* @param string $string the string to be formatted
* @return string
*/
public function formatString($string)
{
if ($this->ansi === true || $this->ansi === null && Console::streamSupportsAnsiColors(STDOUT)) {
$args = func_get_args();
array_shift($args);
$string = Console::ansiFormat($string, $args);
}
return $string;
}
/**
* Prints a string to STDOUT
*
* You may optionally format the string with ANSI codes by
* passing additional parameters using the constants defined in [[yii\helpers\base\Console]].
*
* Example:
* ~~~
* $this->stdout('This will be red and underlined.', Console::FG_RED, Console::UNDERLINE);
* ~~~
*
* @param string $string the string to print
* @return int|boolean Number of bytes printed or false on error
*/
public function stdout($string)
{
if ($this->ansi === true || $this->ansi === null && Console::streamSupportsAnsiColors(STDOUT)) {
$args = func_get_args();
array_shift($args);
$string = Console::ansiFormat($string, $args);
}
return Console::stdout($string);
}
/**
* Prints a string to STDERR
*
* You may optionally format the string with ANSI codes by
* passing additional parameters using the constants defined in [[yii\helpers\base\Console]].
*
* Example:
* ~~~
* $this->stderr('This will be red and underlined.', Console::FG_RED, Console::UNDERLINE);
* ~~~
*
* @param string $string the string to print
* @return int|boolean Number of bytes printed or false on error
*/
public function stderr($string)
{
if ($this->ansi === true || $this->ansi === null && Console::streamSupportsAnsiColors(STDERR)) {
$args = func_get_args();
array_shift($args);
$string = Console::ansiFormat($string, $args);
}
return fwrite(STDERR, $string);
}
/**
* Asks the user for input. Ends when the user types a carriage return (PHP_EOL). Optionally, It also provides a
* prompt.
*
* @param string $prompt the prompt (optional)
* @return string the user's input
*/
public function input($prompt = null)
{
if (isset($prompt)) {
static::stdout($prompt);
}
return static::stdin();
}
/**
* Prints text to STDOUT appended with a carriage return (PHP_EOL).
*
* @param string $text
* @param bool $raw
*
* @return mixed Number of bytes printed or bool false on error
*/
public function output($text = null)
{
return static::stdout($text . PHP_EOL);
}
/**
* Prints text to STDERR appended with a carriage return (PHP_EOL).
*
* @param string $text
* @param bool $raw
*
* @return mixed Number of bytes printed or false on error
*/
public function error($text = null)
{
return static::stderr($text . PHP_EOL);
}
/**
* Prompts the user for input and validates it
*
* @param string $text prompt string
* @param array $options the options to validate the input:
* - required: whether it is required or not
* - default: default value if no input is inserted by the user
* - pattern: regular expression pattern to validate user input
* - validator: a callable function to validate input. The function must accept two parameters:
* - $input: the user input to validate
* - $error: the error value passed by reference if validation failed.
* @return string the user input
*/
public function prompt($text, $options = array())
{
return Console::prompt($text, $options);
}
/**
* Asks user to confirm by typing y or n. * Asks user to confirm by typing y or n.
* *
* @param string $message to echo out before waiting for user input * @param string $message to echo out before waiting for user input
...@@ -124,15 +261,27 @@ class Controller extends \yii\base\Controller ...@@ -124,15 +261,27 @@ class Controller extends \yii\base\Controller
public function confirm($message, $default = false) public function confirm($message, $default = false)
{ {
if ($this->interactive) { if ($this->interactive) {
echo $message . ' (yes|no) [' . ($default ? 'yes' : 'no') . ']:'; return Console::confirm($message, $default);
$input = trim(fgets(STDIN));
return empty($input) ? $default : !strncasecmp($input, 'y', 1);
} else { } else {
return true; return true;
} }
} }
/** /**
* Gives the user an option to choose from. Giving '?' as an input will show
* a list of options to choose from and their explanations.
*
* @param string $prompt the prompt message
* @param array $options Key-value array of options to choose from
*
* @return string An option character the user chose
*/
public static function select($prompt, $options = array())
{
return Console::select($prompt, $options);
}
/**
* Returns the names of the global options for this command. * Returns the names of the global options for this command.
* A global option requires the existence of a public member variable whose * A global option requires the existence of a public member variable whose
* name is the option name. * name is the option name.
......
...@@ -16,6 +16,12 @@ namespace yii\helpers\base; ...@@ -16,6 +16,12 @@ namespace yii\helpers\base;
* A console view provides functionality to create rich console application by allowing to format output * A console view provides functionality to create rich console application by allowing to format output
* by adding color and font style to it. * by adding color and font style to it.
* *
* The following constants are available for formatting:
*
* TODO document constants
*
*
*
* @author Carsten Brandt <mail@cebe.cc> * @author Carsten Brandt <mail@cebe.cc>
* @since 2.0 * @since 2.0
*/ */
...@@ -234,28 +240,47 @@ class Console ...@@ -234,28 +240,47 @@ class Console
} }
/** /**
* Will send ANSI format for following output * Sets the ANSI format for any text that is printed afterwards.
* *
* You can pass any of the FG_*, BG_* and TEXT_* constants and also xterm256ColorBg * You can pass any of the FG_*, BG_* and TEXT_* constants and also [[xterm256ColorFg]] and [[xterm256ColorBg]].
* TODO: documentation * TODO: documentation
*/ */
public static function ansiStyle() public static function ansiFormatBegin()
{ {
echo "\033[" . implode(';', func_get_args()) . 'm'; echo "\033[" . implode(';', func_get_args()) . 'm';
} }
/** /**
* Resets any ANSI format set by previous method [[ansiFormatBegin()]]
* Any output after this is will have default text style.
*/
public static function ansiFormatReset()
{
echo "\033[0m";
}
/**
* Returns the ANSI format code.
*
* You can pass any of the FG_*, BG_* and TEXT_* constants and also [[xterm256ColorFg]] and [[xterm256ColorBg]].
* TODO: documentation
*/
public static function ansiFormatCode($format)
{
return "\033[" . implode(';', $format) . 'm';
}
/**
* Will return a string formatted with the given ANSI style * Will return a string formatted with the given ANSI style
* *
* See {@link ansiStyle} for possible arguments.
* @param string $string the string to be formatted * @param string $string the string to be formatted
* @param array $format array containing formatting values.
* You can pass any of the FG_*, BG_* and TEXT_* constants and also [[xterm256ColorFg]] and [[xterm256ColorBg]].
* @return string * @return string
*/ */
public static function ansiStyleString($string) public static function ansiFormat($string, $format=array())
{ {
$args = func_get_args(); $code = implode(';', $format);
array_shift($args);
$code = implode(';', $args);
return "\033[0m" . ($code !== '' ? "\033[" . $code . "m" : '') . $string . "\033[0m"; return "\033[0m" . ($code !== '' ? "\033[" . $code . "m" : '') . $string . "\033[0m";
} }
...@@ -271,32 +296,12 @@ class Console ...@@ -271,32 +296,12 @@ class Console
} }
/** /**
* Usage: list($w, $h) = ConsoleHelper::getScreenSize();
*
* @return array
*/
public static function getScreenSize()
{
// TODO implement
return array(150, 50);
}
/**
* resets any ansi style set by previous method {@link ansiStyle}
* Any output after this is will have default text style.
*/
public static function reset()
{
echo "\033[0m";
}
/**
* Strips ANSI control codes from a string * Strips ANSI control codes from a string
* *
* @param string $string String to strip * @param string $string String to strip
* @return string * @return string
*/ */
public static function strip($string) public static function stripAnsiFormat($string)
{ {
return preg_replace('/\033\[[\d;]+m/', '', $string); // TODO currently only strips color return preg_replace('/\033\[[\d;]+m/', '', $string); // TODO currently only strips color
} }
...@@ -407,56 +412,9 @@ class Console ...@@ -407,56 +412,9 @@ class Console
); );
} }
/** public function markdownToAnsi()
*
* Returns an ANSI-Controlcode
*
* Takes 1 to 3 Arguments: either 1 to 3 strings containing the name of the
* FG Color, style and BG color, or one array with the indices color, style
* or background.
*
* @param mixed $color Optional.
* Either a string with the name of the foreground
* color, or an array with the indices 'color',
* 'style', 'background' and corresponding names as
* values.
* @param string $style Optional name of the style
* @param string $background Optional name of the background color
*
* @return string
*/
public function color($color = null, $style = null, $background = null) // {{{
{ {
$colors = static::getColorCodes(); // TODO implement
if (is_array($color)) {
$style = isset($color['style']) ? $color['style'] : null;
$background = isset($color['background']) ? $color['background'] : null;
$color = isset($color['color']) ? $color['color'] : null;
}
if ($color == 'reset') {
return "\033[0m";
}
$code = array();
if (isset($style)) {
$code[] = $colors['style'][$style];
}
if (isset($color)) {
$code[] = $colors['color'][$color];
}
if (isset($background)) {
$code[] = $colors['background'][$background];
}
if (empty($code)) {
$code[] = 0;
}
$code = implode(';', $code);
return "\033[{$code}m";
} }
/** /**
...@@ -497,44 +455,40 @@ class Console ...@@ -497,44 +455,40 @@ class Console
*/ */
public static function renderColoredString($string, $colored = true) public static function renderColoredString($string, $colored = true)
{ {
static $conversions = array( // static so the array doesn't get built static $conversions = array(
// everytime '%y' => array(static::FG_YELLOW),
// %y - yellow, and so on... {{{ '%g' => array(static::FG_GREEN),
'%y' => array('color' => 'yellow'), '%b' => array(static::FG_BLUE),
'%g' => array('color' => 'green'), '%r' => array(static::FG_RED),
'%b' => array('color' => 'blue'), '%p' => array(static::FG_PURPLE),
'%r' => array('color' => 'red'), '%m' => array(static::FG_PURPLE),
'%p' => array('color' => 'purple'), '%c' => array(static::FG_CYAN),
'%m' => array('color' => 'purple'), '%w' => array(static::FG_GREY),
'%c' => array('color' => 'cyan'), '%k' => array(static::FG_BLACK),
'%w' => array('color' => 'grey'), '%n' => array(0), // reset
'%k' => array('color' => 'black'), '%Y' => array(static::FG_YELLOW, static::BOLD),
'%n' => array('color' => 'reset'), '%G' => array(static::FG_GREEN, static::BOLD),
'%Y' => array('color' => 'yellow', 'style' => 'light'), '%B' => array(static::FG_BLUE, static::BOLD),
'%G' => array('color' => 'green', 'style' => 'light'), '%R' => array(static::FG_RED, static::BOLD),
'%B' => array('color' => 'blue', 'style' => 'light'), '%P' => array(static::FG_PURPLE, static::BOLD),
'%R' => array('color' => 'red', 'style' => 'light'), '%M' => array(static::FG_PURPLE, static::BOLD),
'%P' => array('color' => 'purple', 'style' => 'light'), '%C' => array(static::FG_CYAN, static::BOLD),
'%M' => array('color' => 'purple', 'style' => 'light'), '%W' => array(static::FG_GREY, static::BOLD),
'%C' => array('color' => 'cyan', 'style' => 'light'), '%K' => array(static::FG_BLACK, static::BOLD),
'%W' => array('color' => 'grey', 'style' => 'light'), '%N' => array(0, static::BOLD),
'%K' => array('color' => 'black', 'style' => 'light'), '%3' => array(static::BG_YELLOW),
'%N' => array('color' => 'reset', 'style' => 'light'), '%2' => array(static::BG_GREEN),
'%3' => array('background' => 'yellow'), '%4' => array(static::BG_BLUE),
'%2' => array('background' => 'green'), '%1' => array(static::BG_RED),
'%4' => array('background' => 'blue'), '%5' => array(static::BG_PURPLE),
'%1' => array('background' => 'red'), '%6' => array(static::BG_PURPLE),
'%5' => array('background' => 'purple'), '%7' => array(static::BG_CYAN),
'%6' => array('background' => 'cyan'), '%0' => array(static::BG_GREY),
'%7' => array('background' => 'grey'), '%F' => array(static::BLINK),
'%0' => array('background' => 'black'), '%U' => array(static::UNDERLINE),
// Don't use this, I can't stand flashing text '%8' => array(static::NEGATIVE),
'%F' => array('style' => 'blink'), '%9' => array(static::BOLD),
'%U' => array('style' => 'underline'), '%_' => array(static::BOLD)
'%8' => array('style' => 'inverse'),
'%9' => array('style' => 'bold'),
'%_' => array('style' => 'bold')
// }}}
); );
if ($colored) { if ($colored) {
...@@ -542,70 +496,25 @@ class Console ...@@ -542,70 +496,25 @@ class Console
foreach ($conversions as $key => $value) { foreach ($conversions as $key => $value) {
$string = str_replace( $string = str_replace(
$key, $key,
static::color($value), static::ansiFormatCode($value),
$string $string
); );
} }
$string = str_replace('% ', '%', $string); $string = str_replace('% ', '%', $string);
} else { } else {
$string = preg_replace('/%((%)|.)/', '$2', $string); $string = preg_replace('/%((%)|.)/', '$2', $string);
} }
return $string; return $string;
} }
/** /**
* Returns the different foreground and background color codes and styles available. * Escapes % so they don't get interpreted as color codes
* @return array the color codes *
*/ * @param string $string String to escape
public static function getColorCodes() *
{ * @access public
return array( * @return string
'color' => array( */
'black' => static::FG_BLACK,
'red' => static::FG_RED,
'green' => static::FG_GREEN,
'yellow' => static::FG_YELLOW,
'blue' => static::FG_BLUE,
'purple' => static::FG_PURPLE,
'cyan' => static::FG_CYAN,
'grey' => static::FG_GREY,
),
'style' => array(
'normal' => static::NORMAL,
'bold' => static::BOLD,
'italic' => static::ITALIC,
'underline' => static::UNDERLINE,
'blink' => static::BLINK,
'negative' => static::NEGATIVE,
'concealed' => static::CONCEALED,
'crossed_out' => static::CROSSED_OUT,
'framed' => static::FRAMED,
'encircled' => static::ENCIRCLED,
'overlined' => static::OVERLINED
),
'background' => array(
'black' => static::BG_BLACK,
'red' => static::BG_RED,
'green' => static::BG_RED,
'yellow' => static::BG_YELLOW,
'blue' => static::BG_BLUE,
'purple' => static::BG_PURPLE,
'cyan' => static::BG_CYAN,
'grey' => static::BG_GREY
)
);
}
/**
* Escapes % so they don't get interpreted as color codes
*
* @param string $string String to escape
*
* @access public
* @return string
*/
public static function escape($string) public static function escape($string)
{ {
return str_replace('%', '%%', $string); return str_replace('%', '%%', $string);
...@@ -637,66 +546,47 @@ class Console ...@@ -637,66 +546,47 @@ class Console
} }
/** /**
* Gets input from STDIN and returns a string right-trimmed for EOLs. * Usage: list($w, $h) = ConsoleHelper::getScreenSize();
*
* @param bool $raw If set to true, returns the raw string without trimming
* *
* @return string * @return array
*/ */
public static function stdin($raw = false) public static function getScreenSize()
{ {
return $raw ? fgets(STDIN) : rtrim(fgets(STDIN), PHP_EOL); // TODO implement
return array(150, 50);
} }
/** /**
* Prints text to STDOUT. * Gets input from STDIN and returns a string right-trimmed for EOLs.
*
* @param string $text
* @param bool $raw
* *
* @return int|false Number of bytes printed or false on error * @param bool $raw If set to true, returns the raw string without trimming
* @return string
*/ */
public static function stdout($text, $raw = false) public static function stdin($raw = false)
{ {
if ($raw) { return $raw ? fgets(STDIN) : rtrim(fgets(STDIN), PHP_EOL);
return fwrite(STDOUT, $text);
} elseif (static::streamSupportsAnsiColors(STDOUT)) {
return fwrite(STDOUT, static::renderColoredString($text));
} else {
return fwrite(STDOUT, static::renderColoredString($text, false));
}
} }
/** /**
* Prints text to STDERR. * Prints a string to STDOUT.
* *
* @param string $text * @param string $string the string to print
* @param bool $raw * @return int|boolean Number of bytes printed or false on error
*
* @return mixed Number of bytes printed or bool false on error.
*/ */
public static function stderr($text, $raw = false) public static function stdout($string)
{ {
if ($raw) { return fwrite(STDOUT, $string);
return fwrite(STDERR, $text);
} elseif (static::streamSupportsAnsiColors(STDERR)) {
return fwrite(STDERR, static::renderColoredString($text));
} else {
return fwrite(STDERR, static::renderColoredString($text, false));
}
} }
/** /**
* Prints text to STDERR appended with a carriage return (PHP_EOL). * Prints a string to STDERR.
* *
* @param string $text * @param string $string the string to print
* @param bool $raw * @return int|boolean Number of bytes printed or false on error
*
* @return mixed Number of bytes printed or false on error
*/ */
public static function error($text = null, $raw = false) public static function stderr($string)
{ {
return static::stderr($text . PHP_EOL, $raw); return fwrite(STDERR, $string);
} }
/** /**
...@@ -722,9 +612,22 @@ class Console ...@@ -722,9 +612,22 @@ class Console
* *
* @return mixed Number of bytes printed or bool false on error * @return mixed Number of bytes printed or bool false on error
*/ */
public static function output($text = null, $raw = false) public static function output($text = null)
{
return static::stdout($text . PHP_EOL);
}
/**
* Prints text to STDERR appended with a carriage return (PHP_EOL).
*
* @param string $text
* @param bool $raw
*
* @return mixed Number of bytes printed or false on error
*/
public static function error($text = null)
{ {
return static::stdout($text . PHP_EOL, $raw); return static::stderr($text . PHP_EOL);
} }
/** /**
...@@ -780,21 +683,17 @@ class Console ...@@ -780,21 +683,17 @@ class Console
} }
/** /**
* Asks the user for a simple yes/no confirmation. * Asks user to confirm by typing y or n.
*
* @param string $prompt the prompt string
* *
* @return bool true or false according to user input. * @param string $message to echo out before waiting for user input
* @param boolean $default this value is returned if no selection is made.
* @return boolean whether user confirmed
*/ */
public static function confirm($prompt) public static function confirm($message, $default = true)
{ {
top: echo $message . ' (yes|no) [' . ($default ? 'yes' : 'no') . ']:';
$input = strtolower(static::input("$prompt [y/n]: ")); $input = trim(static::stdin());
if (!in_array(substr($input, 0, 1), array('y', 'n'))) { return empty($input) ? $default : !strncasecmp($input, 'y', 1);
static::output("Please, type 'y' or 'n'");
goto top;
}
return $input === 'y' ? true : false;
} }
/** /**
...@@ -826,9 +725,9 @@ class Console ...@@ -826,9 +725,9 @@ class Console
/** /**
* Displays and updates a simple progress bar on screen. * Displays and updates a simple progress bar on screen.
* *
* @param $done the number of items that are completed * @param integer $done the number of items that are completed
* @param $total the total value of items that are to be done * @param integer $total the total value of items that are to be done
* @param int $size the size of the status bar (optional) * @param integer $size the size of the status bar (optional)
* @see http://snipplr.com/view/29548/ * @see http://snipplr.com/view/29548/
*/ */
public static function showProgress($done, $total, $size = 30) public static function showProgress($done, $total, $size = 30)
......
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