RepoUtil.java 5.28 KiB
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.*;
import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
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.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) {
        if (!config.matches()) {
            LOG.error("Invalid repository URL format.");
            return;
        String repoUrl = config.group(1);
        String username = config.group(2);
        String password = config.group(3);  // Not used for SSH authentication
        LOG.debug("Cloning repository: {}", repoUrl);
        File targetDirectory = new File(targetPath);
        if (targetDirectory.exists()) {
            LOG.debug("Target directory exists, deleting it.");
            FileSystemUtils.deleteRecursively(targetDirectory);
        File checkoutDirectory = targetDirectory;
        if (!subDir.isEmpty()) {
            checkoutDirectory = new File(targetPath + "_checkout");
            if (checkoutDirectory.exists()) {
                LOG.debug("Checkout directory exists, deleting it.");
                FileSystemUtils.deleteRecursively(checkoutDirectory);
        try {
            LOG.debug("Preparing clone...");
            if (repoUrl.endsWith(".git")) {
                // GIT Repository Clone
                CloneCommand cloneCommand = Git.cloneRepository()
                        .setDirectory(checkoutDirectory)
                        .setURI(repoUrl);
                if (!"none".equals(username) && !"none".equals(password)) {
                    LOG.debug("Setting Git credentials.");
                    cloneCommand.setCredentialsProvider(new UsernamePasswordCredentialsProvider(username, password));
                LOG.debug("Cloning Git repository...");
cloneCommand.call().close(); } else { // SVN Repository Clone (including svn+ssh support) SvnOperationFactory operationFactory = new SvnOperationFactory(); try { SVNURL svnUrl = SVNURL.parseURIEncoded(repoUrl); SvnCheckout checkout = operationFactory.createCheckout(); checkout.setSingleTarget(SvnTarget.fromFile(checkoutDirectory)); checkout.setSource(SvnTarget.fromURL(svnUrl)); checkout.setDepth(SVNDepth.INFINITY); // **Use SSH authentication if URL starts with svn+ssh://** if (repoUrl.startsWith("svn+ssh://")) { LOG.debug("Setting up SSH authentication for SVN..."); String sshPrivateKeyPath = "/home/appuser/.ssh/id_rsa"; File privateKeyFile = new File(sshPrivateKeyPath); if (!privateKeyFile.exists()) { LOG.error("SSH private key not found at: {}", sshPrivateKeyPath); throw new SVNException(SVNErrorMessage.create(SVNErrorCode.AUTHN_CREDS_UNAVAILABLE, "SSH key not found")); } ISVNAuthenticationManager authManager = SVNWCUtil.createDefaultAuthenticationManager( new File("/home/appuser/.ssh/id_rsa"), // Explicit SSH Key username, null, new File("/home/appuser/.ssh/known_hosts"), // Explicit Known Hosts false ); operationFactory.setAuthenticationManager(authManager); } LOG.debug("Performing SVN checkout..."); checkout.run(); } finally { operationFactory.dispose(); } } // Handle subdirectory case if (!subDir.isEmpty()) { File sourceSubDir = new File(checkoutDirectory, subDir); if (sourceSubDir.exists()) { FileSystemUtils.copyRecursively(sourceSubDir, targetDirectory); } else { LOG.error("Specified subdirectory does not exist."); } } LOG.debug("Repository successfully cloned from {} to {}", repoUrl, targetDirectory); } catch (IOException | GitAPIException | SVNException e) { LOG.error("Error while cloning repository: " + repoUrl, e); } } }