Browse files

refactoring and updated documentation

  • Loading branch information...
1 parent 4bbe88c commit 99c34a386ccef7715a2af22443ec11357de7d1ef @maximebf committed Jan 11, 2012
View
154 README.md
@@ -12,22 +12,168 @@ You can also add the folder to your include path using *set\_include\_path()*:
You will also need to configure a class autoloader. You can use the following one:
spl_autoload_register(function($className) {
- $filename = str_replace('\\', DIRECTORY_SEPARATOR, trim($className, '\\')) . '.php';
- require_once $filename;
+ if (substr($className, 0, 10) === 'ConsoleKit') {
+ $filename = str_replace('\\', DIRECTORY_SEPARATOR, trim($className, '\\')) . '.php';
+ require_once $filename;
+ }
});
-## Usage
+## Example
+
+In *cli.php*:
<?php
class HelloCommand extends ConsoleKit\Command
{
public function execute(array $args, array $options = array())
{
- $this->writeln('hello world!');
+ $this->writeln('hello world!', ConsoleKit\Colors::GREEN);
}
}
$console = new ConsoleKit\Console();
$console->addCommand('HelloCommand');
$console->run();
+
+In the shell:
+
+ $ php cli.php hello
+ hello world!
+
+More examples in [example.php](https://github.com/maximebf/ConsoleKit/blob/master/example.php)
+
+## Usage
+
+### Options parser
+
+The default options parser parses an argv-like array.
+Items can be of the form:
+
+ - --key=value
+ - --key
+ - -a
+ - -ab (equivalent of -a -b)
+
+When an option has no value, true will be used.
+If "--" is detected, all folowing values will be treated as a single argument
+
+Example: the string "-a -bc --longopt --key=value arg1 arg2 -- --any text" will produce the following two arrays:
+
+ $args = array('arg1', 'arg2', '--any text');
+ $options = array('a' => true, 'b' => true, 'c' => true, 'longopt' => true, 'key' => 'value');
+
+### Creating commands
+
+Any callbacks can be a command. It will receive three parameters: the
+arguments array, the options array and the console object.
+
+ function my_command($args, $opts, $console) {
+ $console->writeln("hello world!");
+ }
+
+Commands can also be defined as classes. In this case, they must inherit from *ConsoleKit\Command*
+and override the *execute()* method.
+
+ class MyCommand extends ConsoleKit\Command {
+ public function execute(array $args, array $opts) {
+ $this->writeln("hello world!");
+ }
+ }
+
+The *ConsoleKit\Command* class offers helpers method, check it out for more info.
+
+### Registering commands
+
+Commands need to be registered in the console object using the *addCommand()* method (or *addCommands()*).
+
+ $console = new ConsoleKit\Console();
+ $console->addCommand('my_command'); // the my_command function
+ $console->addCommand('MyCommand'); // the MyCommand class
+ $console->addCommand(function() { echo 'hello!'; }, 'hello'); // using a closure
+
+Notice that in the last example we have provided a second argument which is an alias for a command.
+As closures have no name, one must be specified.
+
+The command name for functions is the same as the function name with underscores replaced by dashes (ie. my\_command becomes my-command).
+The command name for command classes is the short class name without the *Command* suffix and "dashized" (ie. HelloWorldCommand becomes hello-world).
+
+### Running
+
+Simply call the *run()* method of the console object
+
+ $console->run();
+ $console->run(array('custom arg1', 'custom arg2')); // overrides $_SERVER['argv']
+
+## Formating text
+
+### Colors
+
+The *ConsoleKit\Colors::colorize()* method provides an easy way colorize a text.
+Colors are defined as either string or integer (through constants of the *Colors* class).
+Available colors: black, red, green, yellow, blue, magenta, cyan, white.
+
+Foreground colors are also available in a "bold" variant. Suffixed the color name with "+bold" or use the OR bit operator with constant.
+
+ echo Colors::colorize('my red text', Colors::RED);
+ echo Colors::colorize('my red text', 'red');
+
+ echo Colors::colorize('my red bold text', Colors::RED | Colors::BOLD);
+ echo Colors::colorize('my red bold text', 'red+bold');
+
+ echo Colors::colorize('my red text over yellow background', Colors::RED, Colors::YELLOW);
+
+### TextFormater
+
+The *ConsoleKit\TextFormater* class allows you to format text using the following options:
+
+ - indentation using *setIndent()* or the *indent* option
+ - quote using *setQuote()* or the *quote* option
+ - foreground color using *setFgColor()* or the *fgcolor* option
+ - background color using *setBgColor()* or the *bgcolor* option
+
+Options can be defined using *setOptions()* or as the first parameter of the constructor.
+
+ $formater = new ConsoleKit\TextFormater(array('quote' => ' > '));
+ echo $formater->format("hello!");
+ // produces: " > hello"
+
+## Widgets
+
+### Dialog
+
+Used to interact with the user
+
+ $dialog = new ConsoleKit\Dialog($console);
+ $name = $dialog->ask('What is your name?');
+
+ if ($dialog->confirm('Are you sure?')) {
+ $console->writeln("hello $name");
+ }
+
+### Box
+
+Wraps text in a box
+
+ $box = new ConsoleKit\Box($console, 'my text');
+ $box->write();
+
+Produces:
+
+ ********************************************
+ * my text *
+ ********************************************
+
+### Progress bar
+
+Displays a progress bar
+
+ $total = 100;
+ $progress = new ConsoleKit\ProgressBar($console, $total);
+ for ($i = 0; $i < $total; $i++) {
+ $progress->incr();
+ usleep(10000);
+ }
+ $progress->stop();
+
+
View
14 example.php
@@ -1,10 +1,6 @@
<?php
-set_include_path(__DIR__ . '/lib' . PATH_SEPARATOR . get_include_path());
-spl_autoload_register(function($className) {
- $filename = str_replace('\\', DIRECTORY_SEPARATOR, trim($className, '\\')) . '.php';
- require_once $filename;
-});
+include __DIR__ . '/tests/bootstrap.php';
use ConsoleKit\Console,
ConsoleKit\Command,
@@ -54,7 +50,7 @@ public function executeHello(array $args, array $options = array())
{
$name = 'unknown';
if (empty($args)) {
- $dialog = new Dialog($this->console->getTextWriter());
+ $dialog = new Dialog($this->console);
$name = $dialog->ask('What is your name?', $name);
} else {
$name = $args[0];
@@ -79,11 +75,11 @@ public function executeHi(array $args, array $options = array())
* @opt total Number of iterations
* @opt usleep Waiting time in microsecond between each iteration
*/
-function progress_command($args, $options, $console)
+function progress($args, $options, $console)
{
$total = isset($options['total']) ? $options['total'] : 100;
$usleep = isset($options['usleep']) ? $options['usleep'] : 10000;
- $progress = new ProgressBar($console->getTextWriter(), $total);
+ $progress = new ProgressBar($console, $total);
for ($i = 0; $i < $total; $i++) {
$progress->incr();
usleep($usleep);
@@ -95,7 +91,7 @@ function progress_command($args, $options, $console)
'hello' => 'HelloWorldCommand',
'SayHelloCommand',
'SayCommand',
- 'progress_command'
+ 'progress'
));
$console->run();
View
5 lib/ConsoleKit/Colors.php
@@ -75,7 +75,10 @@ public static function colorize($text, $fgcolor = null, $bgcolor = null)
if ($fgcolor) {
$colors .= self::getFgColorString(self::getColorCode($fgcolor));
}
- return $colors . $text . self::RESET;
+ if ($colors) {
+ $text = $colors . $text . self::RESET;
+ }
+ return $text;
}
/**
View
6 lib/ConsoleKit/Command.php
@@ -90,7 +90,7 @@ public function execute(array $args, array $options = array())
throw new ConsoleException("Not enough arguments");
}
- $command = Utils::camelize(array_shift($args));
+ $command = ucfirst(Utils::camelize(array_shift($args)));
$method = "execute$command";
if (!method_exists($this, $method)) {
@@ -132,7 +132,7 @@ public function format($text, $formatOptions = array())
*/
public function context(array $formatOptions, Closure $closure)
{
- $formater = new FormatedWriter($this->console->getTextWriter(), $formatOptions);
+ $formater = new FormatedWriter($this->console, $formatOptions);
return $closure($formater);
}
@@ -146,7 +146,7 @@ public function context(array $formatOptions, Closure $closure)
*/
public function write($text, $formatOptions = array(), $pipe = TextWriter::STDOUT)
{
- $this->console->getTextWriter()->write($this->format($text, $formatOptions), $pipe);
+ $this->console->write($this->format($text, $formatOptions), $pipe);
return $this;
}
View
102 lib/ConsoleKit/Console.php
@@ -19,10 +19,13 @@
namespace ConsoleKit;
+use Closure,
+ DirectoryIterator;
+
/**
* Registry of available commands and command runner
*/
-class Console
+class Console implements TextWriter
{
/** @var array */
protected $commands = array();
@@ -49,8 +52,10 @@ public function __construct(array $commands = array(), OptionsParser $parser = n
{
$this->optionsParser = $parser ?: new DefaultOptionsParser();
$this->textWriter = $writer ?: new StdTextWriter();
- $this->addCommand($this->helpCommandClass, $this->helpCommand);
- $this->addCommands($commands);
+ if ($this->helpCommandClass) {
+ $this->addCommand($this->helpCommandClass, $this->helpCommand);
+ $this->addCommands($commands);
+ }
}
/**
@@ -127,28 +132,42 @@ public function addCommands(array $commands)
/**
* Registers a command
*
- * @param string $class Associated class name, function name or Command instance
+ * @param callback $callback Associated class name, function name, Command instance or closure
* @param string $alias Command name to be used in the shell
* @return Console
*/
- public function addCommand($class, $alias = null)
+ public function addCommand($callback, $alias = null)
{
- if (!function_exists($class) && !class_exists($class)) {
- throw new ConsoleException("'$class' must reference a class or a function");
- }
- $name = $class;
- if (strtolower(substr($name, -7)) === 'command') {
- $name = substr($name, 0, -7);
- }
- if (class_exists($class, false)) {
- if (!is_subclass_of($class, 'ConsoleKit\Command')) {
- throw new ConsoleException("'$class' must be a subclass of 'ConsoleKit\Command'");
+ $name = '';
+ if (is_string($callback)) {
+ $name = $callback;
+ if (function_exists($callback)) {
+ $name = strtolower(trim(str_replace('_', '-', $name), '-'));
+ } else if (class_exists($callback)) {
+ if (!is_subclass_of($callback, 'ConsoleKit\Command')) {
+ throw new ConsoleException("'$callback' must be a subclass of 'ConsoleKit\Command'");
+ }
+ if (substr($name, -7) === 'Command') {
+ $name = substr($name, 0, -7);
+ }
+ $name = Utils::dashized(basename(str_replace('\\', '/', $name)));
+ } else {
+ throw new ConsoleException("'$callback' must reference a class or a function");
}
- $name = Utils::dashized($name);
- } else {
- $name = strtolower(trim(str_replace('_', '-', $name), '-'));
+ } else if (is_object($callback) && !($callback instanceof Closure)) {
+ $classname = get_class($callback);
+ if (!($callback instanceof Command)) {
+ throw new ConsoleException("'$classname' must inherit from 'ConsoleKit\Command'");
+ }
+ if (substr($classname, -7) === 'Command') {
+ $classname = substr($classname, 0, -7);
+ }
+ $name = Utils::dashized(basename(str_replace('\\', '/', $classname)));
+ } else if (!$alias) {
+ throw new ConsoleException("Commands using closures must have an alias");
}
- $this->commands[$alias ?: $name] = $class;
+
+ $this->commands[$alias ?: $name] = $callback;
return $this;
}
@@ -163,14 +182,15 @@ public function addCommand($class, $alias = null)
public function addCommandsFromDir($dir, $namespace = '', $includeFiles = false)
{
foreach (new DirectoryIterator($dir) as $file) {
- if ($file->isDir() || substr($file->getFilename(), 0, 1) === '.'
- || strtolower(substr($file->getFilename(), -4)) !== '.php') {
+ $filename = $file->getFilename();
+ if ($file->isDir() || substr($filename, 0, 1) === '.' || strlen($filename) <= 11
+ || strtolower(substr($filename, -11)) !== 'command.php') {
continue;
}
if ($includeFiles) {
include $file->getPathname();
}
- $className = trim($namespace . '\\' . substr($file->getFilename(), 0, -4), '\\');
+ $className = trim($namespace . '\\' . substr($filename, 0, -4), '\\');
$this->addCommand($className);
}
return $this;
@@ -239,18 +259,47 @@ public function execute($command, array $args = array(), array $options = array(
throw new ConsoleException("Command '$command' does not exist");
}
- $classname = $this->commands[$command];
- if (function_exists($classname)) {
- return call_user_func($classname, $args, $options, $this);
+ $callback = $this->commands[$command];
+ if (is_callable($callback)) {
+ return call_user_func($callback, $args, $options, $this);
}
- $instance = new $classname($this);
+ $instance = new $callback($this);
return $instance->execute($args, $options);
}
+
+ /**
+ * Writes some text to the text writer
+ *
+ * @see TextWriter::write()
+ * @param string $text
+ * @param array $formatOptions
+ * @return Console
+ */
+ public function write($text, $pipe = TextWriter::STDOUT)
+ {
+ $this->textWriter->write($text, $pipe);
+ return $this;
+ }
+
+ /**
+ * Writes a line of text
+ *
+ * @see TextWriter::writeln()
+ * @param string $text
+ * @param array $formatOptions
+ * @return Console
+ */
+ public function writeln($text = '', $pipe = TextWriter::STDOUT)
+ {
+ $this->textWriter->writeln($text, $pipe);
+ return $this;
+ }
/**
* Writes an error message to stderr
*
* @param \Exception $e
+ * @return Console
*/
public function writeException(\Exception $e)
{
@@ -264,5 +313,6 @@ public function writeException(\Exception $e)
$box = new Widgets\Box($this->textWriter, $text);
$this->textWriter->writeln(Colors::colorize($box, Colors::RED | Colors::BOLD));
+ return $this;
}
}
View
2 lib/ConsoleKit/DefaultOptionsParser.php
@@ -26,7 +26,7 @@
* --key=value
* --key
* -a
- * -ab (equivalent to -a -b)
+ * -ab (equivalent of -a -b)
*
* When an option has no value, true will be used.
* If "--" is detected, all folowing values will be treated as a single argument
View
6 lib/ConsoleKit/FormatedWriter.php
@@ -58,6 +58,7 @@ public function getTextWriter()
/**
* Writes some text to the text writer
*
+ * @see TextWriter::write()
* @param string $text
* @param array $formatOptions
* @return Command
@@ -71,13 +72,14 @@ public function write($text, $pipe = TextWriter::STDOUT)
/**
* Writes a line of text
*
- * @see write()
+ * @see TextWriter::writeln()
* @param string $text
* @param array $formatOptions
* @return Command
*/
public function writeln($text = '', $pipe = TextWriter::STDOUT)
{
- return $this->write("$text\n", $pipe);
+ $this->textWriter->writeln($this->format($text), $pipe);
+ return $this;
}
}
View
4 lib/ConsoleKit/Utils.php
@@ -45,7 +45,7 @@ public static function get($array, $key, $default = null)
* @param array $dirs
* @return string
*/
- public static function find($filename, array $dirs = array())
+ public static function find($filename, $dirs = array())
{
if (empty($dirs)) {
if ($filename = realpath($filename)) {
@@ -138,7 +138,7 @@ public static function pipedIn()
*/
public static function camelize($string)
{
- return str_replace(' ', '', ucwords(str_replace('-', ' ', $string)));
+ return lcfirst(str_replace(' ', '', ucwords(str_replace('-', ' ', $string))));
}
/**

0 comments on commit 99c34a3

Please sign in to comment.