From e8ed1d997525ac19ce75f88bdd605fd61cc172e1 Mon Sep 17 00:00:00 2001
From: Gero Lueckemeyer <gero.lueckemeyer@hft-stuttgart.de>
Date: Fri, 12 Jul 2024 19:22:36 +0200
Subject: [PATCH] cleaned repo handling

---
 .../dtabackend/rest/v1/task/TaskUpload.java   |   4 +-
 .../rest/v1/unittest/UnitTestUpload.java      |   6 +-
 .../dtabackend/utils/ExecuteTestUtil.java     |   4 +-
 .../dtabackend/utils/JGitUtil.java            |  73 -----------
 .../dtabackend/utils/RepoUtil.java            | 119 ++++++++++++++++++
 5 files changed, 126 insertions(+), 80 deletions(-)
 delete mode 100644 src/main/java/de/hftstuttgart/dtabackend/utils/JGitUtil.java
 create mode 100644 src/main/java/de/hftstuttgart/dtabackend/utils/RepoUtil.java

diff --git a/src/main/java/de/hftstuttgart/dtabackend/rest/v1/task/TaskUpload.java b/src/main/java/de/hftstuttgart/dtabackend/rest/v1/task/TaskUpload.java
index 39119f3..1b4c4ca 100644
--- a/src/main/java/de/hftstuttgart/dtabackend/rest/v1/task/TaskUpload.java
+++ b/src/main/java/de/hftstuttgart/dtabackend/rest/v1/task/TaskUpload.java
@@ -31,13 +31,13 @@ import jakarta.servlet.annotation.MultipartConfig;
 public class TaskUpload {
     private static final Logger LOG = LogManager.getLogger(TaskUpload.class);
 
-    private final JGitUtil jGitUtil;
+    private final RepoUtil jGitUtil;
     private final Path testTmpPath;
     private final ExecuteTestUtil executeTestUtil;
 
     public TaskUpload(
         Environment env,
-        JGitUtil jGitUtil,
+        RepoUtil jGitUtil,
         ExecuteTestUtil executeTestUtil
     ) {
         this.jGitUtil = jGitUtil;
diff --git a/src/main/java/de/hftstuttgart/dtabackend/rest/v1/unittest/UnitTestUpload.java b/src/main/java/de/hftstuttgart/dtabackend/rest/v1/unittest/UnitTestUpload.java
index a894655..ce8b59a 100644
--- a/src/main/java/de/hftstuttgart/dtabackend/rest/v1/unittest/UnitTestUpload.java
+++ b/src/main/java/de/hftstuttgart/dtabackend/rest/v1/unittest/UnitTestUpload.java
@@ -1,6 +1,6 @@
 package de.hftstuttgart.dtabackend.rest.v1.unittest;
 
-import de.hftstuttgart.dtabackend.utils.JGitUtil;
+import de.hftstuttgart.dtabackend.utils.RepoUtil;
 import de.hftstuttgart.dtabackend.utils.RegexUtil;
 
 import org.apache.logging.log4j.LogManager;
@@ -30,10 +30,10 @@ import java.util.regex.Pattern;
 public class UnitTestUpload {
 
     private static final Logger LOG = LogManager.getLogger(UnitTestUpload.class);
-    private final JGitUtil jGitUtil;
+    private final RepoUtil jGitUtil;
     private final String assignmentBasePath;
 
-    public UnitTestUpload(Environment env, JGitUtil jGitUtil) {
+    public UnitTestUpload(Environment env, RepoUtil jGitUtil) {
         this.jGitUtil = jGitUtil;
 
         Path p = Paths.get(env.getProperty("data.dir"), env.getProperty("data.dir.test.folder.name"));
diff --git a/src/main/java/de/hftstuttgart/dtabackend/utils/ExecuteTestUtil.java b/src/main/java/de/hftstuttgart/dtabackend/utils/ExecuteTestUtil.java
index 17fd1b1..6ba00f8 100644
--- a/src/main/java/de/hftstuttgart/dtabackend/utils/ExecuteTestUtil.java
+++ b/src/main/java/de/hftstuttgart/dtabackend/utils/ExecuteTestUtil.java
@@ -26,7 +26,7 @@ import java.util.regex.Pattern;
 public class ExecuteTestUtil  {
     private static final Logger LOG = LogManager.getLogger(ExecuteTestUtil.class);
 
-    private final JGitUtil jGitUtil;
+    private final RepoUtil jGitUtil;
     private final DockerUtil dockerUtil;
     private final String assignmentBasePath;
     private final Path testTmpPathHost;
@@ -34,7 +34,7 @@ public class ExecuteTestUtil  {
 
     public ExecuteTestUtil(
         Environment env,
-        JGitUtil jGitUtil,
+        RepoUtil jGitUtil,
         DockerUtil dockerUtil
     ) {
         this.jGitUtil = jGitUtil;
diff --git a/src/main/java/de/hftstuttgart/dtabackend/utils/JGitUtil.java b/src/main/java/de/hftstuttgart/dtabackend/utils/JGitUtil.java
deleted file mode 100644
index 29bb630..0000000
--- a/src/main/java/de/hftstuttgart/dtabackend/utils/JGitUtil.java
+++ /dev/null
@@ -1,73 +0,0 @@
-package de.hftstuttgart.dtabackend.utils;
-
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.eclipse.jgit.api.CloneCommand;
-import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.api.errors.GitAPIException;
-import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
-import org.springframework.stereotype.Component;
-import org.springframework.util.FileSystemUtils;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.regex.Matcher;
-
-@Component
-public class JGitUtil {
-
-    private static final Logger LOG = LogManager.getLogger(JGitUtil.class);
-
-    public JGitUtil() {}
-
-    public void cloneRepository(Matcher config, String targetPath, String subDir) {
-        LOG.debug(String.format("cloning repository: %s", config.group(1)));
-
-        File targetDirectory = new File(targetPath);
-        if (targetDirectory.exists()) {
-            LOG.debug("clone target directory existing yet, deleting now");
-            FileSystemUtils.deleteRecursively(targetDirectory);
-        }
-
-        File checkoutDirectory = targetDirectory;
-        //if an optional directory parameter was given
-        if(subDir!="")
-        {
-        	//create companion checkout dir "targetPath"+"_checkout"
-            checkoutDirectory = new File(targetPath+"_checkout");
-            if (checkoutDirectory.exists()) {
-            	LOG.debug("clone checkout directory existing yet, deleting now");
-            	FileSystemUtils.deleteRecursively(checkoutDirectory);
-            }
-        }
-        
-        try {
-            LOG.debug("preparing clone");
-            CloneCommand cloneCommand = Git.cloneRepository()
-                .setDirectory(checkoutDirectory)
-                .setURI(config.group(1));
-
-            if (!config.group(2).equals("none") && !config.group(3).equals("none")) {
-                LOG.debug("setting credentials");
-                cloneCommand.setCredentialsProvider(new UsernamePasswordCredentialsProvider(config.group(2), config.group(3)));
-            }
-
-            LOG.debug("cloning...");
-            cloneCommand.call().close();
-            
-            //if an optional directory parameter was given
-            if(subDir!="")
-            {
-            	//copy appropriate path from checkout directory to target directory
-            	FileSystemUtils.copyRecursively(new File(checkoutDirectory+subDir), new File(targetPath));
-            }
-            LOG.debug(String.format("cloned from %s to %s", config.group(1), targetDirectory));            
-        }
-        catch (IOException e) {
-        	LOG.error(String.format("Error while cloning from %s: could not copy to unit test dir", config.group(1)), e);
-        }
-        catch (GitAPIException e) {
-            LOG.error(String.format("Error while cloning from %s: could not read from Git", config.group(1)), e);
-        }
-    }
-}
diff --git a/src/main/java/de/hftstuttgart/dtabackend/utils/RepoUtil.java b/src/main/java/de/hftstuttgart/dtabackend/utils/RepoUtil.java
new file mode 100644
index 0000000..f2c8587
--- /dev/null
+++ b/src/main/java/de/hftstuttgart/dtabackend/utils/RepoUtil.java
@@ -0,0 +1,119 @@
+package de.hftstuttgart.dtabackend.utils;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.eclipse.jgit.api.CloneCommand;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
+import org.springframework.stereotype.Component;
+import org.springframework.util.FileSystemUtils;
+import org.tmatesoft.svn.core.SVNDepth;
+import org.tmatesoft.svn.core.SVNException;
+import org.tmatesoft.svn.core.SVNURL;
+import org.tmatesoft.svn.core.auth.BasicAuthenticationManager;
+import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
+import org.tmatesoft.svn.core.io.SVNRepository;
+import org.tmatesoft.svn.core.io.SVNRepositoryFactory;
+import org.tmatesoft.svn.core.wc.SVNUpdateClient;
+import org.tmatesoft.svn.core.wc.SVNWCUtil;
+import org.tmatesoft.svn.core.wc2.SvnCheckout;
+import org.tmatesoft.svn.core.wc2.SvnOperationFactory;
+import org.tmatesoft.svn.core.wc2.SvnTarget;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.regex.Matcher;
+
+@Component
+public class RepoUtil {
+
+    private static final Logger LOG = LogManager.getLogger(RepoUtil.class);
+
+    public RepoUtil() {}
+
+    public void cloneRepository(Matcher config, String targetPath, String subDir) {
+        LOG.debug(String.format("cloning repository: %s", config.group(1)));
+
+        File targetDirectory = new File(targetPath);
+        if (targetDirectory.exists()) {
+            LOG.debug("clone target directory existing yet, deleting now");
+            FileSystemUtils.deleteRecursively(targetDirectory);
+        }
+
+        File checkoutDirectory = targetDirectory;
+        //if an optional directory parameter was given
+        if(subDir!="")
+        {
+        	//create companion checkout dir "targetPath"+"_checkout"
+            checkoutDirectory = new File(targetPath+"_checkout");
+            if (checkoutDirectory.exists()) {
+            	LOG.debug("clone checkout directory existing yet, deleting now");
+            	FileSystemUtils.deleteRecursively(checkoutDirectory);
+            }
+        }
+        
+        try {
+        	LOG.debug("preparing clone");
+
+        	if (config.group(1).endsWith(".git")) {
+	            CloneCommand cloneCommand = Git.cloneRepository()
+	                .setDirectory(checkoutDirectory)
+	                .setURI(config.group(1));
+	
+	            if (!config.group(2).equals("none") && !config.group(3).equals("none")) {
+	                LOG.debug("setting credentials");
+	                cloneCommand.setCredentialsProvider(new UsernamePasswordCredentialsProvider(config.group(2), config.group(3)));
+	            }
+	
+	            LOG.debug("cloning...");
+	            cloneCommand.call().close();
+        	}
+        	else {
+        		URL sourceUrl=new URL(config.group(1));
+                SVNURL url = SVNURL.create(sourceUrl.getProtocol(), null, sourceUrl.getHost(), sourceUrl.getPort(), sourceUrl.getPath(), false);
+                SvnOperationFactory operationFactory = new SvnOperationFactory();
+                SvnCheckout checkout = operationFactory.createCheckout();
+                checkout.setSingleTarget(SvnTarget.fromFile(new File(targetPath)));
+                checkout.setSource(SvnTarget.fromURL(url));
+                
+                String protocol = url.getProtocol();
+
+                if (!config.group(2).equals("none") && !config.group(3).equals("none")) {
+                	if (protocol.equals("https")) {
+                		LOG.debug("Setting SVN credentials for HTTPS checkout with username/password");
+                		operationFactory.setAuthenticationManager(new BasicAuthenticationManager(config.group(2), config.group(3)));
+                	}
+                	else if (protocol.equals("svn+ssh")) {
+                		LOG.debug("Setting credentials for SVN+SSH Authentication with username/password");
+                		//ISVNAuthenticationManager authManager = new BasicAuthenticationManager(new SVNAuthentication[] { new SVNSSHAuthentication(username, password, -1, false)});//SVNWCUtil.createDefaultAuthenticationManager(username, password); 
+                		ISVNAuthenticationManager authManager = SVNWCUtil.createDefaultAuthenticationManager(config.group(2), config.group(3).toCharArray());
+                		operationFactory.setAuthenticationManager(authManager);
+                	}
+                }
+
+                checkout.run();
+                LOG.debug("SVN checkout completed successfully.");
+        	}
+        		
+            //if an optional directory parameter was given
+            if(subDir!="")
+            {
+            	//copy appropriate path from checkout directory to target directory
+            	FileSystemUtils.copyRecursively(new File(checkoutDirectory+subDir), new File(targetPath));
+            }
+            LOG.debug(String.format("cloned from %s to %s", config.group(1), targetDirectory));            
+        }
+        catch (IOException e) {
+        	LOG.error(String.format("Error while cloning from %s: could not copy to unit test dir", config.group(1)), e);
+        }
+        catch (GitAPIException e) {
+            LOG.error(String.format("Error while cloning from %s: could not read from Git", config.group(1)), e);
+        }
+        catch (SVNException e) {
+        	LOG.error(String.format("Error while cloning from %s: could not read from Svn", config.group(1)), e);
+        }
+    }
+}
-- 
GitLab