summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Gohr <andi@splitbrain.org>2014-03-19 11:52:22 +0100
committerAndreas Gohr <andi@splitbrain.org>2014-03-19 18:23:18 +0100
commit9fb664942d6f51d48d02b592980455259907d9a5 (patch)
tree507ec8c22ba529fca150dc68c84f8d1f3a3bd235
parent496e3a6f34d97e44e44340c1fbd2d3cbc262c05c (diff)
downloadrpg-9fb664942d6f51d48d02b592980455259907d9a5.tar.gz
rpg-9fb664942d6f51d48d02b592980455259907d9a5.tar.bz2
converted git tool to new CLI base
-rwxr-xr-xbin/gittool.php231
-rw-r--r--inc/cli.php125
2 files changed, 181 insertions, 175 deletions
diff --git a/bin/gittool.php b/bin/gittool.php
index f9f68ac94..b429c8d1a 100755
--- a/bin/gittool.php
+++ b/bin/gittool.php
@@ -3,78 +3,108 @@
if('cli' != php_sapi_name()) die();
ini_set('memory_limit', '128M');
-if(!defined('DOKU_INC')) define('DOKU_INC', realpath(dirname(__FILE__).'/../').'/');
+if(!defined('DOKU_INC')) define('DOKU_INC', realpath(dirname(__FILE__) . '/../') . '/');
define('NOSESSION', 1);
-require_once(DOKU_INC.'inc/init.php');
+require_once(DOKU_INC . 'inc/init.php');
-$GitToolCLI = new GitToolCLI();
-array_shift($argv);
-$command = array_shift($argv);
-
-switch($command) {
- case '':
- case 'help':
- $GitToolCLI->cmd_help();
- break;
- case 'clone':
- $GitToolCLI->cmd_clone($argv);
- break;
- case 'install':
- $GitToolCLI->cmd_install($argv);
- break;
- case 'repo':
- case 'repos':
- $GitToolCLI->cmd_repos();
- break;
- default:
- $GitToolCLI->cmd_git($command, $argv);
-}
/**
* Easily manage DokuWiki git repositories
*
* @author Andreas Gohr <andi@splitbrain.org>
*/
-class GitToolCLI {
- private $color = true;
-
- public function cmd_help() {
- echo <<<EOF
-Usage: gittool.php <command> [parameters]
-
-Manage git repositories for DokuWiki and its plugins and templates.
-
-EXAMPLE
+class GitToolCLI extends DokuCLI {
-$> ./bin/gittool.php clone gallery template:ach
-$> ./bin/gittool.php repos
-$> ./bin/gittool.php origin -v
-
-COMMANDS
+ /**
+ * Register options and arguments on the given $options object
+ *
+ * @param DokuCLI_Options $options
+ * @return void
+ */
+ protected function setup(DokuCLI_Options $options) {
+ $options->setHelp(
+ "Manage git repositories for DokuWiki and its plugins and templates.\n\n" .
+ "EXAMPLE\n\n" .
+ "$> ./bin/gittool.php clone gallery template:ach\n" .
+ "$> ./bin/gittool.php repos\n" .
+ "$> ./bin/gittool.php origin -v\n"
+ );
-help
- This help screen
+ $options->registerArgument(
+ 'command',
+ 'Command to execute. See below',
+ true
+ );
-clone <extensions>
- Tries to install a known plugin or template (prefix with template:) via
- git. Uses the DokuWiki.org plugin repository to find the proper git
- repository. Multiple extensions can be given as parameters
+ $options->registerCommand(
+ 'clone',
+ 'Tries to install a known plugin or template (prefix with template:) via git. Uses the DokuWiki.org ' .
+ 'plugin repository to find the proper git repository. Multiple extensions can be given as parameters'
+ );
+ $options->registerArgument(
+ 'extension',
+ 'name of the extension to install, prefix with \'template:\' for templates',
+ true,
+ 'clone'
+ );
-install <extensions>
- The same as clone, but when no git source repository can be found, the
- extension is installed via download
+ $options->registerCommand(
+ 'install',
+ 'The same as clone, but when no git source repository can be found, the extension is installed via ' .
+ 'download'
+ );
+ $options->registerArgument(
+ 'extension',
+ 'name of the extension to install, prefix with \'template:\' for templates',
+ true,
+ 'install'
+ );
-repos
- Lists all git repositories found in this DokuWiki installation
+ $options->registerCommand(
+ 'repos',
+ 'Lists all git repositories found in this DokuWiki installation'
+ );
-<any>
- Any unknown commands are assumed to be arguments to git and will be
- executed in all repositories found within this DokuWiki installation
+ $options->registerCommand(
+ '*',
+ 'Any unknown commands are assumed to be arguments to git and will be executed in all repositories ' .
+ 'found within this DokuWiki installation'
+ );
+ }
-EOF;
+ /**
+ * Your main program
+ *
+ * Arguments and options have been parsed when this is run
+ *
+ * @param DokuCLI_Options $options
+ * @return void
+ */
+ protected function main(DokuCLI_Options $options) {
+ $command = $options->getCmd();
+ if(!$command) $command = array_shift($options->args);
+
+ switch($command) {
+ case '':
+ echo $options->help('foo');
+ break;
+ case 'clone':
+ $this->cmd_clone($options->args);
+ break;
+ case 'install':
+ $this->cmd_install($options->args);
+ break;
+ case 'repo':
+ case 'repos':
+ $this->cmd_repos();
+ break;
+ default:
+ $this->cmd_git($command, $options->args);
+ }
}
+
/**
* Tries to install the given extensions using git clone
*
@@ -88,7 +118,7 @@ EOF;
$repo = $this->getSourceRepo($ext);
if(!$repo) {
- $this->msg_error("could not find a repository for $ext");
+ $this->error("could not find a repository for $ext");
$errors[] = $ext;
} else {
if($this->cloneExtension($ext, $repo)) {
@@ -100,8 +130,8 @@ EOF;
}
echo "\n";
- if($succeeded) $this->msg_success('successfully cloned the following extensions: '.join(', ', $succeeded));
- if($errors) $this->msg_error('failed to clone the following extensions: '.join(', ', $errors));
+ if($succeeded) $this->success('successfully cloned the following extensions: ' . join(', ', $succeeded));
+ if($errors) $this->error('failed to clone the following extensions: ' . join(', ', $errors));
}
/**
@@ -117,7 +147,7 @@ EOF;
$repo = $this->getSourceRepo($ext);
if(!$repo) {
- $this->msg_info("could not find a repository for $ext");
+ $this->info("could not find a repository for $ext");
if($this->downloadExtension($ext)) {
$succeeded[] = $ext;
} else {
@@ -133,8 +163,8 @@ EOF;
}
echo "\n";
- if($succeeded) $this->msg_success('successfully installed the following extensions: '.join(', ', $succeeded));
- if($errors) $this->msg_error('failed to install the following extensions: '.join(', ', $errors));
+ if($succeeded) $this->success('successfully installed the following extensions: ' . join(', ', $succeeded));
+ if($errors) $this->error('failed to install the following extensions: ' . join(', ', $errors));
}
/**
@@ -152,19 +182,19 @@ EOF;
foreach($repos as $repo) {
if(!@chdir($repo)) {
- $this->msg_error("Could not change into $repo");
+ $this->error("Could not change into $repo");
continue;
}
echo "\n";
- $this->msg_info("executing $shell in $repo");
+ $this->info("executing $shell in $repo");
$ret = 0;
system($shell, $ret);
if($ret == 0) {
- $this->msg_success("git succeeded in $repo");
+ $this->success("git succeeded in $repo");
} else {
- $this->msg_error("git failed in $repo");
+ $this->error("git failed in $repo");
}
}
}
@@ -193,23 +223,23 @@ EOF;
$url = $plugin->getDownloadURL();
if(!$url) {
- $this->msg_error("no download URL for $ext");
+ $this->error("no download URL for $ext");
return false;
}
$ok = false;
try {
- $this->msg_info("installing $ext via download from $url");
+ $this->info("installing $ext via download from $url");
$ok = $plugin->installFromURL($url);
} catch(Exception $e) {
- $this->msg_error($e->getMessage());
+ $this->error($e->getMessage());
}
if($ok) {
- $this->msg_success("installed $ext via download");
+ $this->success("installed $ext via download");
return true;
} else {
- $this->msg_success("failed to install $ext via download");
+ $this->success("failed to install $ext via download");
return false;
}
}
@@ -223,19 +253,19 @@ EOF;
*/
private function cloneExtension($ext, $repo) {
if(substr($ext, 0, 9) == 'template:') {
- $target = fullpath(tpl_incdir().'../'.substr($ext, 9));
+ $target = fullpath(tpl_incdir() . '../' . substr($ext, 9));
} else {
- $target = DOKU_PLUGIN.$ext;
+ $target = DOKU_PLUGIN . $ext;
}
- $this->msg_info("cloning $ext from $repo to $target");
+ $this->info("cloning $ext from $repo to $target");
$ret = 0;
system("git clone $repo $target", $ret);
if($ret === 0) {
- $this->msg_success("cloning of $ext succeeded");
+ $this->success("cloning of $ext succeeded");
return true;
} else {
- $this->msg_error("cloning of $ext failed");
+ $this->error("cloning of $ext failed");
return false;
}
}
@@ -248,17 +278,17 @@ EOF;
* @return array
*/
private function findRepos() {
- $this->msg_info('Looking for .git directories');
+ $this->info('Looking for .git directories');
$data = array_merge(
- glob(DOKU_INC.'.git', GLOB_ONLYDIR),
- glob(DOKU_PLUGIN.'*/.git', GLOB_ONLYDIR),
- glob(fullpath(tpl_incdir().'../').'/*/.git', GLOB_ONLYDIR)
+ glob(DOKU_INC . '.git', GLOB_ONLYDIR),
+ glob(DOKU_PLUGIN . '*/.git', GLOB_ONLYDIR),
+ glob(fullpath(tpl_incdir() . '../') . '/*/.git', GLOB_ONLYDIR)
);
if(!$data) {
- $this->msg_error('Found no .git directories');
+ $this->error('Found no .git directories');
} else {
- $this->msg_success('Found '.count($data).' .git directories');
+ $this->success('Found ' . count($data) . ' .git directories');
}
$data = array_map('fullpath', array_map('dirname', $data));
return $data;
@@ -283,7 +313,7 @@ EOF;
if(preg_match('/github\.com\/([^\/]+)\/([^\/]+)/i', $repourl, $m)) {
$user = $m[1];
$repo = $m[2];
- return 'https://github.com/'.$user.'/'.$repo.'.git';
+ return 'https://github.com/' . $user . '/' . $repo . '.git';
}
// match gitorious repos
@@ -292,49 +322,20 @@ EOF;
$repo = $m[2];
if(!$repo) $repo = $user;
- return 'https://git.gitorious.org/'.$user.'/'.$repo.'.git';
+ return 'https://git.gitorious.org/' . $user . '/' . $repo . '.git';
}
// match bitbucket repos - most people seem to use mercurial there though
if(preg_match('/bitbucket\.org\/([^\/]+)\/([^\/]+)/i', $repourl, $m)) {
$user = $m[1];
$repo = $m[2];
- return 'https://bitbucket.org/'.$user.'/'.$repo.'.git';
+ return 'https://bitbucket.org/' . $user . '/' . $repo . '.git';
}
return false;
}
+}
- /**
- * Print an error message
- *
- * @param $string
- */
- private function msg_error($string) {
- if($this->color) echo "\033[31m"; // red
- echo "E: $string\n";
- if($this->color) echo "\033[37m"; // reset
- }
- /**
- * Print a success message
- *
- * @param $string
- */
- private function msg_success($string) {
- if($this->color) echo "\033[32m"; // green
- echo "S: $string\n";
- if($this->color) echo "\033[37m"; // reset
- }
-
- /**
- * Print an info message
- *
- * @param $string
- */
- private function msg_info($string) {
- if($this->color) echo "\033[36m"; // cyan
- echo "I: $string\n";
- if($this->color) echo "\033[37m"; // reset
- }
-} \ No newline at end of file
+$GitToolCLI = new GitToolCLI();
+$GitToolCLI->run(); \ No newline at end of file
diff --git a/inc/cli.php b/inc/cli.php
index 2827ae233..2cba828f0 100644
--- a/inc/cli.php
+++ b/inc/cli.php
@@ -10,8 +10,6 @@
abstract class DokuCLI {
/** @var string the executed script itself */
protected $bin;
- /** @var array list of non-option arguments */
- protected $args;
/** @var DokuCLI_Options the option parser */
protected $options;
/** @var DokuCLI_Colors */
@@ -25,8 +23,6 @@ abstract class DokuCLI {
public function __construct() {
set_exception_handler(array($this, 'fatal'));
- $this->args = $this->readPHPArgv();
- $this->bin = basename(array_shift($this->args));
$this->options = new DokuCLI_Options();
$this->colors = new DokuCLI_Colors();
@@ -46,10 +42,9 @@ abstract class DokuCLI {
* Arguments and options have been parsed when this is run
*
* @param DokuCLI_Options $options
- * @param array $args
* @return void
*/
- abstract protected function main(DokuCLI_Options $options, &$args);
+ abstract protected function main(DokuCLI_Options $options);
/**
* Execute the CLI program
@@ -73,22 +68,24 @@ abstract class DokuCLI {
);
// parse
- $this->options->parseOptions($this->args);
+ $this->options->parseOptions();
// handle defaults
if($this->options->getOpt('no-colors')) {
$this->colors->disable();
}
if($this->options->getOpt('help')) {
- $this->options->help($this->bin);
+ echo $this->options->help($this->bin);
exit(0);
}
// check arguments
- $this->options->checkArguments($this->args);
+ $this->options->checkArguments();
// execute
- $this->main($this->options, $this->args);
+ $this->main($this->options);
+
+ exit(0);
}
/**
@@ -98,7 +95,7 @@ abstract class DokuCLI {
*/
public function fatal($error) {
$code = 0;
- if(is_a($error, 'Exception')) {
+ if(is_object($error) && is_a($error, 'Exception')) {
/** @var Exception $error */
$code = $error->getCode();
$error = $error->getMessage();
@@ -136,29 +133,6 @@ abstract class DokuCLI {
$this->colors->ptln("I: $string", 'cyan');
}
- /**
- * Safely read the $argv PHP array across different PHP configurations.
- * Will take care on register_globals and register_argc_argv ini directives
- *
- * @throws DokuCLI_Exception
- * @return array the $argv PHP array or PEAR error if not registered
- */
- private function readPHPArgv() {
- global $argv;
- if(!is_array($argv)) {
- if(!@is_array($_SERVER['argv'])) {
- if(!@is_array($GLOBALS['HTTP_SERVER_VARS']['argv'])) {
- throw new DokuCLI_Exception(
- "Could not read cmd args (register_argc_argv=Off?)",
- DOKU_CLI_OPTS_ARG_READ
- );
- }
- return $GLOBALS['HTTP_SERVER_VARS']['argv'];
- }
- return $_SERVER['argv'];
- }
- return $argv;
- }
}
/**
@@ -264,14 +238,21 @@ class DokuCLI_Colors {
* @author Andreas Gohr <andi@splitbrain.org>
*/
class DokuCLI_Options {
- /** @var array $setup keeps the list of options to parse */
+ /** @var array keeps the list of options to parse */
protected $setup;
- /** @var array $options store parsed options */
- protected $options;
+ /** @var array store parsed options */
+ protected $options = array();
+ /** @var string current parsed command if any */
protected $command = '';
+ /** @var array passed non-option arguments*/
+ public $args = array();
+
+ /** @var string the executed script */
+ protected $bin;
+
public function __construct() {
$this->setup = array(
'' => array(
@@ -281,6 +262,9 @@ class DokuCLI_Options {
)
); // default command
+ $this->args = $this->readPHPArgv();
+ $this->bin = basename(array_shift($this->args));
+
$this->options = array();
}
@@ -317,7 +301,7 @@ class DokuCLI_Options {
/**
* This registers a sub command
*
- * Sub commands have their own options and use their own function (not main())
+ * Sub commands have their own options and use their own function (not main()).
*
* @param string $command
* @param string $help
@@ -365,15 +349,14 @@ class DokuCLI_Options {
*
* Throws an exception if arguments are missing. Called from parseOptions()
*
- * @param array $args
* @throws DokuCLI_Exception
*/
- public function checkArguments($args) {
- $argc = count($args);
+ public function checkArguments() {
+ $argc = count($this->args);
$req = 0;
foreach($this->setup[$this->command]['args'] as $arg) {
- if(!$args['required']) break; // last required arguments seen
+ if(!$arg['required']) break; // last required arguments seen
$req++;
}
@@ -389,32 +372,31 @@ class DokuCLI_Options {
*
* Note that command options will overwrite any global options with the same name
*
- * @param array $args
* @throws DokuCLI_Exception
*/
- public function parseOptions(&$args) {
+ public function parseOptions() {
$non_opts = array();
- $argc = count($args);
+ $argc = count($this->args);
for($i = 0; $i < $argc; $i++) {
- $arg = $args[$i];
+ $arg = $this->args[$i];
// The special element '--' means explicit end of options. Treat the rest of the arguments as non-options
// and end the loop.
if($arg == '--') {
- $non_opts = array_merge($non_opts, array_slice($args, $i + 1));
+ $non_opts = array_merge($non_opts, array_slice($this->args, $i + 1));
break;
}
// '-' is stdin - a normal argument
if($arg == '-') {
- $non_opts = array_merge($non_opts, array_slice($args, $i));
+ $non_opts = array_merge($non_opts, array_slice($this->args, $i));
break;
}
// first non-option
if($arg{0} != '-') {
- $non_opts = array_merge($non_opts, array_slice($args, $i));
+ $non_opts = array_merge($non_opts, array_slice($this->args, $i));
break;
}
@@ -428,8 +410,8 @@ class DokuCLI_Options {
// argument required?
if($this->setup[$this->command]['opts'][$opt]['needsarg']) {
- if(is_null($val) && $i + 1 < $argc && !preg_match('/^--?[\w]/', $args[$i + 1])) {
- $val = $args[++$i];
+ if(is_null($val) && $i + 1 < $argc && !preg_match('/^--?[\w]/', $this->args[$i + 1])) {
+ $val = $this->args[++$i];
}
if(is_null($val)) {
throw new DokuCLI_Exception("Option $arg requires an argument", DokuCLI_Exception::E_OPT_ARG_REQUIRED);
@@ -453,8 +435,8 @@ class DokuCLI_Options {
// argument required?
if($this->setup[$this->command]['opts'][$opt]['needsarg']) {
$val = null;
- if($i + 1 < $argc && !preg_match('/^--?[\w]/', $args[$i + 1])) {
- $val = $args[++$i];
+ if($i + 1 < $argc && !preg_match('/^--?[\w]/', $this->args[$i + 1])) {
+ $val = $this->args[++$i];
}
if(is_null($val)) {
throw new DokuCLI_Exception("Option $arg requires an argument", DokuCLI_Exception::E_OPT_ARG_REQUIRED);
@@ -466,13 +448,13 @@ class DokuCLI_Options {
}
// parsing is now done, update args array
- $args = $non_opts;
+ $this->args = $non_opts;
// if not done yet, check if first argument is a command and reexecute argument parsing if it is
- if(!$this->command && $args && isset($this->setup[$args[0]])) {
+ if(!$this->command && $this->args && isset($this->setup[$this->args[0]]) ) {
// it is a command!
- $this->command = array_shift($args);
- $this->parseOptions($args); // second pass
+ $this->command = array_shift($this->args);
+ $this->parseOptions(); // second pass
}
}
@@ -504,10 +486,9 @@ class DokuCLI_Options {
/**
* Builds a help screen from the available options. You may want to call it from -h or on error
*
- * @param string $bin name of the script itself
* @return string
*/
- public function help($bin) {
+ public function help() {
$text = '';
$hascommands = (count($this->setup) > 1);
@@ -516,7 +497,7 @@ class DokuCLI_Options {
$hasargs = (bool) $this->setup[$command]['args'];
if(!$command) {
- $text .= 'USAGE: ' . $bin;
+ $text .= 'USAGE: ' . $this->bin;
} else {
$text .= "\n$command";
}
@@ -565,6 +546,30 @@ class DokuCLI_Options {
return $text;
}
+ /**
+ * Safely read the $argv PHP array across different PHP configurations.
+ * Will take care on register_globals and register_argc_argv ini directives
+ *
+ * @throws DokuCLI_Exception
+ * @return array the $argv PHP array or PEAR error if not registered
+ */
+ private function readPHPArgv() {
+ global $argv;
+ if(!is_array($argv)) {
+ if(!@is_array($_SERVER['argv'])) {
+ if(!@is_array($GLOBALS['HTTP_SERVER_VARS']['argv'])) {
+ throw new DokuCLI_Exception(
+ "Could not read cmd args (register_argc_argv=Off?)",
+ DOKU_CLI_OPTS_ARG_READ
+ );
+ }
+ return $GLOBALS['HTTP_SERVER_VARS']['argv'];
+ }
+ return $_SERVER['argv'];
+ }
+ return $argv;
+ }
+
}
/**