Skip to content
Snippets Groups Projects
Select Git revision
  • a5ae17a54c2485e893b6004f2ba0ab0d753191f0
  • master default protected
  • Legacy_Php7
3 results

vcs.git.class.php

Blame
  • user avatar
    hahn authored
    - changed: data dirs
    WARNING: deployment requires manual changes!
    ALPHA: 
    - settings, roles
    a5ae17a5
    History
    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"];
        }
    
    }