| 
							- #!/usr/bin/env php
 - <?php
 - 
 - use splitbrain\phpcli\CLI;
 - use splitbrain\phpcli\Options;
 - 
 - if (!defined('DOKU_INC')) define('DOKU_INC', realpath(__DIR__ . '/../') . '/');
 - define('NOSESSION', 1);
 - require_once(DOKU_INC . 'inc/init.php');
 - 
 - /**
 -  * Easily manage DokuWiki git repositories
 -  *
 -  * @author Andreas Gohr <andi@splitbrain.org>
 -  */
 - class GitToolCLI extends CLI
 - {
 -     /**
 -      * Register options and arguments on the given $options object
 -      *
 -      * @param Options $options
 -      * @return void
 -      */
 -     protected function setup(Options $options)
 -     {
 -         $options->setHelp(
 -             "Manage git repositories for DokuWiki and its plugins and templates.\n\n" .
 -             "$> ./bin/gittool.php clone gallery template:ach\n" .
 -             "$> ./bin/gittool.php repos\n" .
 -             "$> ./bin/gittool.php origin -v"
 -         );
 - 
 -         $options->registerArgument(
 -             'command',
 -             'Command to execute. See below',
 -             true
 -         );
 - 
 -         $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'
 -         );
 - 
 -         $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'
 -         );
 - 
 -         $options->registerCommand(
 -             'repos',
 -             'Lists all git repositories found in 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'
 -         );
 -     }
 - 
 -     /**
 -      * Your main program
 -      *
 -      * Arguments and options have been parsed when this is run
 -      *
 -      * @param Options $options
 -      * @return void
 -      */
 -     protected function main(Options $options)
 -     {
 -         $command = $options->getCmd();
 -         $args = $options->getArgs();
 -         if (!$command) $command = array_shift($args);
 - 
 -         switch ($command) {
 -             case '':
 -                 echo $options->help();
 -                 break;
 -             case 'clone':
 -                 $this->cmdClone($args);
 -                 break;
 -             case 'install':
 -                 $this->cmdInstall($args);
 -                 break;
 -             case 'repo':
 -             case 'repos':
 -                 $this->cmdRepos();
 -                 break;
 -             default:
 -                 $this->cmdGit($command, $args);
 -         }
 -     }
 - 
 -     /**
 -      * Tries to install the given extensions using git clone
 -      *
 -      * @param array $extensions
 -      */
 -     public function cmdClone($extensions)
 -     {
 -         $errors = [];
 -         $succeeded = [];
 - 
 -         foreach ($extensions as $ext) {
 -             $repo = $this->getSourceRepo($ext);
 - 
 -             if (!$repo) {
 -                 $this->error("could not find a repository for $ext");
 -                 $errors[] = $ext;
 -             } elseif ($this->cloneExtension($ext, $repo)) {
 -                 $succeeded[] = $ext;
 -             } else {
 -                 $errors[] = $ext;
 -             }
 -         }
 - 
 -         echo "\n";
 -         if ($succeeded) $this->success('successfully cloned the following extensions: ' . implode(', ', $succeeded));
 -         if ($errors) $this->error('failed to clone the following extensions: ' . implode(', ', $errors));
 -     }
 - 
 -     /**
 -      * Tries to install the given extensions using git clone with fallback to install
 -      *
 -      * @param array $extensions
 -      */
 -     public function cmdInstall($extensions)
 -     {
 -         $errors = [];
 -         $succeeded = [];
 - 
 -         foreach ($extensions as $ext) {
 -             $repo = $this->getSourceRepo($ext);
 - 
 -             if (!$repo) {
 -                 $this->info("could not find a repository for $ext");
 -                 if ($this->downloadExtension($ext)) {
 -                     $succeeded[] = $ext;
 -                 } else {
 -                     $errors[] = $ext;
 -                 }
 -             } elseif ($this->cloneExtension($ext, $repo)) {
 -                 $succeeded[] = $ext;
 -             } else {
 -                 $errors[] = $ext;
 -             }
 -         }
 - 
 -         echo "\n";
 -         if ($succeeded) $this->success('successfully installed the following extensions: ' . implode(', ', $succeeded));
 -         if ($errors) $this->error('failed to install the following extensions: ' . implode(', ', $errors));
 -     }
 - 
 -     /**
 -      * Executes the given git command in every repository
 -      *
 -      * @param $cmd
 -      * @param $arg
 -      */
 -     public function cmdGit($cmd, $arg)
 -     {
 -         $repos = $this->findRepos();
 - 
 -         $shell = array_merge(['git', $cmd], $arg);
 -         $shell = array_map('escapeshellarg', $shell);
 -         $shell = implode(' ', $shell);
 - 
 -         foreach ($repos as $repo) {
 -             if (!@chdir($repo)) {
 -                 $this->error("Could not change into $repo");
 -                 continue;
 -             }
 - 
 -             $this->info("executing $shell in $repo");
 -             $ret = 0;
 -             system($shell, $ret);
 - 
 -             if ($ret == 0) {
 -                 $this->success("git succeeded in $repo");
 -             } else {
 -                 $this->error("git failed in $repo");
 -             }
 -         }
 -     }
 - 
 -     /**
 -      * Simply lists the repositories
 -      */
 -     public function cmdRepos()
 -     {
 -         $repos = $this->findRepos();
 -         foreach ($repos as $repo) {
 -             echo "$repo\n";
 -         }
 -     }
 - 
 -     /**
 -      * Install extension from the given download URL
 -      *
 -      * @param string $ext
 -      * @return bool|null
 -      */
 -     private function downloadExtension($ext)
 -     {
 -         /** @var helper_plugin_extension_extension $plugin */
 -         $plugin = plugin_load('helper', 'extension_extension');
 -         if (!$ext) die("extension plugin not available, can't continue");
 - 
 -         $plugin->setExtension($ext);
 - 
 -         $url = $plugin->getDownloadURL();
 -         if (!$url) {
 -             $this->error("no download URL for $ext");
 -             return false;
 -         }
 - 
 -         $ok = false;
 -         try {
 -             $this->info("installing $ext via download from $url");
 -             $ok = $plugin->installFromURL($url);
 -         } catch (Exception $e) {
 -             $this->error($e->getMessage());
 -         }
 - 
 -         if ($ok) {
 -             $this->success("installed $ext via download");
 -             return true;
 -         } else {
 -             $this->success("failed to install $ext via download");
 -             return false;
 -         }
 -     }
 - 
 -     /**
 -      * Clones the extension from the given repository
 -      *
 -      * @param string $ext
 -      * @param string $repo
 -      * @return bool
 -      */
 -     private function cloneExtension($ext, $repo)
 -     {
 -         if (str_starts_with($ext, 'template:')) {
 -             $target = fullpath(tpl_incdir() . '../' . substr($ext, 9));
 -         } else {
 -             $target = DOKU_PLUGIN . $ext;
 -         }
 - 
 -         $this->info("cloning $ext from $repo to $target");
 -         $ret = 0;
 -         system("git clone $repo $target", $ret);
 -         if ($ret === 0) {
 -             $this->success("cloning of $ext succeeded");
 -             return true;
 -         } else {
 -             $this->error("cloning of $ext failed");
 -             return false;
 -         }
 -     }
 - 
 -     /**
 -      * Returns all git repositories in this DokuWiki install
 -      *
 -      * Looks in root, template and plugin directories only.
 -      *
 -      * @return array
 -      */
 -     private function findRepos()
 -     {
 -         $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)
 -         );
 - 
 -         if (!$data) {
 -             $this->error('Found no .git directories');
 -         } else {
 -             $this->success('Found ' . count($data) . ' .git directories');
 -         }
 -         $data = array_map('fullpath', array_map('dirname', $data));
 -         return $data;
 -     }
 - 
 -     /**
 -      * Returns the repository for the given extension
 -      *
 -      * @param $extension
 -      * @return false|string
 -      */
 -     private function getSourceRepo($extension)
 -     {
 -         /** @var helper_plugin_extension_extension $ext */
 -         $ext = plugin_load('helper', 'extension_extension');
 -         if (!$ext) die("extension plugin not available, can't continue");
 - 
 -         $ext->setExtension($extension);
 - 
 -         $repourl = $ext->getSourcerepoURL();
 -         if (!$repourl) return false;
 - 
 -         // match github repos
 -         if (preg_match('/github\.com\/([^\/]+)\/([^\/]+)/i', $repourl, $m)) {
 -             $user = $m[1];
 -             $repo = $m[2];
 -             return 'https://github.com/' . $user . '/' . $repo . '.git';
 -         }
 - 
 -         // match gitorious repos
 -         if (preg_match('/gitorious.org\/([^\/]+)\/([^\/]+)?/i', $repourl, $m)) {
 -             $user = $m[1];
 -             $repo = $m[2];
 -             if (!$repo) $repo = $user;
 - 
 -             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 false;
 -     }
 - }
 - 
 - // Main
 - $cli = new GitToolCLI();
 - $cli->run();
 
 
  |