package org.paylogic.jenkins.advancedscm;
import hudson.Launcher;
import hudson.model.AbstractBuild;
import hudson.model.BuildListener;
import hudson.plugins.git.GitSCM;
import hudson.plugins.git.extensions.GitSCMExtension;
import hudson.plugins.git.extensions.impl.RelativeTargetDirectory;
import hudson.plugins.mercurial.MercurialSCM;
import hudson.scm.SCM;
import lombok.extern.java.Log;
import org.jenkinsci.plugins.multiplescms.MultiSCM;
import org.paylogic.jenkins.advancedscm.backends.GitBackend;
import org.paylogic.jenkins.advancedscm.backends.MercurialBackend;
import java.io.PrintStream;
import java.util.List;
/**
* Factory for AdvancedSCMManager derived objects.
* Automagically chooses which backend implementation you need,
* and even assigns the correct multiscm repo to that implementation if you use multiscm.
*/
@Log
public class SCMManagerFactory {
public static AdvancedSCMManager getManager(AbstractBuild build, Launcher launcher, BuildListener listener) throws Exception {
String givenRepoSubdir = null;
PrintStream l = listener.getLogger();
givenRepoSubdir = build.getEnvironment(listener).get("REPO_SUBDIR", "");
SCM scm = build.getProject().getScm();
// Sort out multiscm scms.
if (scm instanceof MultiSCM) {
List<SCM> scms = ((MultiSCM) scm).getConfiguredSCMs();
if (scms.size() > 1) {
// loop and find correct repo to apply credentials on
for (SCM s: ((MultiSCM) scm).getConfiguredSCMs()) {
// Only if typeof scm is mercurial
if (s instanceof MercurialSCM) {
String subDir = ((MercurialSCM) s).getSubdir();
if (subDir != null) {
if (subDir.equals(givenRepoSubdir)) {
l.append("Chosen MultiSCM with Mercurial Backend");
return new MercurialBackend(build, launcher, listener, (MercurialSCM) s);
}
}
} else if (s instanceof GitSCM) {
GitSCM gitSCM = (GitSCM) s;
for (GitSCMExtension extension: gitSCM.getExtensions()){
if (extension instanceof RelativeTargetDirectory) {
String targetDir = ((RelativeTargetDirectory) extension).getRelativeTargetDir();
if (targetDir != null && !targetDir .isEmpty() && targetDir == givenRepoSubdir) {
l.append("Chosen MultiSCM with Git Backend");
return new GitBackend(build, launcher, listener, (GitSCM) s);
}
}
}
}
}
} else {
scm = scms.get(0);
}
}
// No multiscm, just return correct backend.
if (scm instanceof MercurialSCM) {
l.append("Chosen Mercurial backend, NO MultiSCM");
return new MercurialBackend(build, launcher, listener, (MercurialSCM) scm);
} else if (scm instanceof GitSCM) {
l.append("Chosen Git backend, NO MultiSCM");
return new GitBackend(build, launcher, listener, (GitSCM) scm);
}
// If we come here, no viable SCM was found, so we quit.
throw new Exception("There is no implementation available for the chosen SCM. Sorry about that.");
}
}