Commit 69cad905 by Carsten Brandt

Refactoring Console commands

added method wrappers in console/Controller issue #33
parent 55cc8813
......@@ -11,6 +11,7 @@ use Yii;
use yii\base\Action;
use yii\base\InlineAction;
use yii\base\InvalidRouteException;
use yii\helpers\Console;
/**
* Controller is the base class of console command classes.
......@@ -35,6 +36,12 @@ class Controller extends \yii\base\Controller
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.
* If the action ID is empty, the method will use [[defaultAction]].
* @param string $id the ID of the action to be executed.
......@@ -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.
*
* @param string $message to echo out before waiting for user input
......@@ -124,15 +261,27 @@ class Controller extends \yii\base\Controller
public function confirm($message, $default = false)
{
if ($this->interactive) {
echo $message . ' (yes|no) [' . ($default ? 'yes' : 'no') . ']:';
$input = trim(fgets(STDIN));
return empty($input) ? $default : !strncasecmp($input, 'y', 1);
return Console::confirm($message, $default);
} else {
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.
* A global option requires the existence of a public member variable whose
* name is the option name.
......
......@@ -16,6 +16,12 @@ namespace yii\helpers\base;
* A console view provides functionality to create rich console application by allowing to format output
* by adding color and font style to it.
*
* The following constants are available for formatting:
*
* TODO document constants
*
*
*
* @author Carsten Brandt <mail@cebe.cc>
* @since 2.0
*/
......@@ -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
*/
public static function ansiStyle()
public static function ansiFormatBegin()
{
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
*
* See {@link ansiStyle} for possible arguments.
* @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
*/
public static function ansiStyleString($string)
public static function ansiFormat($string, $format=array())
{
$args = func_get_args();
array_shift($args);
$code = implode(';', $args);
$code = implode(';', $format);
return "\033[0m" . ($code !== '' ? "\033[" . $code . "m" : '') . $string . "\033[0m";
}
......@@ -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
*
* @param string $string String to strip
* @return string
*/
public static function strip($string)
public static function stripAnsiFormat($string)
{
return preg_replace('/\033\[[\d;]+m/', '', $string); // TODO currently only strips color
}
......@@ -407,56 +412,9 @@ class Console
);
}
/**
*
* 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) // {{{
public function markdownToAnsi()
{
$colors = static::getColorCodes();
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";
// TODO implement
}
/**
......@@ -497,44 +455,40 @@ class Console
*/
public static function renderColoredString($string, $colored = true)
{
static $conversions = array( // static so the array doesn't get built
// everytime
// %y - yellow, and so on... {{{
'%y' => array('color' => 'yellow'),
'%g' => array('color' => 'green'),
'%b' => array('color' => 'blue'),
'%r' => array('color' => 'red'),
'%p' => array('color' => 'purple'),
'%m' => array('color' => 'purple'),
'%c' => array('color' => 'cyan'),
'%w' => array('color' => 'grey'),
'%k' => array('color' => 'black'),
'%n' => array('color' => 'reset'),
'%Y' => array('color' => 'yellow', 'style' => 'light'),
'%G' => array('color' => 'green', 'style' => 'light'),
'%B' => array('color' => 'blue', 'style' => 'light'),
'%R' => array('color' => 'red', 'style' => 'light'),
'%P' => array('color' => 'purple', 'style' => 'light'),
'%M' => array('color' => 'purple', 'style' => 'light'),
'%C' => array('color' => 'cyan', 'style' => 'light'),
'%W' => array('color' => 'grey', 'style' => 'light'),
'%K' => array('color' => 'black', 'style' => 'light'),
'%N' => array('color' => 'reset', 'style' => 'light'),
'%3' => array('background' => 'yellow'),
'%2' => array('background' => 'green'),
'%4' => array('background' => 'blue'),
'%1' => array('background' => 'red'),
'%5' => array('background' => 'purple'),
'%6' => array('background' => 'cyan'),
'%7' => array('background' => 'grey'),
'%0' => array('background' => 'black'),
// Don't use this, I can't stand flashing text
'%F' => array('style' => 'blink'),
'%U' => array('style' => 'underline'),
'%8' => array('style' => 'inverse'),
'%9' => array('style' => 'bold'),
'%_' => array('style' => 'bold')
// }}}
static $conversions = array(
'%y' => array(static::FG_YELLOW),
'%g' => array(static::FG_GREEN),
'%b' => array(static::FG_BLUE),
'%r' => array(static::FG_RED),
'%p' => array(static::FG_PURPLE),
'%m' => array(static::FG_PURPLE),
'%c' => array(static::FG_CYAN),
'%w' => array(static::FG_GREY),
'%k' => array(static::FG_BLACK),
'%n' => array(0), // reset
'%Y' => array(static::FG_YELLOW, static::BOLD),
'%G' => array(static::FG_GREEN, static::BOLD),
'%B' => array(static::FG_BLUE, static::BOLD),
'%R' => array(static::FG_RED, static::BOLD),
'%P' => array(static::FG_PURPLE, static::BOLD),
'%M' => array(static::FG_PURPLE, static::BOLD),
'%C' => array(static::FG_CYAN, static::BOLD),
'%W' => array(static::FG_GREY, static::BOLD),
'%K' => array(static::FG_BLACK, static::BOLD),
'%N' => array(0, static::BOLD),
'%3' => array(static::BG_YELLOW),
'%2' => array(static::BG_GREEN),
'%4' => array(static::BG_BLUE),
'%1' => array(static::BG_RED),
'%5' => array(static::BG_PURPLE),
'%6' => array(static::BG_PURPLE),
'%7' => array(static::BG_CYAN),
'%0' => array(static::BG_GREY),
'%F' => array(static::BLINK),
'%U' => array(static::UNDERLINE),
'%8' => array(static::NEGATIVE),
'%9' => array(static::BOLD),
'%_' => array(static::BOLD)
);
if ($colored) {
......@@ -542,70 +496,25 @@ class Console
foreach ($conversions as $key => $value) {
$string = str_replace(
$key,
static::color($value),
static::ansiFormatCode($value),
$string
);
}
$string = str_replace('% ', '%', $string);
} else {
$string = preg_replace('/%((%)|.)/', '$2', $string);
}
return $string;
}
/**
* Returns the different foreground and background color codes and styles available.
* @return array the color codes
*/
public static function getColorCodes()
{
return array(
'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
*/
* 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)
{
return str_replace('%', '%%', $string);
......@@ -637,66 +546,47 @@ class Console
}
/**
* Gets input from STDIN and returns a string right-trimmed for EOLs.
*
* @param bool $raw If set to true, returns the raw string without trimming
* Usage: list($w, $h) = ConsoleHelper::getScreenSize();
*
* @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.
*
* @param string $text
* @param bool $raw
* Gets input from STDIN and returns a string right-trimmed for EOLs.
*
* @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 fwrite(STDOUT, $text);
} elseif (static::streamSupportsAnsiColors(STDOUT)) {
return fwrite(STDOUT, static::renderColoredString($text));
} else {
return fwrite(STDOUT, static::renderColoredString($text, false));
}
return $raw ? fgets(STDIN) : rtrim(fgets(STDIN), PHP_EOL);
}
/**
* Prints text to STDERR.
* Prints a string to STDOUT.
*
* @param string $text
* @param bool $raw
*
* @return mixed Number of bytes printed or bool false on error.
* @param string $string the string to print
* @return int|boolean Number of bytes printed or false on error
*/
public static function stderr($text, $raw = false)
public static function stdout($string)
{
if ($raw) {
return fwrite(STDERR, $text);
} elseif (static::streamSupportsAnsiColors(STDERR)) {
return fwrite(STDERR, static::renderColoredString($text));
} else {
return fwrite(STDERR, static::renderColoredString($text, false));
}
return fwrite(STDOUT, $string);
}
/**
* Prints text to STDERR appended with a carriage return (PHP_EOL).
* Prints a string to STDERR.
*
* @param string $text
* @param bool $raw
*
* @return mixed Number of bytes printed or false on error
* @param string $string the string to print
* @return int|boolean 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
*
* @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
}
/**
* Asks the user for a simple yes/no confirmation.
*
* @param string $prompt the prompt string
* Asks user to confirm by typing y or n.
*
* @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:
$input = strtolower(static::input("$prompt [y/n]: "));
if (!in_array(substr($input, 0, 1), array('y', 'n'))) {
static::output("Please, type 'y' or 'n'");
goto top;
}
return $input === 'y' ? true : false;
echo $message . ' (yes|no) [' . ($default ? 'yes' : 'no') . ']:';
$input = trim(static::stdin());
return empty($input) ? $default : !strncasecmp($input, 'y', 1);
}
/**
......@@ -826,9 +725,9 @@ class Console
/**
* Displays and updates a simple progress bar on screen.
*
* @param $done the number of items that are completed
* @param $total the total value of items that are to be done
* @param int $size the size of the status bar (optional)
* @param integer $done the number of items that are completed
* @param integer $total the total value of items that are to be done
* @param integer $size the size of the status bar (optional)
* @see http://snipplr.com/view/29548/
*/
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