From c1a9414f1d57b54ee64ad2f070cfa292df90e2f0 Mon Sep 17 00:00:00 2001
From: "Hahn Axel (hahn)" <axel.hahn@unibe.ch>
Date: Fri, 21 Jul 2023 16:12:28 +0200
Subject: [PATCH] git support for main as master branch

---
 config/lang/de-de.json                        |  5 +-
 config/lang/en-en.json                        |  5 +-
 .../deployment/classes/project.class.php      | 29 +++++++----
 .../deployment/classes/vcs.git.class.php      | 48 ++++++++++++++++---
 public_html/deployment/pages/act_build.php    |  4 +-
 5 files changed, 69 insertions(+), 22 deletions(-)

diff --git a/config/lang/de-de.json b/config/lang/de-de.json
index 3911549d..5ac8fc5e 100644
--- a/config/lang/de-de.json
+++ b/config/lang/de-de.json
@@ -89,7 +89,8 @@
     "class-project-error-no-archivedir": "FEHLER::KONFIGURATION: Es wurde kein Archiv-Verzeichnis ($aConfig[&quot;archiveDir&quot;]) definiert.",
     "class-project-error-no-config": "FEHLER::KONFIGURATION: Fuer dieses Projekt wurde keine Konfiguration gefunden.",
     "class-project-error-no-packagedir": "FEHLER::KONFIGURATION: Es wurde kein Paketverzeichnis ($aConfig[&quot;packageDir&quot;]) definiert.",
-    "class-project-error-no-repoaccess": "Auf das Projekt Repo konnte nicht zugegriffen werden (%s).",
+    "class-project-error-no-repoaccess": "Auf das Projekt Repo konnte nicht zugegriffen werden - oder es gibt noch keinen Remode Branch.",
+    "class-project-error-no-repoinfo": "Auf das Projekt Repo konnte nicht zugegriffen werden.",
     "class-project-error-packagedir-does-not-exist": "FEHLER::KONFIGURATION: Das gesetzte Paketverzeichnis existiert nicht: $aConfig[&quot;packageDir&quot;]=&quot;%s&quot;.",
     "class-project-error-packagedir-empty": "FEHLER::KONFIGURATION: Das Paketverzeichnis ($aConfig[&quot;packageDir&quot;]) ist leer; es muss auf ein Verzeichnis zeigen.",
     "class-project-error-project-id-does-not-exist": "FEHLER: Ein Projekt mit der ID %s exisitiert nicht.",    
@@ -142,7 +143,7 @@
     
     "class-project-info-no-package": "Für dieses Projekt wurde noch kein Paket erzeugt.",
     "class-project-info-no-package-in-queue": "Es ist kein Paket in der Queue.",
-    "class-project-info-repoaccess": "OK, Zugriff auf das Repo erfolgreich.",
+    "class-project-info-repoaccess": "OK, Zugriff auf das Repo erfolgreich. Gefundene Tags und Branches: %s",
     "class-project-info-table-packages": "Die nachfolgende Tabelle zeigt die bereits erzeugten Pakete an und wo diese verwendet werden.",
     "class-project-warning-cannot-delete-archive-dir": "WARNUNG: Das Archiv-Verzeichnis %s konnte nicht gel&ouml;scht werden.",
     "class-project-warning-cannot-delete-build-dir": "WARNUNG: Das Build-Verzeichnis %s konnte nicht gel&ouml;scht werden.",
diff --git a/config/lang/en-en.json b/config/lang/en-en.json
index aad495d6..b30efa89 100644
--- a/config/lang/en-en.json
+++ b/config/lang/en-en.json
@@ -88,7 +88,8 @@
     "class-project-error-no-archivedir": "ERROR::CONFIG: The archive directory ($aConfig[&quot;archiveDir&quot;]) was not defined.",
     "class-project-error-no-config": "ERROR::CONFIG: There is no configuration for this project.",
     "class-project-error-no-packagedir": "ERROR::CONFIG: The package diectory ($aConfig[&quot;packageDir&quot;]) was not defined.",
-    "class-project-error-no-repoaccess": "Unable to access the project repository (%s).",
+    "class-project-error-no-repoaccess": "Unable to access the project repository - or no remote branch was found.",
+    "class-project-error-no-repoinfo": "Unable to access the project repository.",
     "class-project-error-packagedir-does-not-exist": "ERROR::CONFIG: The package directory does not exist: $aConfig[&quot;packageDir&quot;]=&quot;%s&quot;.",
     "class-project-error-packagedir-empty": "ERROR::CONFIG: The package directory ($aConfig[&quot;packageDir&quot;]) is empty; it must point to a directory.",
     "class-project-error-project-id-does-not-exist": "ERROR: a project with ID %s does not exist.",    
@@ -143,7 +144,7 @@
     
     "class-project-info-no-package": "No build was created yet for this project.",
     "class-project-info-no-package-in-queue": "There is no package in the queue.",
-    "class-project-info-repoaccess": "OK, access to the repository was successful.",
+    "class-project-info-repoaccess": "OK, access to the repository was successful. Found tags and branches: %s",
     "class-project-info-table-packages": "The table below shows the existing packages and where they are in use.",
     "class-project-warning-cannot-delete-archive-dir": "WARNING: The archive directory %s could not be deleted.",
     "class-project-warning-cannot-delete-build-dir": "WARNING: The Build directory %s could not be deleted.",
diff --git a/public_html/deployment/classes/project.class.php b/public_html/deployment/classes/project.class.php
index 1fba1103..e1a38611 100644
--- a/public_html/deployment/classes/project.class.php
+++ b/public_html/deployment/classes/project.class.php
@@ -1089,7 +1089,7 @@ class project extends base {
 
     /**
      * return array of all (active and inactive) phases
-     * @return type
+     * @return array
      */
     public function getPlaces() {
         return $this->_aPlaces;
@@ -1612,15 +1612,19 @@ class project extends base {
 
     /**
      * get the name of the current branch (or default branch)
+     * @param bool  $bReturnMasterIfEmpty  flag: if there is no current branch then detect a master branch
      * @return string
      */
-    public function getBranchname() {
+    public function getBranchname($bReturnMasterIfEmpty=false) {
         $this->log(__FUNCTION__ . " start");
         $this->_initVcs();
         if ($this->_oVcs) {
             if (method_exists($this->_oVcs, "getCurrentBranch")) {
-                $this->setBranchname($this->_oVcs->getCurrentBranch());
-                return $this->_oVcs->getCurrentBranch();
+                $sCurrentBranch=$this->_oVcs->getCurrentBranch(true); // true means search for master branch if empty
+                if($sCurrentBranch){
+                    $this->setBranchname($sCurrentBranch);
+                    return $sCurrentBranch;
+                }
             }
         }
         return false;
@@ -3092,7 +3096,7 @@ class project extends base {
                         )
                         ."<pre>" . strip_tags($aRepodata["message"], '<br>') . "</pre>";
                 } else {
-                    $sReturn .= $this->_oHtml->getBox("error", sprintf(t('class-project-error-no-repoaccess'), $aRepodata["error"]))
+                    $sReturn .= $this->_oHtml->getBox("error", sprintf(t('class-project-error-no-repoinfo'), $aRepodata["error"]))
                             . $this->renderLink("setup") . '<br>';
                 }
 
@@ -3623,12 +3627,17 @@ class project extends base {
             'placeholder' => '',
         );
 
-        $aRepodata = $this->getRepoRevision();
-        if (is_array($aRepodata) && array_key_exists("message", $aRepodata)) {
-            $sRepoCheck = '<span class="ok">' . t('class-project-info-repoaccess') . '</span>';
+        // detect access to repo url
+        $aBranches=$this->getRemoteBranches();
+        // $aRepodata = $this->getRepoRevision();
+
+        // if (is_array($aRepodata) && array_key_exists("message", $aRepodata)) {
+        if (is_array($aBranches) && count($aBranches)) {
+            $sRepoCheck = '<span class="ok">' . sprintf(t('class-project-info-repoaccess'), count($aBranches)) . '</span>';
         } else {
-            $sRepoCheck = '<span class="error">' . sprintf(t('class-project-error-no-repoaccess'), $aRepodata["error"]) . '</span>';
-            $sMessages.=$this->_oHtml->getBox("error", sprintf(t('class-project-error-no-repoaccess'), $aRepodata["error"]));
+            $sRepoError=sprintf(t('class-project-error-no-repoaccess'), $aRepodata["error"]);
+            $sRepoCheck = '<span class="error">' . $sRepoError . '</span>';
+            $sMessages.=$this->_oHtml->getBox("error", $sRepoError);
         }
 
         // generate datalist with exisating ssh keys for auth field
diff --git a/public_html/deployment/classes/vcs.git.class.php b/public_html/deployment/classes/vcs.git.class.php
index 7f2f5584..4e8783f6 100644
--- a/public_html/deployment/classes/vcs.git.class.php
+++ b/public_html/deployment/classes/vcs.git.class.php
@@ -48,7 +48,7 @@ class vcs implements iVcs {
      * name of the default remote branch to access
      * @var string
      */
-    private $_sCurrentBranch = "origin/master";
+    private $_sCurrentBranch = "";
 
     /**
      * constructor
@@ -111,9 +111,10 @@ class vcs implements iVcs {
         $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->_sTempDir .= preg_replace('/[\@\.\:\/]/', '_', ($this->_sCurrentBranch ? $this->_sCurrentBranch : '__no-branch__') ) . '/';
 
-        if (!file_exists($this->_sTempDir . ".git") || true) {
+        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 && ';
@@ -164,12 +165,38 @@ class vcs implements iVcs {
 
     /**
      * get the current branch
-     * @param string $sBranchname  name of the branch
+     * @param bool  $bReturnMasterIfEmpty  flag: if there is no current branch then detect a master branch
+     * @return string
      */
-    public function getCurrentBranch() {
+    public function getCurrentBranch($bReturnMasterIfEmpty=false) {
+        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'
+     * @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;
+                    break;
+                }
+            }
+        }
+        return $sMasterBranch;
+    }
+
     /**
      * return the build type, i.e. git|svn|cvs|
      * @return string
@@ -229,11 +256,12 @@ class vcs implements iVcs {
         }
 
         $oCache = new AhCache($this->_getNameOfCacheModule(), "RemoteBranches");
-        $aOutput=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");
             $sGitCmd = 'export GIT_SSH="' . $this->_sWrapper . '" ; export PKEY="' . $this->_sKeyfile . '" ; ';
@@ -310,6 +338,7 @@ class vcs implements iVcs {
     public function getRemoteBranches($bIgnoreCache=false) {
         $this->log(__FUNCTION__."($bIgnoreCache) start");
         if (!$this->_aRemoteBranches || $bIgnoreCache) {
+            $this->log(__FUNCTION__."($bIgnoreCache) uncached");
             $this->_fetchRemoteBranches($bIgnoreCache);
         }
         return $this->_aRemoteBranches;
@@ -323,6 +352,9 @@ class vcs implements iVcs {
      */
     public function getRepoRevision($bRefresh=false) {
         $this->log(__FUNCTION__."($bRefresh) start");
+        if(!$this->_sCurrentBranch){
+            return false;
+        }
         $sMessage = $this->getCommitmessageByBranch(false, $bRefresh ? 'dummy_to_force_refresh' : false);
         if ($sMessage) {
             $aReturn = array(
@@ -425,6 +457,7 @@ class vcs implements iVcs {
             $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 && ';
@@ -441,6 +474,7 @@ class vcs implements iVcs {
         }
 
         $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>");
         // $sLoginfo = shell_exec($sGitCmd);
         exec($sGitCmd, $aOutput, $iRc);
@@ -512,7 +546,7 @@ class vcs implements iVcs {
         $sBranchname = str_replace("origin/", "", $this->_sCurrentBranch);
 
         $sGitCmd = 'export GIT_SSH="' . $this->_sWrapper . '" ; export PKEY="' . $this->_sKeyfile . '" ; ';
-        $aOutput=false;
+        $aOutput=[];
         $iRc=false;
         
         // this does not checkout tags in git v1.7 - only branches:
diff --git a/public_html/deployment/pages/act_build.php b/public_html/deployment/pages/act_build.php
index 4ed04d4a..265443a9 100644
--- a/public_html/deployment/pages/act_build.php
+++ b/public_html/deployment/pages/act_build.php
@@ -27,9 +27,11 @@ if (array_key_exists("branchname", $aParams)) {
     $sBranchname = $aParams["branchname"];
     $oPrj->setBranchname($aParams["branchname"]);
 } else {
-    $sBranchname = $oPrj->getBranchname();
+    $sBranchname = $oPrj->getBranchname(true);
 }
 
+echo "DEBUG: Branch: [$sBranchname]<br>";
+
 if (!array_key_exists("confirm", $aParams)) {
     // ------------------------------------------------------------
     // let the user click a button to make a new build
-- 
GitLab