From 0ae8cbf5c0b1a198b963490985b7738392ebcb97 Mon Sep 17 00:00:00 2001 From: ahriman Date: Mon, 3 Dec 2018 19:22:25 -0500 Subject: installed dokuwiki, added to navbar, updated news --- wiki/bin/gittool.php | 340 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 340 insertions(+) create mode 100755 wiki/bin/gittool.php (limited to 'wiki/bin/gittool.php') diff --git a/wiki/bin/gittool.php b/wiki/bin/gittool.php new file mode 100755 index 0000000..63d5b44 --- /dev/null +++ b/wiki/bin/gittool.php @@ -0,0 +1,340 @@ +#!/usr/bin/php + + */ +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->cmd_clone($args); + break; + case 'install': + $this->cmd_install($args); + break; + case 'repo': + case 'repos': + $this->cmd_repos(); + break; + default: + $this->cmd_git($command, $args); + } + } + + /** + * Tries to install the given extensions using git clone + * + * @param array $extensions + */ + public function cmd_clone($extensions) { + $errors = array(); + $succeeded = array(); + + foreach($extensions as $ext) { + $repo = $this->getSourceRepo($ext); + + if(!$repo) { + $this->error("could not find a repository for $ext"); + $errors[] = $ext; + } else { + if($this->cloneExtension($ext, $repo)) { + $succeeded[] = $ext; + } else { + $errors[] = $ext; + } + } + } + + echo "\n"; + if($succeeded) $this->success('successfully cloned the following extensions: ' . join(', ', $succeeded)); + if($errors) $this->error('failed to clone the following extensions: ' . join(', ', $errors)); + } + + /** + * Tries to install the given extensions using git clone with fallback to install + * + * @param array $extensions + */ + public function cmd_install($extensions) { + $errors = array(); + $succeeded = array(); + + 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; + } + } else { + if($this->cloneExtension($ext, $repo)) { + $succeeded[] = $ext; + } else { + $errors[] = $ext; + } + } + } + + echo "\n"; + if($succeeded) $this->success('successfully installed the following extensions: ' . join(', ', $succeeded)); + if($errors) $this->error('failed to install the following extensions: ' . join(', ', $errors)); + } + + /** + * Executes the given git command in every repository + * + * @param $cmd + * @param $arg + */ + public function cmd_git($cmd, $arg) { + $repos = $this->findRepos(); + + $shell = array_merge(array('git', $cmd), $arg); + $shell = array_map('escapeshellarg', $shell); + $shell = join(' ', $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 cmd_repos() { + $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(substr($ext, 0, 9) == '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(); -- cgit 1.4.1-2-gfad0