From 4e877c52e4408e7dbc3ea7109ac1894db30f58f9 Mon Sep 17 00:00:00 2001 From: "Jonathan.Wage" Date: Wed, 10 Oct 2007 02:31:11 +0000 Subject: [PATCH] Fleshing out the cli system. --- lib/Doctrine/Cli.php | 70 +++++++++++++- lib/Doctrine/Cli/Task.php | 92 +++++++++++++++++++ .../Cli/Task/{Test.php => TestTask.php} | 13 ++- 3 files changed, 169 insertions(+), 6 deletions(-) rename lib/Doctrine/Cli/Task/{Test.php => TestTask.php} (74%) diff --git a/lib/Doctrine/Cli.php b/lib/Doctrine/Cli.php index 91a1b09bb..b28f34837 100644 --- a/lib/Doctrine/Cli.php +++ b/lib/Doctrine/Cli.php @@ -35,20 +35,86 @@ class Doctrine_Cli public function run($args) { if (!isset($args[1])) { - throw new Doctrine_Cli_Exception('You must specify the task to execute'); + echo $this->printTasks(); + return; } unset($args[0]); - $taskName = $args[1]; + $taskName = str_replace('-', '_', $args[1]); unset($args[1]); $taskClass = 'Doctrine_Cli_Task_' . Doctrine::classify($taskName); if (class_exists($taskClass)) { $taskInstance = new $taskClass(); + $taskInstance->taskName = str_replace('_', '-', Doctrine::tableize(str_replace('Doctrine_Cli_Task_', '', $taskName))); + + $args = $taskInstance->prepareArgs($args); + + $taskInstance->validate($args); $taskInstance->execute($args); } else { throw new Doctrine_Cli_Exception('Cli task could not be found: '.$taskClass); } } + + public function printTasks() + { + $tasks = $this->loadTasks(); + + echo "\nAvailable Doctrine Command Line Interface Tasks\n"; + echo str_repeat('-', 40)."\n\n"; + foreach ($tasks as $taskName) + { + $className = 'Doctrine_Cli_Task_' . $taskName; + $taskInstance = new $className(); + $taskInstance->taskName = str_replace('_', '-', Doctrine::tableize($taskName)); + + echo "Name: " . $taskInstance->getName() . "\n"; + echo "Description: " . $taskInstance->getDescription() . "\n"; + + if ($requiredArguments = $taskInstance->getRequiredArguments()) { + echo "Required Arguments: " . implode(', ', $requiredArguments) . "\n"; + } + + if ($optionalArguments = $taskInstance->getOptionalArguments()) { + echo "Optional Arguments: " . implode(', ', $taskInstance->getOptionalArguments()) . "\n"; + } + + echo "Syntax: " . $taskInstance->getSyntax() . "\n"; + echo str_repeat('-', 40) . "\n\n"; + } + } + + public function loadTasks($directory = null) + { + if ($directory === null) { + $directory = dirname(__FILE__). DIRECTORY_SEPARATOR . 'Cli' . DIRECTORY_SEPARATOR . 'Task'; + } + + $parent = new ReflectionClass('Doctrine_Cli_Task'); + + $tasks = array(); + + foreach ((array) $directory as $dir) { + $it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir), + RecursiveIteratorIterator::LEAVES_ONLY); + + foreach ($it as $file) { + $e = explode('.', $file->getFileName()); + if (end($e) === 'php' && strpos($file->getFileName(), '.inc') === false) { + require_once($file->getPathName()); + + $className = 'Doctrine_Cli_Task_' . $e[0]; + $class = new ReflectionClass($className); + + if ($class->isSubClassOf($parent)) { + $tasks[] = $e[0]; + } + } + } + } + + return $tasks; + } } \ No newline at end of file diff --git a/lib/Doctrine/Cli/Task.php b/lib/Doctrine/Cli/Task.php index 87f32f66e..b75fb5478 100644 --- a/lib/Doctrine/Cli/Task.php +++ b/lib/Doctrine/Cli/Task.php @@ -32,5 +32,97 @@ */ abstract class Doctrine_Cli_Task { + public $name = null, + $taskName = null, + $description = null, + $requiredArguments = array(), + $optionalArguments = array(); + abstract function execute($args); + + public function validate($args) + { + $requiredArguments = $this->getRequiredArguments(); + + foreach ($requiredArguments as $arg) { + if (!isset($args[$arg])) { + throw new Doctrine_Cli_Exception('Required arguments missing. The follow arguments are required: ' . implode(', ', $requiredArguments)); + } + } + + return true; + } + + public function prepareArgs($args) + { + $args = array_values($args); + + $prepared = array(); + $requiredArguments = $this->getRequiredArguments(); + + $count = 0; + foreach ($requiredArguments as $key => $arg) { + if (isset($args[$count])) { + $prepared[$arg] = $args[$count]; + } + + $count++; + } + + $optionalArguments = $this->getOptionalArguments(); + + foreach ($optionalArguments as $key => $arg) { + if (isset($args[$count])) { + $prepared[$arg] = $args[$count]; + } else { + $prepared[$arg] = null; + } + + $count++; + } + + return $prepared; + } + + public function getName() + { + return $this->name; + } + + public function getTaskName() + { + return $this->taskName; + } + + public function getDescription() + { + return $this->description; + } + + public function getRequiredArguments() + { + return $this->requiredArguments; + } + + public function getOptionalArguments() + { + return $this->optionalArguments; + } + + public function getSyntax() + { + $taskName = $this->getTaskName(); + $requiredArguments = null; + $optionalArguments = null; + + if ($required = $this->getRequiredArguments()) { + $requiredArguments = '<' . implode('> <', $required) . '>'; + } + + if ($optional = $this->getOptionalArguments()) { + $optionalArguments = '<' . implode('> <', $optional) . '>'; + } + + return './cli ' . $taskName . ' ' . $requiredArguments . ' ' . $optionalArguments; + } } \ No newline at end of file diff --git a/lib/Doctrine/Cli/Task/Test.php b/lib/Doctrine/Cli/Task/TestTask.php similarity index 74% rename from lib/Doctrine/Cli/Task/Test.php rename to lib/Doctrine/Cli/Task/TestTask.php index e23ce04cb..0ea3e0d78 100644 --- a/lib/Doctrine/Cli/Task/Test.php +++ b/lib/Doctrine/Cli/Task/TestTask.php @@ -20,7 +20,7 @@ */ /** - * Doctrine_Cli_Test_Task + * Doctrine_Cli_Task_TestTask * * @package Doctrine * @subpackage Cli @@ -30,15 +30,20 @@ * @version $Revision: 2761 $ * @author Jonathan H. Wage */ -class Doctrine_Cli_Task_Test +class Doctrine_Cli_Task_TestTask extends Doctrine_Cli_Task { + public $name = 'Test Task', + $description = 'This is a sample task which prints the arguments you enter.', + $requiredArguments = array('name', 'title'), + $optionalArguments = array('description'); + public function execute($args) { $count = 0; - foreach ($args as $arg) { + foreach ($args as $name => $value) { $count++; - echo $count.".) ".$arg."\n"; + echo $count . ".) " . $name . " => " . $value . "\n"; } } } \ No newline at end of file