Skip to content
Permalink
Browse files

Merge pull request #3 from jglick/SCMStep-JENKINS-35247-reflection

[JENKINS-35247] Delegate to Git and Subversion plugins via reflection
  • Loading branch information
jglick committed Jun 9, 2016
2 parents edc5c62 + ff3e0b9 commit 58237d3ca4f72fa102234910018286d9898cfcc4
15 pom.xml
@@ -46,11 +46,22 @@
<artifactId>workflow-step-api</artifactId>
<version>1.15</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>git-client</artifactId>
<version>1.19.0</version>
<exclusions>
<exclusion>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>git</artifactId>
<version>2.4.1</version>
<optional>true</optional>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.apache.httpcomponents</groupId>
@@ -62,7 +73,7 @@
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>subversion</artifactId>
<version>2.5</version>
<optional>true</optional>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
@@ -33,25 +33,18 @@
import hudson.Util;
import hudson.model.Item;
import hudson.model.TaskListener;
import hudson.plugins.git.BranchSpec;
import hudson.plugins.git.GitException;
import hudson.plugins.git.GitSCM;
import hudson.plugins.git.GitTool;
import hudson.plugins.git.Messages;
import hudson.plugins.git.SubmoduleConfig;
import hudson.plugins.git.UserRemoteConfig;
import hudson.plugins.git.extensions.GitSCMExtension;
import hudson.plugins.git.extensions.impl.LocalBranch;
import hudson.scm.SCM;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import hudson.security.ACL;
import hudson.util.FormValidation;
import hudson.util.ListBoxModel;
import java.util.Collection;
import org.jenkinsci.plugins.gitclient.Git;
import org.jenkinsci.plugins.gitclient.GitClient;
import org.jenkinsci.plugins.gitclient.GitURIRequirementsBuilder;
@@ -61,9 +54,10 @@
import org.kohsuke.stapler.QueryParameter;

import javax.annotation.Nonnull;
import jenkins.model.Jenkins;

/**
* Runs Git using {@link GitSCM}.
* Runs Git using {@code GitSCM}.
*/
public final class GitStep extends SCMStep {

@@ -95,18 +89,33 @@ public String getCredentialsId() {
this.credentialsId = Util.fixEmpty(credentialsId);
}

@SuppressWarnings("rawtypes")
@Override public SCM createSCM() {
return new GitSCM(createRepoList(url, credentialsId), Collections.singletonList(new BranchSpec("*/" + branch)), false, Collections.<SubmoduleConfig>emptyList(), null, null, Collections.<GitSCMExtension>singletonList(new LocalBranch(branch)));
}

// copied from GitSCM
static private List<UserRemoteConfig> createRepoList(String url, String credentialsId) {
List<UserRemoteConfig> repoList = new ArrayList<UserRemoteConfig>();
repoList.add(new UserRemoteConfig(url, null, null, credentialsId));
return repoList;
try {
ClassLoader cl = Jenkins.getActiveInstance().getPluginManager().uberClassLoader;
return (SCM) cl.loadClass("hudson.plugins.git.GitSCM").getConstructor(
List.class, // userRemoteConfigs
List.class, // branches
Boolean.class, // doGenerateSubmoduleConfigurations
Collection.class, // submoduleCfg
cl.loadClass("hudson.plugins.git.browser.GitRepositoryBrowser"), // browser
String.class, // gitTool
List.class // extensions
).newInstance(
Collections.singletonList(cl.loadClass("hudson.plugins.git.UserRemoteConfig").getConstructor(String.class, String.class, String.class, String.class).newInstance(url, null, null, credentialsId)),
Collections.singletonList(cl.loadClass("hudson.plugins.git.BranchSpec").getConstructor(String.class).newInstance("*/" + branch)),
false,
Collections.EMPTY_LIST,
null,
null,
Collections.singletonList(cl.loadClass("hudson.plugins.git.extensions.impl.LocalBranch").getConstructor(String.class).newInstance(branch)));
} catch (RuntimeException x) {
throw x;
} catch (Exception x) {
throw new IllegalStateException(x);
}
}


private static StandardCredentials lookupCredentials(Item project, @Nonnull String credentialId, String uri) {
return CredentialsMatchers.firstOrNull(
CredentialsProvider.lookupCredentials(StandardCredentials.class, project, ACL.SYSTEM,
@@ -116,9 +125,17 @@ private static StandardCredentials lookupCredentials(Item project, @Nonnull Stri

@Extension(optional=true) public static final class DescriptorImpl extends SCMStepDescriptor {

public DescriptorImpl() {
// Fail now if dependency plugin not loaded. Descriptor.<init> will actually fail anyway, but this is just to be sure.
GitSCM.class.hashCode();
public DescriptorImpl() throws Exception {
ClassLoader cl = Jenkins.getActiveInstance().getPluginManager().uberClassLoader;
// Dependency plugin must be loaded…
cl.loadClass("hudson.plugins.git.GitSCM");
// …but not our own replacement.
try {
cl.loadClass("jenkins.plugins.git.GitStep");
throw new IllegalStateException("skip the old copy of GitStep");
} catch (ClassNotFoundException x) {
// good
}
}

// copy/paste from GitSCM.DescriptorImpl
@@ -166,7 +183,7 @@ public FormValidation doCheckUrl(@AncestorInPath Item project,
try {
git.getHeadRev(url, "HEAD");
} catch (GitException e) {
return FormValidation.error(Messages.UserRemoteConfig_FailedToConnect(e.getMessage()));
return FormValidation.error("Failed to connect to repository : " + e.getMessage());
}

return FormValidation.ok();
@@ -26,11 +26,11 @@

import hudson.Extension;
import hudson.scm.SCM;
import hudson.scm.SubversionSCM;
import jenkins.model.Jenkins;
import org.kohsuke.stapler.DataBoundConstructor;

/**
* Runs Subversion using {@link SubversionSCM}.
* Runs Subversion using {@code SubversionSCM}.
*/
public final class SubversionStep extends SCMStep {

@@ -45,14 +45,29 @@ public String getUrl() {
}

@Override protected SCM createSCM() {
return new SubversionSCM(url); // TODO maybe default to UpdateWithCleanUpdater, etc.
try {
ClassLoader cl = Jenkins.getActiveInstance().getPluginManager().uberClassLoader;
return (SCM) cl.loadClass("hudson.scm.SubversionSCM").getConstructor(String.class).newInstance(url);
} catch (RuntimeException x) {
throw x;
} catch (Exception x) {
throw new IllegalStateException(x);
}
}

@Extension(optional=true) public static final class DescriptorImpl extends SCMStepDescriptor {

public DescriptorImpl() {
// Fail now if dependency plugin not loaded. Descriptor.<init> will actually fail anyway, but this is just to be sure.
SubversionSCM.class.hashCode();
public DescriptorImpl() throws Exception {
ClassLoader cl = Jenkins.getActiveInstance().getPluginManager().uberClassLoader;
// Dependency plugin must be loaded…
cl.loadClass("hudson.scm.SubversionSCM");
// …but not our own replacement.
try {
cl.loadClass("jenkins.scm.impl.subversion.SubversionStep");
throw new IllegalStateException("skip the old copy of SubversionStep");
} catch (ClassNotFoundException x) {
// good
}
}

@Override public String getFunctionName() {

0 comments on commit 58237d3

Please sign in to comment.
You can’t perform that action at this time.