Skip to content
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 54 additions & 20 deletions src/main/java/jenkins/plugins/git/GitSCMFileSystem.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import hudson.EnvVars;
import hudson.Extension;
import hudson.model.Item;
import hudson.model.Run;
import hudson.model.TaskListener;
import hudson.plugins.git.BranchSpec;
import hudson.plugins.git.GitException;
Expand Down Expand Up @@ -284,8 +285,47 @@ public boolean supportsDescriptor(SCMSourceDescriptor descriptor) {
return AbstractGitSCMSource.class.isAssignableFrom(descriptor.clazz);
}

static class HeadNameResult {
final String headName;
final String prefix;

private HeadNameResult(String headName, String prefix) {
this.headName = headName;
this.prefix = prefix;
}

static HeadNameResult calculate(@NonNull BranchSpec branchSpec,
@CheckForNull SCMRevision rev,
@CheckForNull EnvVars env) {
String branchSpecExpandedName = branchSpec.getName();
if (env != null) {
branchSpecExpandedName = env.expand(branchSpecExpandedName);
}

String prefix = Constants.R_HEADS;
if (branchSpecExpandedName.startsWith(Constants.R_TAGS)) {
prefix = Constants.R_TAGS;
}

String headName;
if (rev != null) {
headName = env.expand(rev.getHead().getName());
} else {
if (branchSpecExpandedName.startsWith(prefix)) {
headName = branchSpecExpandedName.substring(prefix.length());
} else if (branchSpecExpandedName.startsWith("*/")) {
headName = branchSpecExpandedName.substring(2);
} else {
headName = branchSpecExpandedName;
}
}
return new HeadNameResult(headName, prefix);
}
}

@Override
public SCMFileSystem build(@NonNull Item owner, @NonNull SCM scm, @CheckForNull SCMRevision rev)
public SCMFileSystem build(@NonNull Item owner, @NonNull SCM scm, @CheckForNull SCMRevision rev,
@CheckForNull Run<?,?> _build)
throws IOException, InterruptedException {
if (rev != null && !(rev instanceof AbstractGitSCMSource.SCMRevisionImpl)) {
return null;
Expand All @@ -302,6 +342,12 @@ public SCMFileSystem build(@NonNull Item owner, @NonNull SCM scm, @CheckForNull
listener.getLogger().println("Git remote url is null");
return null;
}

EnvVars env = null;
if (_build != null) {
env = _build.getEnvironment(listener);
}

String cacheEntry = AbstractGitSCMSource.getCacheEntry(remote);
Lock cacheLock = AbstractGitSCMSource.getCacheLock(cacheEntry);
cacheLock.lock();
Expand Down Expand Up @@ -346,27 +392,15 @@ public SCMFileSystem build(@NonNull Item owner, @NonNull SCM scm, @CheckForNull
} catch (URISyntaxException ex) {
listener.getLogger().println("URI syntax exception for '" + remoteName + "' " + ex);
}
String prefix = Constants.R_HEADS;
if(branchSpec.getName().startsWith(Constants.R_TAGS)){
prefix = Constants.R_TAGS;
}
String headName;
if (rev != null) {
headName = rev.getHead().getName();
} else {
if (branchSpec.getName().startsWith(prefix)){
headName = branchSpec.getName().substring(prefix.length());
} else if (branchSpec.getName().startsWith("*/")) {
headName = branchSpec.getName().substring(2);
} else {
headName = branchSpec.getName();
}
}

HeadNameResult headNameResult = HeadNameResult.calculate(branchSpec, rev, env);

client.fetch_().prune(true).from(remoteURI, Collections.singletonList(new RefSpec(
"+" + prefix + headName + ":" + Constants.R_REMOTES + remoteName + "/"
+ headName))).execute();
"+" + headNameResult.prefix + headNameResult.headName + ":" + Constants.R_REMOTES + remoteName + "/"
+ headNameResult.headName))).execute();

listener.getLogger().println("Done.");
return new GitSCMFileSystem(client, remote, Constants.R_REMOTES + remoteName + "/" +headName, (AbstractGitSCMSource.SCMRevisionImpl) rev);
return new GitSCMFileSystem(client, remote, Constants.R_REMOTES + remoteName + "/" + headNameResult.headName, (AbstractGitSCMSource.SCMRevisionImpl) rev);
} finally {
cacheLock.unlock();
}
Expand Down
36 changes: 36 additions & 0 deletions src/test/java/jenkins/plugins/git/GitSCMFileSystemTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
import jenkins.scm.api.SCMRevision;
import jenkins.scm.api.SCMSource;
import jenkins.scm.api.SCMSourceDescriptor;

import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.jenkinsci.plugins.gitclient.Git;
import org.jenkinsci.plugins.gitclient.GitClient;
Expand Down Expand Up @@ -426,6 +428,40 @@ public void filesystem_supports_descriptor() throws Exception {
assertTrue(SCMFileSystem.supports(descriptor));
}

@Issue("JENKINS-42971")
@Test
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May also want to assert behavior with a null env, undefined variable, etc.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is one for null env, but this is internal method, and there are many checks already in the calling method

public void calculate_head_name_with_env() throws Exception {
GitSCMFileSystem.BuilderImpl.HeadNameResult result1 = GitSCMFileSystem.BuilderImpl.HeadNameResult.calculate(new BranchSpec("${BRANCH}"), null,
new EnvVars("BRANCH", "master-a"));
assertEquals("master-a", result1.headName);
assertEquals(Constants.R_HEADS, result1.prefix);

GitSCMFileSystem.BuilderImpl.HeadNameResult result2 = GitSCMFileSystem.BuilderImpl.HeadNameResult.calculate(new BranchSpec("${BRANCH}"), null,
new EnvVars("BRANCH", "refs/heads/master-b"));
assertEquals("master-b", result2.headName);
assertEquals(Constants.R_HEADS, result2.prefix);

GitSCMFileSystem.BuilderImpl.HeadNameResult result3 = GitSCMFileSystem.BuilderImpl.HeadNameResult.calculate(new BranchSpec("refs/heads/${BRANCH}"), null,
new EnvVars("BRANCH", "master-c"));
assertEquals("master-c", result3.headName);
assertEquals(Constants.R_HEADS, result3.prefix);

GitSCMFileSystem.BuilderImpl.HeadNameResult result4 = GitSCMFileSystem.BuilderImpl.HeadNameResult.calculate(new BranchSpec("${BRANCH}"), null,
null);
assertEquals("${BRANCH}", result4.headName);
assertEquals(Constants.R_HEADS, result4.prefix);

GitSCMFileSystem.BuilderImpl.HeadNameResult result5 = GitSCMFileSystem.BuilderImpl.HeadNameResult.calculate(new BranchSpec("*/${BRANCH}"), null,
new EnvVars("BRANCH", "master-d"));
assertEquals("master-d", result5.headName);
assertEquals(Constants.R_HEADS, result5.prefix);

GitSCMFileSystem.BuilderImpl.HeadNameResult result6 = GitSCMFileSystem.BuilderImpl.HeadNameResult.calculate(new BranchSpec("*/master-e"), null,
new EnvVars("BRANCH", "dummy"));
assertEquals("master-e", result6.headName);
assertEquals(Constants.R_HEADS, result6.prefix);
}

/** inline ${@link hudson.Functions#isWindows()} to prevent a transient remote classloader issue */
private boolean isWindows() {
return java.io.File.pathSeparatorChar==';';
Expand Down