about summary refs log tree commit diff stats
path: root/wiki/inc/cli.php
diff options
context:
space:
mode:
Diffstat (limited to 'wiki/inc/cli.php')
-rw-r--r--wiki/inc/cli.php655
1 files changed, 0 insertions, 655 deletions
diff --git a/wiki/inc/cli.php b/wiki/inc/cli.php
deleted file mode 100644
index cb4fc58..0000000
--- a/wiki/inc/cli.php
+++ /dev/null
@@ -1,655 +0,0 @@
-<?php
-
-/**
- * Class DokuCLI
- *
- * All DokuWiki commandline scripts should inherit from this class and implement the abstract methods.
- *
- * @author Andreas Gohr <andi@splitbrain.org>
- */
-abstract class DokuCLI {
-    /** @var string the executed script itself */
-    protected $bin;
-    /** @var  DokuCLI_Options the option parser */
-    protected $options;
-    /** @var  DokuCLI_Colors */
-    public $colors;
-
-    /**
-     * constructor
-     *
-     * Initialize the arguments, set up helper classes and set up the CLI environment
-     */
-    public function __construct() {
-        set_exception_handler(array($this, 'fatal'));
-
-        $this->options = new DokuCLI_Options();
-        $this->colors  = new DokuCLI_Colors();
-
-        dbg_deprecated('use \splitbrain\phpcli\CLI instead');
-        $this->error('DokuCLI is deprecated, use \splitbrain\phpcli\CLI instead.');
-    }
-
-    /**
-     * Register options and arguments on the given $options object
-     *
-     * @param DokuCLI_Options $options
-     * @return void
-     */
-    abstract protected function setup(DokuCLI_Options $options);
-
-    /**
-     * Your main program
-     *
-     * Arguments and options have been parsed when this is run
-     *
-     * @param DokuCLI_Options $options
-     * @return void
-     */
-    abstract protected function main(DokuCLI_Options $options);
-
-    /**
-     * Execute the CLI program
-     *
-     * Executes the setup() routine, adds default options, initiate the options parsing and argument checking
-     * and finally executes main()
-     */
-    public function run() {
-        if('cli' != php_sapi_name()) throw new DokuCLI_Exception('This has to be run from the command line');
-
-        // setup
-        $this->setup($this->options);
-        $this->options->registerOption(
-            'no-colors',
-            'Do not use any colors in output. Useful when piping output to other tools or files.'
-        );
-        $this->options->registerOption(
-            'help',
-            'Display this help screen and exit immediately.',
-            'h'
-        );
-
-        // parse
-        $this->options->parseOptions();
-
-        // handle defaults
-        if($this->options->getOpt('no-colors')) {
-            $this->colors->disable();
-        }
-        if($this->options->getOpt('help')) {
-            echo $this->options->help();
-            exit(0);
-        }
-
-        // check arguments
-        $this->options->checkArguments();
-
-        // execute
-        $this->main($this->options);
-
-        exit(0);
-    }
-
-    /**
-     * Exits the program on a fatal error
-     *
-     * @param Exception|string $error either an exception or an error message
-     */
-    public function fatal($error) {
-        $code = 0;
-        if(is_object($error) && is_a($error, 'Exception')) {
-            /** @var Exception $error */
-            $code  = $error->getCode();
-            $error = $error->getMessage();
-        }
-        if(!$code) $code = DokuCLI_Exception::E_ANY;
-
-        $this->error($error);
-        exit($code);
-    }
-
-    /**
-     * Print an error message
-     *
-     * @param string $string
-     */
-    public function error($string) {
-        $this->colors->ptln("E: $string", 'red', STDERR);
-    }
-
-    /**
-     * Print a success message
-     *
-     * @param string $string
-     */
-    public function success($string) {
-        $this->colors->ptln("S: $string", 'green', STDERR);
-    }
-
-    /**
-     * Print an info message
-     *
-     * @param string $string
-     */
-    public function info($string) {
-        $this->colors->ptln("I: $string", 'cyan', STDERR);
-    }
-
-}
-
-/**
- * Class DokuCLI_Colors
- *
- * Handles color output on (Linux) terminals
- *
- * @author Andreas Gohr <andi@splitbrain.org>
- */
-class DokuCLI_Colors {
-    /** @var array known color names */
-    protected $colors = array(
-        'reset'       => "\33[0m",
-        'black'       => "\33[0;30m",
-        'darkgray'    => "\33[1;30m",
-        'blue'        => "\33[0;34m",
-        'lightblue'   => "\33[1;34m",
-        'green'       => "\33[0;32m",
-        'lightgreen'  => "\33[1;32m",
-        'cyan'        => "\33[0;36m",
-        'lightcyan'   => "\33[1;36m",
-        'red'         => "\33[0;31m",
-        'lightred'    => "\33[1;31m",
-        'purple'      => "\33[0;35m",
-        'lightpurple' => "\33[1;35m",
-        'brown'       => "\33[0;33m",
-        'yellow'      => "\33[1;33m",
-        'lightgray'   => "\33[0;37m",
-        'white'       => "\33[1;37m",
-    );
-
-    /** @var bool should colors be used? */
-    protected $enabled = true;
-
-    /**
-     * Constructor
-     *
-     * Tries to disable colors for non-terminals
-     */
-    public function __construct() {
-        if(function_exists('posix_isatty') && !posix_isatty(STDOUT)) {
-            $this->enabled = false;
-            return;
-        }
-        if(!getenv('TERM')) {
-            $this->enabled = false;
-            return;
-        }
-    }
-
-    /**
-     * enable color output
-     */
-    public function enable() {
-        $this->enabled = true;
-    }
-
-    /**
-     * disable color output
-     */
-    public function disable() {
-        $this->enabled = false;
-    }
-
-    /**
-     * Convenience function to print a line in a given color
-     *
-     * @param string   $line
-     * @param string   $color
-     * @param resource $channel
-     */
-    public function ptln($line, $color, $channel = STDOUT) {
-        $this->set($color);
-        fwrite($channel, rtrim($line)."\n");
-        $this->reset();
-    }
-
-    /**
-     * Set the given color for consecutive output
-     *
-     * @param string $color one of the supported color names
-     * @throws DokuCLI_Exception
-     */
-    public function set($color) {
-        if(!$this->enabled) return;
-        if(!isset($this->colors[$color])) throw new DokuCLI_Exception("No such color $color");
-        echo $this->colors[$color];
-    }
-
-    /**
-     * reset the terminal color
-     */
-    public function reset() {
-        $this->set('reset');
-    }
-}
-
-/**
- * Class DokuCLI_Options
- *
- * Parses command line options passed to the CLI script. Allows CLI scripts to easily register all accepted options and
- * commands and even generates a help text from this setup.
- *
- * @author Andreas Gohr <andi@splitbrain.org>
- */
-class DokuCLI_Options {
-    /** @var  array keeps the list of options to parse */
-    protected $setup;
-
-    /** @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;
-
-    /**
-     * Constructor
-     */
-    public function __construct() {
-        $this->setup = array(
-            '' => array(
-                'opts' => array(),
-                'args' => array(),
-                'help' => ''
-            )
-        ); // default command
-
-        $this->args = $this->readPHPArgv();
-        $this->bin  = basename(array_shift($this->args));
-
-        $this->options = array();
-    }
-
-    /**
-     * Sets the help text for the tool itself
-     *
-     * @param string $help
-     */
-    public function setHelp($help) {
-        $this->setup['']['help'] = $help;
-    }
-
-    /**
-     * Register the names of arguments for help generation and number checking
-     *
-     * This has to be called in the order arguments are expected
-     *
-     * @param string $arg      argument name (just for help)
-     * @param string $help     help text
-     * @param bool   $required is this a required argument
-     * @param string $command  if theses apply to a sub command only
-     * @throws DokuCLI_Exception
-     */
-    public function registerArgument($arg, $help, $required = true, $command = '') {
-        if(!isset($this->setup[$command])) throw new DokuCLI_Exception("Command $command not registered");
-
-        $this->setup[$command]['args'][] = array(
-            'name'     => $arg,
-            'help'     => $help,
-            'required' => $required
-        );
-    }
-
-    /**
-     * This registers a sub command
-     *
-     * Sub commands have their own options and use their own function (not main()).
-     *
-     * @param string $command
-     * @param string $help
-     * @throws DokuCLI_Exception
-     */
-    public function registerCommand($command, $help) {
-        if(isset($this->setup[$command])) throw new DokuCLI_Exception("Command $command already registered");
-
-        $this->setup[$command] = array(
-            'opts' => array(),
-            'args' => array(),
-            'help' => $help
-        );
-
-    }
-
-    /**
-     * Register an option for option parsing and help generation
-     *
-     * @param string      $long     multi character option (specified with --)
-     * @param string      $help     help text for this option
-     * @param string|null $short    one character option (specified with -)
-     * @param bool|string $needsarg does this option require an argument? give it a name here
-     * @param string      $command  what command does this option apply to
-     * @throws DokuCLI_Exception
-     */
-    public function registerOption($long, $help, $short = null, $needsarg = false, $command = '') {
-        if(!isset($this->setup[$command])) throw new DokuCLI_Exception("Command $command not registered");
-
-        $this->setup[$command]['opts'][$long] = array(
-            'needsarg' => $needsarg,
-            'help'     => $help,
-            'short'    => $short
-        );
-
-        if($short) {
-            if(strlen($short) > 1) throw new DokuCLI_Exception("Short options should be exactly one ASCII character");
-
-            $this->setup[$command]['short'][$short] = $long;
-        }
-    }
-
-    /**
-     * Checks the actual number of arguments against the required number
-     *
-     * Throws an exception if arguments are missing. Called from parseOptions()
-     *
-     * @throws DokuCLI_Exception
-     */
-    public function checkArguments() {
-        $argc = count($this->args);
-
-        $req = 0;
-        foreach($this->setup[$this->command]['args'] as $arg) {
-            if(!$arg['required']) break; // last required arguments seen
-            $req++;
-        }
-
-        if($req > $argc) throw new DokuCLI_Exception("Not enough arguments", DokuCLI_Exception::E_OPT_ARG_REQUIRED);
-    }
-
-    /**
-     * Parses the given arguments for known options and command
-     *
-     * The given $args array should NOT contain the executed file as first item anymore! The $args
-     * array is stripped from any options and possible command. All found otions can be accessed via the
-     * getOpt() function
-     *
-     * Note that command options will overwrite any global options with the same name
-     *
-     * @throws DokuCLI_Exception
-     */
-    public function parseOptions() {
-        $non_opts = array();
-
-        $argc = count($this->args);
-        for($i = 0; $i < $argc; $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($this->args, $i + 1));
-                break;
-            }
-
-            // '-' is stdin - a normal argument
-            if($arg == '-') {
-                $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($this->args, $i));
-                break;
-            }
-
-            // long option
-            if(strlen($arg) > 1 && $arg{1} == '-') {
-                list($opt, $val) = explode('=', substr($arg, 2), 2);
-
-                if(!isset($this->setup[$this->command]['opts'][$opt])) {
-                    throw new DokuCLI_Exception("No such option $arg", DokuCLI_Exception::E_UNKNOWN_OPT);
-                }
-
-                // argument required?
-                if($this->setup[$this->command]['opts'][$opt]['needsarg']) {
-                    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);
-                    }
-                    $this->options[$opt] = $val;
-                } else {
-                    $this->options[$opt] = true;
-                }
-
-                continue;
-            }
-
-            // short option
-            $opt = substr($arg, 1);
-            if(!isset($this->setup[$this->command]['short'][$opt])) {
-                throw new DokuCLI_Exception("No such option $arg", DokuCLI_Exception::E_UNKNOWN_OPT);
-            } else {
-                $opt = $this->setup[$this->command]['short'][$opt]; // store it under long name
-            }
-
-            // argument required?
-            if($this->setup[$this->command]['opts'][$opt]['needsarg']) {
-                $val = null;
-                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);
-                }
-                $this->options[$opt] = $val;
-            } else {
-                $this->options[$opt] = true;
-            }
-        }
-
-        // parsing is now done, update args array
-        $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 && $this->args && isset($this->setup[$this->args[0]])) {
-            // it is a command!
-            $this->command = array_shift($this->args);
-            $this->parseOptions(); // second pass
-        }
-    }
-
-    /**
-     * Get the value of the given option
-     *
-     * Please note that all options are accessed by their long option names regardless of how they were
-     * specified on commandline.
-     *
-     * Can only be used after parseOptions() has been run
-     *
-     * @param string $option
-     * @param bool|string $default what to return if the option was not set
-     * @return bool|string
-     */
-    public function getOpt($option, $default = false) {
-        if(isset($this->options[$option])) return $this->options[$option];
-        return $default;
-    }
-
-    /**
-     * Return the found command if any
-     *
-     * @return string
-     */
-    public function getCmd() {
-        return $this->command;
-    }
-
-    /**
-     * Builds a help screen from the available options. You may want to call it from -h or on error
-     *
-     * @return string
-     */
-    public function help() {
-        $text = '';
-
-        $hascommands = (count($this->setup) > 1);
-        foreach($this->setup as $command => $config) {
-            $hasopts = (bool) $this->setup[$command]['opts'];
-            $hasargs = (bool) $this->setup[$command]['args'];
-
-            if(!$command) {
-                $text .= 'USAGE: '.$this->bin;
-            } else {
-                $text .= "\n$command";
-            }
-
-            if($hasopts) $text .= ' <OPTIONS>';
-
-            foreach($this->setup[$command]['args'] as $arg) {
-                if($arg['required']) {
-                    $text .= ' <'.$arg['name'].'>';
-                } else {
-                    $text .= ' [<'.$arg['name'].'>]';
-                }
-            }
-            $text .= "\n";
-
-            if($this->setup[$command]['help']) {
-                $text .= "\n";
-                $text .= $this->tableFormat(
-                    array(2, 72),
-                    array('', $this->setup[$command]['help']."\n")
-                );
-            }
-
-            if($hasopts) {
-                $text .= "\n  OPTIONS\n\n";
-                foreach($this->setup[$command]['opts'] as $long => $opt) {
-
-                    $name = '';
-                    if($opt['short']) {
-                        $name .= '-'.$opt['short'];
-                        if($opt['needsarg']) $name .= ' <'.$opt['needsarg'].'>';
-                        $name .= ', ';
-                    }
-                    $name .= "--$long";
-                    if($opt['needsarg']) $name .= ' <'.$opt['needsarg'].'>';
-
-                    $text .= $this->tableFormat(
-                        array(2, 20, 52),
-                        array('', $name, $opt['help'])
-                    );
-                    $text .= "\n";
-                }
-            }
-
-            if($hasargs) {
-                $text .= "\n";
-                foreach($this->setup[$command]['args'] as $arg) {
-                    $name = '<'.$arg['name'].'>';
-
-                    $text .= $this->tableFormat(
-                        array(2, 20, 52),
-                        array('', $name, $arg['help'])
-                    );
-                }
-            }
-
-            if($command == '' && $hascommands) {
-                $text .= "\nThis tool accepts a command as first parameter as outlined below:\n";
-            }
-        }
-
-        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;
-    }
-
-    /**
-     * Displays text in multiple word wrapped columns
-     *
-     * @param int[]    $widths list of column widths (in characters)
-     * @param string[] $texts  list of texts for each column
-     * @return string
-     */
-    private function tableFormat($widths, $texts) {
-        $wrapped = array();
-        $maxlen  = 0;
-
-        foreach($widths as $col => $width) {
-            $wrapped[$col] = explode("\n", wordwrap($texts[$col], $width - 1, "\n", true)); // -1 char border
-            $len           = count($wrapped[$col]);
-            if($len > $maxlen) $maxlen = $len;
-
-        }
-
-        $out = '';
-        for($i = 0; $i < $maxlen; $i++) {
-            foreach($widths as $col => $width) {
-                if(isset($wrapped[$col][$i])) {
-                    $val = $wrapped[$col][$i];
-                } else {
-                    $val = '';
-                }
-                $out .= sprintf('%-'.$width.'s', $val);
-            }
-            $out .= "\n";
-        }
-        return $out;
-    }
-}
-
-/**
- * Class DokuCLI_Exception
- *
- * The code is used as exit code for the CLI tool. This should probably be extended. Many cases just fall back to the
- * E_ANY code.
- *
- * @author Andreas Gohr <andi@splitbrain.org>
- */
-class DokuCLI_Exception extends Exception {
-    const E_ANY = -1; // no error code specified
-    const E_UNKNOWN_OPT = 1; //Unrecognized option
-    const E_OPT_ARG_REQUIRED = 2; //Option requires argument
-    const E_OPT_ARG_DENIED = 3; //Option not allowed argument
-    const E_OPT_ABIGUOUS = 4; //Option abiguous
-    const E_ARG_READ = 5; //Could not read argv
-
-    /**
-     * @param string    $message     The Exception message to throw.
-     * @param int       $code        The Exception code
-     * @param Exception $previous    The previous exception used for the exception chaining.
-     */
-    public function __construct($message = "", $code = 0, Exception $previous = null) {
-        if(!$code) $code = DokuCLI_Exception::E_ANY;
-        parent::__construct($message, $code, $previous);
-    }
-}