Select Git revision
vcs.git.class.php
vcs.git.class.php 8.47 KiB
<?php
require_once("vcs.interface.php");
/**
* version control system :: GIT
* implements vcs interface
*
*
* @author hahn
*/
class vcs implements iVcs {
// class vcs {
/**
* configuration
* @var array
*/
private $_aCfg = array();
/**
* temp dir to fetch repo version and ommit message; its value will be
* generated in set_config()
* @var string
*/
private $_sTempDir = false; //
/**
* filename of ssh key file with complete path
* @var string
*/
private $_sKeyfile = false;
/**
* filename of ssh wrapper script with complete path
* @var string
*/
private $_sWrapper = false;
/**
* flat array with remote branch names
* @var array
*/
private $_aRemoteBranches = array();
/**
* name of the remote branch to access
* @var type
*/
private $_sCurrentBranch = "origin/master";
/**
* constructor
* @param array $aRepoConfig
*/
public function __construct($aRepoConfig = array()) {
$this->setConfig($aRepoConfig);
}
/**
* set a config and update internal (private) variables
* @param array $aRepoConfig
* @return boolean
*/
public function setConfig($aRepoConfig = array()) {
// checks
foreach (array("type", "url") as $key) {
if (!array_key_exists($key, $aRepoConfig)) {
die("ERROR: key $key does not exist in config <pre>" . print_r($aRepoConfig, true) . "</pre>");
}
if (!$aRepoConfig[$key]) {
die("ERROR: key $key in config exists but is empty<pre>" . print_r($aRepoConfig, true) . "</pre>");
}
}
if ($aRepoConfig["type"] !== "git") {
die("ERROR: type is not git<pre>" . print_r($aRepoConfig, true) . "</pre>");
}
// set config array
$this->_aCfg = $aRepoConfig;
// define temp dir
$this->_sTempDir = $this->_aCfg["url"];
$this->_sTempDir = preg_replace('/[\@\.\:\/]/', '_', $this->_sTempDir);
$this->_sTempDir = (getenv("temp") ? getenv("temp") : "/tmp") . '/checkout_vcsgit_' . $this->_sTempDir . "/";
$this->_sKeyfile = $this->_aCfg["dataDir"] . "/sshkeys/" . $this->_aCfg["auth"];
$this->_sWrapper = $this->_aCfg["appRootDir"] . "/shellscripts/gitsshwrapper.sh";
return $this->_aCfg = $aRepoConfig;
}
/**
* set the current branch
* @param string $sBranchname name of the branch
*/
public function setCurrentBranch($sBranchname) {
return $this->_sCurrentBranch=$sBranchname;
}
/**
* helper: dump values
* @return boolean
*/
public function dump() {
echo "<h3>Dump class " . __CLASS__ . "</h3>";
echo "config array: <pre>" . print_r($this->_aCfg, true) . "</pre>";
echo "temp dir to read revision: " . $this->_sTempDir . "<br>";
return true;
}
/**
* cleanup unneeded files and directories in a checked out directory
* and remove all vcs specific files and directories
* @return bool
*/
public function cleanupWorkdir($sWorkDir) {
if (!is_dir($sWorkDir)) {
return false;
}
shell_exec('rm -rf "' . $sWorkDir . '/.git"');
@unlink($sWorkDir . "/.gitignore");
return true;
}
/**
* get the current branch
* @param string $sBranchname name of the branch
*/
public function getCurrentBranch() {
return $this->_sCurrentBranch;
}
/**
* return the build type, i.e. git|svn|cvs|
* @return string
*/
public function getBuildType() {
return $this->_aCfg["type"];
}
/**
* read remote repository and get a flat array with names of all branches
* @return array
*/
private function _fetchRemoteBranches() {
$aReturn = array();
$sGitCmd = 'export GIT_SSH="' . $this->_sWrapper . '" ; export PKEY="' . $this->_sKeyfile . '" ; ';
if (!file_exists($this->_sTempDir . ".git")) {
$sGitCmd.='mkdir "' . $this->_sTempDir . '" && cd "' . $this->_sTempDir . '" && ';
$sGitCmd.='git init >/dev/null && ';
$sGitCmd.='git remote add origin "' . $this->getUrl() . '" && ';
} else {
$sGitCmd.='cd "' . $this->_sTempDir . '" && ';
}
$sGitCmd.='git branch -r ; ';
exec($sGitCmd, $aOutput, $iRc);
if ($iRc == 0) {
foreach ($aOutput as $sBranch) {
// $aReturn[] = str_replace("origin/", "", trim($sBranch));
$aReturn[] = trim($sBranch);
}
}
$this->_aRemoteBranches = $aReturn;
return $aReturn;
}
/**
* get a flat array with names of all remote branches
* @return array
*/
public function getRemoteBranches() {
if (!$this->_aRemoteBranches) {
$this->_aRemoteBranches = $this->_fetchRemoteBranches();
}
return $this->_aRemoteBranches;
}
/**
* get current revision and log message from remote repository
* @see $this::getRevision
* @return array
*/
public function getRepoRevision() {
return $this->getRevision(false);
}
/**
* get current revision and log message from an existing directory or a
* remote repository
* the return will fill $this->_aData["phases"]["source"] in project class
* (array keys are revision, message or error)
* if ok:
* array(
* "revision" => $sRevision,
* "message" => $sCommitmessage
* );
*
* on error:
* array(
* "error" => $sErrormessage,
* );
* @return array
*/
public function getRevision($sWorkDir = false) {
$aReturn = array();
$sGitCmd = 'export GIT_SSH="' . $this->_sWrapper . '" ; export PKEY="' . $this->_sKeyfile . '" ; ';
if ($sWorkDir) {
$sGitCmd.='cd "' . $sWorkDir . '" && ';
} else {
if (!file_exists($this->_sTempDir . ".git")) {
$sGitCmd.='mkdir "' . $this->_sTempDir . '" && cd "' . $this->_sTempDir . '" && ';
$sGitCmd.='git init >/dev/null && ';
$sGitCmd.='git remote add origin "' . $this->getUrl() . '" && ';
} else {
$sGitCmd.='cd "' . $this->_sTempDir . '" && ';
}
$sGitCmd.='git fetch --update-head-ok --depth 1 2>&1 && ';
}
$sGitCmd.='git log -1 "' . $this->_sCurrentBranch . '" ; ';
$sLoginfo = shell_exec($sGitCmd);
$sRevision = false;
if (preg_match('#commit\ (.*)#', $sLoginfo, $aRev)) {
$sRevision = $aRev[1];
}
if ($sRevision) {
$aReturn = array(
"branch" => $this->_sCurrentBranch,
"revision" => $sRevision,
"message" => $sLoginfo
);
} else {
if (!$sLoginfo) {
$sLoginfo = $sGitCmd;
}
$aReturn = array(
"error" => '<pre>'.$sLoginfo.'<hr>'.$sGitCmd.'</pre>'
);
}
return $aReturn;
}
/**
* get sources from vsc and check them out in given directory
* @return bool
*/
public function getSources($sWorkDir) {
if (!$sWorkDir || !is_dir($sWorkDir)) {
return false;
}
$sBranchname=$this->_sCurrentBranch;
$sBranchname=str_replace("origin/", "", $sBranchname);
$sGitCmd = 'export GIT_SSH="' . $this->_sWrapper . '" ; export PKEY="' . $this->_sKeyfile . '" ; ';
$sGitCmd .= 'echo git clone --depth 1 --recursive --branch "' . $sBranchname . '" "' . $this->getUrl() . '" "' . $sWorkDir . '" ; ';
$sGitCmd .= 'git clone --depth 1 --recursive --branch "' . $sBranchname . '" "' . $this->getUrl() . '" "' . $sWorkDir . '" 2>&1; ';
$sReturn=shell_exec($sGitCmd);
return $sReturn;
}
/**
* return url to vcs sources
*/
public function getUrl() {
return $this->_aCfg["url"];
}
/**
* return url to view sources in webrowser to generate an infolink
*/
public function getWebGuiUrl() {
return $this->_aCfg["webaccess"];
}
}