diff options
Diffstat (limited to 'Zotlabs/Storage/GitRepo.php')
-rw-r--r-- | Zotlabs/Storage/GitRepo.php | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/Zotlabs/Storage/GitRepo.php b/Zotlabs/Storage/GitRepo.php new file mode 100644 index 000000000..2a24e03c0 --- /dev/null +++ b/Zotlabs/Storage/GitRepo.php @@ -0,0 +1,141 @@ +<?php + +namespace Zotlabs\Storage; + +use PHPGit\Git as PHPGit; + +require __DIR__ . '/../../library/PHPGit.autoload.php'; // Load PHPGit dependencies + +/** + * Wrapper class for PHPGit class for git repositories managed by Hubzilla + * + * @author Andrew Manning <andrewmanning@grid.reticu.li> + */ +class GitRepo { + + public $url = null; + public $name = null; + private $path = null; + private $channel = null; + public $git = null; + private $repoBasePath = null; + + function __construct($channel = 'sys', $url = null, $clone = false, $name = null, $path = null) { + + if ($channel === 'sys' && !is_site_admin()) { + logger('Only admin can use channel sys'); + return null; + } + + $this->repoBasePath = __DIR__ . '/../../store/git'; + $this->channel = $channel; + $this->git = new PHPGit(); + + // Allow custom path for repo in the case of , for example + if ($path) { + $this->path = $path; + } else { + $this->path = $this->repoBasePath . "/" . $this->channel . "/" . $this->name; + } + + if ($this->isValidGitRepoURL($url)) { + $this->url = $url; + } + + if ($name) { + $this->name = $name; + } else { + $this->name = $this->getRepoNameFromURL($url); + } + if (!$this->name) { + logger('Error creating GitRepo. No repo name found.'); + return null; + } + + if (is_dir($this->path)) { + // ignore the $url input if it exists + // TODO: Check if the path is either empty or is a valid git repo and error if not + $this->git->setRepository($this->path); + // TODO: get repo metadata + return; + } + + if ($this->url) { + // create the folder and clone the repo at url to that folder if $clone is true + if ($clone) { + if (mkdir($this->path, 0770, true)) { + $this->git->setRepository($this->path); + if (!$this->cloneRepo()) { + // TODO: throw error + logger('git clone failed: ' . json_encode($this->git)); + } + } else { + logger('git repo path could not be created: ' . json_encode($this->git)); + } + } + } + } + + public function pull() { + try { + $success = $this->git->pull(); + } catch (\PHPGit\Exception\GitException $ex) { + return false; + } + return $success; + } + + public function getRepoPath() { + return $this->path; + } + + public function setRepoPath($directory) { + if (is_dir($directory)) { + $this->path->$directory; + $this->git->setRepository($directory); + return true; + } + return false; + } + + public function setIdentity($user_name, $user_email) { + // setup user for commit messages + $this->git->config->set("user.name", $user_name, ['global' => false, 'system' => false]); + $this->git->config->set("user.email", $user_email, ['global' => false, 'system' => false]); + } + + public function cloneRepo() { + if (validate_url($this->url) && $this->isValidGitRepoURL($this->url) && is_dir($this->path)) { + return $this->git->clone($this->url, $this->path); + } + } + + public function probeRepo() { + $git = $this->git; + $repo = array(); + $repo['remote'] = $git->remote(); + $repo['branches'] = $git->branch(['all' => true]); + $repo['logs'] = $git->log(array('limit' => 50)); + return $repo; + } + + public static function isValidGitRepoURL($url) { + if (validate_url($url) && strrpos(parse_url($url, PHP_URL_PATH), '.')) { + return true; + } else { + return false; + } + } + + public static function getRepoNameFromURL($url) { + $urlpath = parse_url($url, PHP_URL_PATH); + $lastslash = strrpos($urlpath, '/') + 1; + $gitext = strrpos($urlpath, '.'); + if ($gitext) { + return substr($urlpath, $lastslash, $gitext - $lastslash); + } else { + return null; + } + } + +} |