diff --git a/public_html/deployment/classes/vcs.git.class.php b/public_html/deployment/classes/vcs.git.class.php index 312f957b56900a16797853c5d064004cfe780ed9..56239a197e94904a8cd8e1fc375c1f6c8243f8a6 100644 --- a/public_html/deployment/classes/vcs.git.class.php +++ b/public_html/deployment/classes/vcs.git.class.php @@ -1,7 +1,7 @@ <?php require_once("vcs.interface.php"); -require_once __DIR__.'/../../vendor/axelhahn/ahcache/cache.class.php'; +require_once __DIR__ . '/../../vendor/axelhahn/ahcache/cache.class.php'; /** * version control system :: GIT @@ -9,74 +9,85 @@ require_once __DIR__.'/../../vendor/axelhahn/ahcache/cache.class.php'; * * * @author hahn + * + * Axel: <axel.hahn@unibe.ch> + * (...) + * 2024-08-28 Axel php8 only; added variable types; short array syntax + */ -class vcs implements iVcs { -// class vcs { +class vcs implements iVcs +{ + // class vcs { /** * configuration * @var array */ - private $_aCfg = array(); + private array $_aCfg = []; /** * temp dir to fetch repo version and ommit message; its value will be * generated in set_config() * @var string */ - private $_sTempDir = false; // + private string $_sTempDir = ''; // /** * filename of ssh key file with complete path * @var string */ - private $_sKeyfile = false; + private string $_sKeyfile = ''; /** * filename of ssh wrapper script with complete path * @var string */ - private $_sWrapper = false; + private string $_sWrapper = ''; /** * flat array with remote branch names * @var array */ - private $_aRemoteBranches = array(); + private array $_aRemoteBranches = []; /** * name of the default remote branch to access * @var string */ - private $_sCurrentBranch = ""; + private string $_sCurrentBranch = ''; /** - * constructor + * Constructor * @param array $aRepoConfig */ - public function __construct($aRepoConfig = array()) { + public function __construct(array $aRepoConfig = []) + { $this->setConfig($aRepoConfig); $this->getRemoteBranches(); // to fill the cache } - + /** - * add a log messsage + * Add a log messsage * @global object $oLog + * * @param string $sMessage messeage text * @param string $sLevel warnlevel of the given message * @return bool */ - private function log($sMessage,$sLevel="info"){ + private function log(string $sMessage, string $sLevel = "info"): bool + { global $oCLog; - return $oCLog->add(basename(__FILE__)." class ".__CLASS__." - ".$sMessage,$sLevel); + return $oCLog->add(basename(__FILE__) . " class " . __CLASS__ . " - " . $sMessage, $sLevel); } /** - * set a config and update internal (private) variables + * Set a config and update internal (private) variables + * * @param array $aRepoConfig * @return boolean */ - public function setConfig($aRepoConfig = array()) { + public function setConfig(array $aRepoConfig = []): bool + { // checks // foreach (array("type", "url") as $key) { foreach (array("type") as $key) { @@ -99,50 +110,56 @@ class vcs implements iVcs { $this->_sWrapper = $this->_aCfg["appRootDir"] . "/shellscripts/gitsshwrapper.sh"; $this->_setTempdir(); - return $this->_aCfg = $aRepoConfig; + $this->_aCfg = $aRepoConfig; + return true; } /** - * set directory für current branch of a project below tempdir - * In it the branch will be initialized - * @return type + * Get directory für current branch of a project below tempdir + * If it does not exist yet it will be created and the repository will be initialized. + * + * @return string */ - private function _setTempdir() { + private function _setTempdir() + { $this->_sTempDir = $this->_aCfg["url"]; $this->_sTempDir = preg_replace('/[\@\.\:\/]/', '_', $this->_sTempDir); $this->_sTempDir = $this->_aCfg["tmpDir"] . '/checkout_vcsgit_' . $this->_sTempDir . '/'; - $this->_sTempDir .= preg_replace('/[\@\.\:\/]/', '_', ($this->_sCurrentBranch ? $this->_sCurrentBranch : '__no-branch__') ) . '/'; + $this->_sTempDir .= preg_replace('/[\@\.\:\/]/', '_', ($this->_sCurrentBranch ? $this->_sCurrentBranch : '__no-branch__')) . '/'; - if (!is_dir($this->_sTempDir . ".git") ) { - $this->log(__FUNCTION__." does not exist yet: " . $this->_sTempDir . ".git"); + if (!is_dir($this->_sTempDir . ".git")) { + $this->log(__FUNCTION__ . " does not exist yet: " . $this->_sTempDir . ".git"); $sGitCmd = 'export GIT_SSH="' . $this->_sWrapper . '" ; export PKEY="' . $this->_sKeyfile . '" ; '; - $sGitCmd.='mkdir -p "' . $this->_sTempDir . '" && cd "' . $this->_sTempDir . '" && '; - $sGitCmd.='git init >/dev/null && '; - $sGitCmd.='git remote add origin "' . $this->getUrl() . '" 2>&1 '; + $sGitCmd .= 'mkdir -p "' . $this->_sTempDir . '" && cd "' . $this->_sTempDir . '" && '; + $sGitCmd .= 'git init >/dev/null && '; + $sGitCmd .= 'git remote add origin "' . $this->getUrl() . '" 2>&1 '; // $sGitCmd='time ('.$sGitCmd.')'; // exec($sGitCmd, $aOutput, $iRc); - $this->log(__FUNCTION__." start command <code>$sGitCmd</code>"); - exec($sGitCmd, $aOutput,$iRc); - $this->log(__FUNCTION__." command ended with rc=$iRc ". '<pre>'.implode("\n", $aOutput).'</pre>', ($iRc==0 ? 'info':'error')); + $this->log(__FUNCTION__ . " start command <code>$sGitCmd</code>"); + exec($sGitCmd, $aOutput, $iRc); + $this->log(__FUNCTION__ . " command ended with rc=$iRc " . '<pre>' . implode("\n", $aOutput) . '</pre>', ($iRc == 0 ? 'info' : 'error')); } return $this->_sTempDir; } /** - * set the current branch + * Set the current branch + * * @param string $sBranchname name of the branch + * @return void */ - public function setCurrentBranch($sBranchname) { + public function setCurrentBranch($sBranchname): void + { $this->_sCurrentBranch = $sBranchname; $this->_setTempdir(); - return $this->_sCurrentBranch; } /** * helper: dump values * @return boolean */ - public function dump() { + public function dump(): bool + { 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>"; @@ -151,10 +168,14 @@ class vcs implements iVcs { /** * cleanup unneeded files and directories in a checked out directory - * and remove all vcs specific files and directories + * and remove all vcs specific files and directories. + * This method works on linux only + * + * @param string $sWorkDir path of the build directory to cleanup the git meta data from * @return bool */ - public function cleanupWorkdir($sWorkDir) { + public function cleanupWorkdir(string $sWorkDir): bool + { if (!is_dir($sWorkDir)) { return false; } @@ -164,32 +185,36 @@ class vcs implements iVcs { } /** - * get the current branch + * Get the current branch + * * @param bool $bReturnMasterIfEmpty flag: if there is no current branch then detect a master branch * @return string */ - public function getCurrentBranch($bReturnMasterIfEmpty=false) { - if(!$this->_sCurrentBranch){ - if ($bReturnMasterIfEmpty){ - $this->_sCurrentBranch=$this->_getMasterbranchname(); + public function getCurrentBranch(bool $bReturnMasterIfEmpty = false): string + { + if (!$this->_sCurrentBranch) { + if ($bReturnMasterIfEmpty) { + $this->_sCurrentBranch = $this->_getMasterbranchname(); } } return $this->_sCurrentBranch; } /** - * detect an existing master branch ... and return one of 'origin/main' | 'origin/master' + * Detect an existing master branch ... and return one of 'origin/main' | 'origin/master' + * * @return string */ - protected function _getMasterbranchname(){ - $sMasterBranch=''; - $aMasternames=['origin/main', 'origin/master']; - - $aAllBranches=$this->getRemoteBranches(); - if(count($aAllBranches)){ - foreach($aMasternames as $sBranchToTest){ - if (isset($aAllBranches[$sBranchToTest])){ - $sMasterBranch=$sBranchToTest; + protected function _getMasterbranchname(): string + { + $sMasterBranch = ''; + $aMasternames = ['origin/main', 'origin/master']; + + $aAllBranches = $this->getRemoteBranches(); + if (count($aAllBranches)) { + foreach ($aMasternames as $sBranchToTest) { + if (isset($aAllBranches[$sBranchToTest])) { + $sMasterBranch = $sBranchToTest; break; } } @@ -198,98 +223,109 @@ class vcs implements iVcs { } /** - * return the build type, i.e. git|svn|cvs| + * Get the build type, i.e. git|svn|cvs| * @return string */ - public function getBuildType() { - return $this->_aCfg["type"]; + public function getBuildType(): string + { + return $this->_aCfg["type"] ?? ''; } /** - * get a nice name for a cache module based on repo url - * @return type + * Get a nice name for a cache module based on repo url + * + * @return string */ - private function _getNameOfCacheModule() { + private function _getNameOfCacheModule(): string + { return preg_replace('/([^0-9a-z])/i', "", $this->getUrl()); } /** - * cleanup cache data for this project (revisions, list of branches+tags) + * Cleanup cache data for this project (revisions, list of branches+tags) + * + * @param int $iAge max age in sec; older items will be deleted * @return bool */ - public function cleanupCache($iAge) { - $this->log(__FUNCTION__." start"); + public function cleanupCache(int $iAge): string + { + $this->log(__FUNCTION__ . " start"); $oCache = new AhCache($this->_getNameOfCacheModule()); ob_start(); - $oCache->cleanup((int)$iAge); + $oCache->cleanup((int) $iAge); $sOut = ob_get_contents(); ob_end_clean(); return $sOut; } /** - * helper: cache hash with all branches + * helper: store hash with all branches in cache * It saves 1.5 sec for reading 300 branches + * * @return boolean */ - private function _cacheRemoteBranches() { - $iTtl=300; + private function _cacheRemoteBranches(): bool + { + $iTtl = 300; $oCache = new AhCache($this->_getNameOfCacheModule(), "RemoteBranches"); // $this->log(__FUNCTION__." <pre>".print_r($this->_aRemoteBranches, 1)."</pre>"); $oCache->write($this->_aRemoteBranches, $iTtl); return true; } - + /** - * read remote repository and get an array with names and revisions of + * Read remote repository and get an array with names and revisions of * all branches and tags - * pre branch you get an array element with the keys revision, name, type + * per branch you get an array element with the keys revision, name, type + * It returns false if there is no git url + * * @param bool $bIgnoreCache flag to overrde cache * @return array */ - private function _fetchRemoteBranches($bIgnoreCache = false) { - $this->log(__FUNCTION__."(bIgnoreCache = ".($bIgnoreCache ? 'true' : 'false').") start"); - $aReturn = array(); + private function _fetchRemoteBranches($bIgnoreCache = false): bool|array + { + $this->log(__FUNCTION__ . "(bIgnoreCache = " . ($bIgnoreCache ? 'true' : 'false') . ") start"); + $aReturn = []; - $sGitUrl=$this->getUrl(); + $sGitUrl = $this->getUrl(); if (!$sGitUrl) { return false; } $oCache = new AhCache($this->_getNameOfCacheModule(), "RemoteBranches"); - $aOutput=[]; - $iRc=false; + $aOutput = []; + $iRc = false; // list of cached branch keys if ($oCache->isExpired() || $bIgnoreCache) { // workdir is on level of set project ... going 1 level up means to leave the dir with the current branch $sWorkdir = dirname($this->_sTempDir) . '/fetchRemoteBranches/'; - $this->log(__FUNCTION__." - sWorkdir = $sWorkdir"); + $this->log(__FUNCTION__ . " - sWorkdir = $sWorkdir"); $sGitCmd = 'export GIT_SSH="' . $this->_sWrapper . '" ; export PKEY="' . $this->_sKeyfile . '" ; '; - + if (is_dir($sWorkdir . ".git")) { // if a subdir .git exists: // Verify if git remote -v contains the current git url // If not, we delete it - $sPreCmd='cd "' . $sWorkdir . '" 2>&1 && git remote -v 2>&1 | grep -F "' . $sGitUrl . '" >/dev/null || ( echo "DELETING .git dir..."; rm -rf .git && rc=$?; echo "rc=$rc"; sleep 1; exit $rc) '; - $this->log(__FUNCTION__." - start PRE command <code>$sPreCmd</code>"); + $sPreCmd = 'cd "' . $sWorkdir . '" 2>&1 && git remote -v 2>&1 | grep -F "' . $sGitUrl . '" >/dev/null || ( echo "DELETING .git dir..."; rm -rf .git && rc=$?; echo "rc=$rc"; sleep 1; exit $rc) '; + $this->log(__FUNCTION__ . " - start PRE command <code>$sPreCmd</code>"); exec($sPreCmd, $aPreLines, $iRc); - if (!$iRc==0){ - $this->log(__FUNCTION__." <code>".print_r($aPreLines, 1)."</code> rc=$iRc"); + if (!$iRc == 0) { + $this->log(__FUNCTION__ . " <code>" . print_r($aPreLines, 1) . "</code> rc=$iRc"); } } if (!is_dir($sWorkdir . ".git")) { - $sGitCmd.='mkdir -p "' . $sWorkdir . '" && cd "' . $sWorkdir . '" && '; - $sGitCmd.='git init >/dev/null && '; - $sGitCmd.='git remote add origin "' . $sGitUrl . '" 2>&1 && '; + $sGitCmd .= 'mkdir -p "' . $sWorkdir . '" && cd "' . $sWorkdir . '" && '; + $sGitCmd .= 'git init >/dev/null && '; + $sGitCmd .= 'git remote add origin "' . $sGitUrl . '" 2>&1 && '; } else { - $sGitCmd.='cd "' . $sWorkdir . '" 2>&1 && '; + $sGitCmd .= 'cd "' . $sWorkdir . '" 2>&1 && '; } - $sGitCmd.='git ls-remote --heads --tags origin 2>&1 ;'; - $this->log(__FUNCTION__." - start command <code>$sGitCmd</code>"); + $sGitCmd .= 'git ls-remote --heads --tags origin 2>&1 ;'; + $this->log(__FUNCTION__ . " - start command <code>$sGitCmd</code>"); exec($sGitCmd, $aOutput, $iRc); - $this->log(__FUNCTION__." - command ended with rc=$iRc ". '<pre>'.implode("\n", $aOutput).'</pre>', ($iRc==0 ? 'info':'error')); + $this->log(__FUNCTION__ . " - command ended with rc=$iRc " . '<pre>' . implode("\n", $aOutput) . '</pre>', ($iRc == 0 ? 'info' : 'error')); if ($iRc == 0) { $this->log(__FUNCTION__ . ' start reading all branches'); @@ -314,9 +350,9 @@ class vcs implements iVcs { // http://stackoverflow.com/questions/15472107/when-listing-git-ls-remote-why-theres-after-the-tag-name if (!preg_match('/\^\{\}$/', $sBranch)) { $sRevision = $aTmp[0]; - $sType = preg_replace('#/.*$#', '', $sBranchPath); + $sType = preg_replace('#/.*$#', '', $sBranchPath); $sName = ($sType == "heads") ? "origin/" . $sBranch : $sBranch; - + $sBranchKey = $sName; // $this->log(__FUNCTION__ . ' $sBranchKey = '.$sBranchKey); @@ -333,11 +369,11 @@ class vcs implements iVcs { } } $this->_aRemoteBranches = $aReturn; - $this->log(__FUNCTION__ . ' '.count($aReturn).' branches: <pre>'.print_r($this->_aRemoteBranches, 1).'</pre>'); + $this->log(__FUNCTION__ . ' ' . count($aReturn) . ' branches: <pre>' . print_r($this->_aRemoteBranches, 1) . '</pre>'); $this->_cacheRemoteBranches(); } else { // $this->_aRemoteBranches = $oCache->read(); - $this->log(__FUNCTION__." - No git access? --> deleting cache of former fetched branches..."); + $this->log(__FUNCTION__ . " - No git access? --> deleting cache of former fetched branches..."); $oCache->delete(); $this->_aRemoteBranches = []; } @@ -349,30 +385,34 @@ class vcs implements iVcs { } /** - * get a flat array with names of all remote branches + * Get a flat array with names of all remote branches * @param bool $bIgnoreCache flag: ignore caching; default: use cache * @return array */ - public function getRemoteBranches($bIgnoreCache=false) { - $this->log(__FUNCTION__."($bIgnoreCache) start"); + public function getRemoteBranches(bool $bIgnoreCache = false): array + { + $this->log(__FUNCTION__ . "($bIgnoreCache) start"); if (!$this->_aRemoteBranches || $bIgnoreCache) { - $this->log(__FUNCTION__."($bIgnoreCache) --> fetching fresh data"); + $this->log(__FUNCTION__ . "($bIgnoreCache) --> fetching fresh data"); $this->_fetchRemoteBranches($bIgnoreCache); } else { - $this->log(__FUNCTION__."($bIgnoreCache) --> returning cached data"); + $this->log(__FUNCTION__ . "($bIgnoreCache) --> returning cached data"); } return $this->_aRemoteBranches; } /** - * get current revision and commit message from remote repository + * Get current revision and commit message from remote repository * @see $this::getRevision + * It returns false if no branch is set + * * @param boolean $bRefresh optional: refresh data; default: use cache - * @return array + * @return bool|array */ - public function getRepoRevision($bRefresh=false) { - $this->log(__FUNCTION__."($bRefresh) start"); - if(!$this->_sCurrentBranch){ + public function getRepoRevision(bool $bRefresh = false): bool|array + { + $this->log(__FUNCTION__ . "($bRefresh) start"); + if (!$this->_sCurrentBranch) { return false; } $sMessage = $this->getCommitmessageByBranch(false, $bRefresh ? 'dummy_to_force_refresh' : false); @@ -383,7 +423,7 @@ class vcs implements iVcs { 'revision' => $this->_aRemoteBranches[$this->_sCurrentBranch]['revision'], 'type' => $this->_aRemoteBranches[$this->_sCurrentBranch]['type'], 'message' => $sMessage, - '_data'=>$this->_aRemoteBranches[$this->_sCurrentBranch], + '_data' => $this->_aRemoteBranches[$this->_sCurrentBranch], ); } else { $aReturn = $this->getRevision(false); @@ -392,31 +432,34 @@ class vcs implements iVcs { } /** - * get a commit message of a given branch + * Get a commit message of a given branch. + * It reurns if no branch was found in meta infos + * * @param string $sBranch name of a branch * @param string $sVerifyRevision optional: revision to verify if it is the newsest * @return string */ - public function getCommitmessageByBranch($sBranch = false, $sVerifyRevision = false) { - $this->log(__FUNCTION__."($sBranch, $sVerifyRevision) start"); + public function getCommitmessageByBranch(string $sBranch = '', string $sVerifyRevision = ''): bool|string + { + $this->log(__FUNCTION__ . "($sBranch, $sVerifyRevision) start"); if (!$sBranch) { $sBranch = $this->_sCurrentBranch; } // try to get infos from the cache if ( - is_array($this->_aRemoteBranches) - && ( - isset($this->_aRemoteBranches[$sBranch]) && $sVerifyRevision && $this->_aRemoteBranches[$sBranch]['revision'] == $sVerifyRevision - || - isset($this->_aRemoteBranches[$sBranch]) && !$sVerifyRevision - ) + is_array($this->_aRemoteBranches) + && ( + isset($this->_aRemoteBranches[$sBranch]) && $sVerifyRevision && $this->_aRemoteBranches[$sBranch]['revision'] == $sVerifyRevision + || + isset($this->_aRemoteBranches[$sBranch]) && !$sVerifyRevision + ) ) { // it is up to date - doing nothing - $this->log(__FUNCTION__." return cached data"); + $this->log(__FUNCTION__ . " return cached data"); return $this->_aRemoteBranches[$sBranch]['message']; } // ok, then I need to read it - $this->log(__FUNCTION__." return fresh data"); + $this->log(__FUNCTION__ . " return fresh data"); if ($this->_sCurrentBranch != $sBranch) { $sSaveBranch = $this->_sCurrentBranch; $this->setCurrentBranch($sBranch); @@ -425,14 +468,14 @@ class vcs implements iVcs { } else { $a = $this->getRevision(false); } - if(!isset($a['branch'])){ + if (!isset($a['branch'])) { return false; } // merge with cached info ... to add type and label - if(isset($this->_aRemoteBranches[$a['branch']])){ - $this->_aRemoteBranches[$a['branch']]=array_merge($this->_aRemoteBranches[$a['branch']], $a); + if (isset($this->_aRemoteBranches[$a['branch']])) { + $this->_aRemoteBranches[$a['branch']] = array_merge($this->_aRemoteBranches[$a['branch']], $a); } else { - $this->_aRemoteBranches[$a['branch']]=$a; + $this->_aRemoteBranches[$a['branch']] = $a; } // store in cache $this->_cacheRemoteBranches(); @@ -440,7 +483,7 @@ class vcs implements iVcs { } /** - * get current revision and commit message from an existing directory or a + * Get current revision and commit 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) @@ -455,14 +498,16 @@ class vcs implements iVcs { * array( * "error" => $sErrormessage, * ); + * * @param string $sWorkDir optional: local directory with initialized git repo - * @return array + * @return bool|array */ - public function getRevision($sWorkDir = false) { - $this->log(__FUNCTION__." start"); - $aReturn = array(); - $aOutput=array(); - $iRc=false; + public function getRevision(string $sWorkDir = ''): bool|array + { + $this->log(__FUNCTION__ . " start"); + $aReturn = []; + $aOutput = []; + $iRc = false; if (!$this->getUrl()) { return false; } @@ -477,33 +522,33 @@ class vcs implements iVcs { $sGitCmd.='git clone -b '.$this->_sCurrentBranch.' --single-branch '.$this->getUrl().' --depth 1 --bare "' . $sWorkDir . '" 2>&1; rm -rf "' . $sWorkDir . '"'; */ if ($sWorkDir) { - $sGitCmd.='cd "' . $sWorkDir . '" && '; + $sGitCmd .= 'cd "' . $sWorkDir . '" && '; } else { if (!file_exists($this->_sTempDir . ".git")) { - $this->log(__FUNCTION__." does not exist yet: ".$this->_sTempDir . ".git"); - $sGitCmd.='mkdir -p "' . $this->_sTempDir . '" && cd "' . $this->_sTempDir . '" && '; - $sGitCmd.='git init >/dev/null 2>&1 && '; - $sGitCmd.='git remote add origin "' . $this->getUrl() . '" 2>&1 && '; + $this->log(__FUNCTION__ . " does not exist yet: " . $this->_sTempDir . ".git"); + $sGitCmd .= 'mkdir -p "' . $this->_sTempDir . '" && cd "' . $this->_sTempDir . '" && '; + $sGitCmd .= 'git init >/dev/null 2>&1 && '; + $sGitCmd .= 'git remote add origin "' . $this->getUrl() . '" 2>&1 && '; } else { - $sGitCmd.='cd "' . $this->_sTempDir . '" && '; + $sGitCmd .= 'cd "' . $this->_sTempDir . '" && '; } // TODO: git 1.9 does needs only the line with --tags - $sGitCmd.=' ( ' - // . 'git fetch --update-head-ok --tags --depth 1 2>&1 ; ' // 1.5 s - . 'git fetch --update-head-ok --tags --depth 1 2>&1 ; ' // 1.5 s - //. 'git fetch --update-head-ok --depth 1 2>&1 ' // 1.5 s - . ') && '; + $sGitCmd .= ' ( ' + // . 'git fetch --update-head-ok --tags --depth 1 2>&1 ; ' // 1.5 s + . 'git fetch --update-head-ok --tags --depth 1 2>&1 ; ' // 1.5 s + //. 'git fetch --update-head-ok --depth 1 2>&1 ' // 1.5 s + . ') && '; } - $sGitCmd.='git log -1 "' . $this->_sCurrentBranch . '" 2>&1 ; '; // 0.0 s + $sGitCmd .= 'git log -1 "' . $this->_sCurrentBranch . '" 2>&1 ; '; // 0.0 s // $sGitCmd.='git log -1 2>&1 ; '; // 0.0 s - $this->log(__FUNCTION__." start command <code>$sGitCmd</code>"); + $this->log(__FUNCTION__ . " start command <code>$sGitCmd</code>"); // $sLoginfo = shell_exec($sGitCmd); exec($sGitCmd, $aOutput, $iRc); - $this->log(__FUNCTION__." command ended with rc=$iRc ". '<pre>'.implode("\n", $aOutput).'</pre>', ($iRc==0 ? 'info':'error')); - $sLoginfo= implode("\n", $aOutput); - + $this->log(__FUNCTION__ . " command ended with rc=$iRc " . '<pre>' . implode("\n", $aOutput) . '</pre>', ($iRc == 0 ? 'info' : 'error')); + $sLoginfo = implode("\n", $aOutput); + /* * * example output: @@ -521,7 +566,7 @@ class vcs implements iVcs { // parse revision $sRevision = false; - $aRev=array(); + $aRev = []; if (preg_match('#commit\ (.*)#', $sLoginfo, $aRev)) { $sRevision = $aRev[1]; } @@ -555,11 +600,16 @@ class vcs implements iVcs { } /** - * get sources from vsc and check them out in given directory - * @return bool + * Get sources from vsc and check them out in given directory + * It returns false if the workdir was not found or the url for git repo is not set + * Otherwise it retunrs the output of git clone + git checkout + * + * @param string $sWorkDir working dir where to check out source url + * @return bool|string */ - public function getSources($sWorkDir) { - $this->log(__FUNCTION__." start"); + public function getSources(string $sWorkDir): bool|string + { + $this->log(__FUNCTION__ . " start"); if (!$sWorkDir || !is_dir($sWorkDir)) { return false; } @@ -569,36 +619,42 @@ class vcs implements iVcs { $sBranchname = str_replace("origin/", "", $this->_sCurrentBranch); $sGitCmd = 'export GIT_SSH="' . $this->_sWrapper . '" ; export PKEY="' . $this->_sKeyfile . '" ; '; - $aOutput=[]; - $iRc=false; - + $aOutput = []; + $iRc = false; + // this does not checkout tags in git v1.7 - only branches: // $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; '; // - $sGitCmd .= 'echo git clone "' . $this->getUrl() . '" "'.$sWorkDir.'" 2>&1 \&\& cd "'.$sWorkDir.'" \&\& git checkout "' . $sBranchname . '" ; '; - $sGitCmd .= ' git clone "' . $this->getUrl() . '" "'.$sWorkDir.'" 2>&1 && cd "'.$sWorkDir.'" && git checkout "' . $sBranchname . '" 2>&1 '; - $this->log(__FUNCTION__." start command <code>$sGitCmd</code>"); + $sGitCmd .= 'echo git clone "' . $this->getUrl() . '" "' . $sWorkDir . '" 2>&1 \&\& cd "' . $sWorkDir . '" \&\& git checkout "' . $sBranchname . '" ; '; + $sGitCmd .= ' git clone "' . $this->getUrl() . '" "' . $sWorkDir . '" 2>&1 && cd "' . $sWorkDir . '" && git checkout "' . $sBranchname . '" 2>&1 '; + $this->log(__FUNCTION__ . " start command <code>$sGitCmd</code>"); // $sReturn = shell_exec($sGitCmd); exec($sGitCmd, $aOutput, $iRc); - $this->log(__FUNCTION__." command ended with rc=$iRc ". '<pre>'.implode("\n", $aOutput).'</pre>', ($iRc==0 ? 'info':'error')); - return implode("\n", $aOutput). "\nrc=$iRc"; + $this->log(__FUNCTION__ . " command ended with rc=$iRc " . '<pre>' . implode("\n", $aOutput) . '</pre>', ($iRc == 0 ? 'info' : 'error')); + return implode("\n", $aOutput) . "\nrc=$iRc"; } /** - * return url to vcs sources + * Get url to vcs sources + * + * @return string */ - public function getUrl() { - $this->log(__FUNCTION__." --> ".$this->_aCfg["url"]); - return $this->_aCfg["url"]; + public function getUrl(): string + { + $this->log(__FUNCTION__ . " --> " . $this->_aCfg["url"]); + return $this->_aCfg["url"] ?? ''; } /** - * return url to view sources in webrowser to generate an infolink + * Get url to view sources in webrowser to generate an infolink + * + * @return string */ - public function getWebGuiUrl() { - $this->log(__FUNCTION__." start"); - return $this->_aCfg["webaccess"]; + public function getWebGuiUrl(): string + { + $this->log(__FUNCTION__ . " start"); + return $this->_aCfg["webaccess"] ?? ''; } } diff --git a/public_html/deployment/classes/vcs.interface.php b/public_html/deployment/classes/vcs.interface.php index 4ced62baa3d2120643dc6cc981830310cedd30ed..d52a50802460ec613a87da5c0b9177493e9f0aa3 100644 --- a/public_html/deployment/classes/vcs.interface.php +++ b/public_html/deployment/classes/vcs.interface.php @@ -4,6 +4,10 @@ * * interface for a version control system * @author hahn + * + * Axel: <axel.hahn@unibe.ch> + * (...) + * 2024-08-28 Axel php8 only; added variable types; short array syntax */ interface iVcs { @@ -14,46 +18,54 @@ interface iVcs { /** * return url to vcs sources */ - public function getUrl(); + public function getUrl(): string; /** * return url to view sources in webrowser to generate an infolink */ - public function getWebGuiUrl(); + public function getWebGuiUrl(): string; /** * return the build type, i.e. git|svn|cvs| */ - public function getBuildType(); + public function getBuildType(): string; // ---------------------------------------------------------------------- // actions // ---------------------------------------------------------------------- + /** * cleanup unneeded files and directories in a checked out directory - * and remove all vcs specific files and directories + * and remove all vcs specific files and directories. + * This method works on linux only + * + * @param string $sWorkDir path of the build directory to cleanup the vcs meta data from * @return bool */ - public function cleanupWorkdir($sWorkDir); + public function cleanupWorkdir(string $sWorkDir): bool; /** * get current revision and commit message from remote repository * @param boolean $bRefresh optional: refresh data; default: use cache * @return array */ - public function getRepoRevision($bRefresh=false); + public function getRepoRevision(bool $bRefresh=false); /** * get current revision and log message from given directory - * @return array + * @return bool|array */ - public function getRevision($sWorkDir); - + public function getRevision(string $sWorkDir = ''): bool|array; + /** - * get sources from vsc and check them out in given directory - * @return bool + * Get sources from vsc and check them out in given directory + * It returns false if the workdir was not found or the url for git repo is not set + * Otherwise it retunrs the output of the checkout commands + * + * @param string $sWorkDir working dir where to check out source url + * @return bool|string */ - public function getSources($sWorkDir); + public function getSources(string $sWorkDir): bool|string; }