-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[JENKINS-71506] Support custom refspec in lightweight checkout #1468
base: master
Are you sure you want to change the base?
Changes from 10 commits
2a91c95
d20c716
1fde396
efed3af
c64fd02
e3269b0
080cfb8
fd64d80
e6e957f
6d0daaf
fb0afc9
d21149d
343d3f1
244ba1f
1b881a6
ac489cf
e66e798
c40b747
8878bbb
6673ed0
78797e8
4c04395
7080cd6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -60,6 +60,9 @@ | |||||||||||||
import java.util.concurrent.locks.Lock; | ||||||||||||||
import java.util.logging.Level; | ||||||||||||||
import java.util.logging.Logger; | ||||||||||||||
import java.util.regex.Matcher; | ||||||||||||||
import java.util.regex.Pattern; | ||||||||||||||
|
||||||||||||||
import jenkins.scm.api.SCMFile; | ||||||||||||||
import jenkins.scm.api.SCMFileSystem; | ||||||||||||||
import jenkins.scm.api.SCMHead; | ||||||||||||||
|
@@ -287,39 +290,76 @@ public boolean supportsDescriptor(SCMSourceDescriptor descriptor) { | |||||||||||||
|
||||||||||||||
static class HeadNameResult { | ||||||||||||||
final String headName; | ||||||||||||||
final String prefix; | ||||||||||||||
final String remoteHeadName; | ||||||||||||||
final String refspec; | ||||||||||||||
final SCMRevision rev; | ||||||||||||||
|
||||||||||||||
private HeadNameResult(String headName, String prefix) { | ||||||||||||||
private HeadNameResult(String headName, String remoteHeadName, String refspec, SCMRevision rev) { | ||||||||||||||
this.headName = headName; | ||||||||||||||
this.prefix = prefix; | ||||||||||||||
this.remoteHeadName = remoteHeadName; | ||||||||||||||
this.refspec = refspec; | ||||||||||||||
this.rev = rev; | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
static HeadNameResult calculate(@NonNull BranchSpec branchSpec, | ||||||||||||||
@CheckForNull SCMRevision rev, | ||||||||||||||
@CheckForNull EnvVars env) { | ||||||||||||||
@NonNull String refSpec, | ||||||||||||||
@CheckForNull EnvVars env, | ||||||||||||||
@CheckForNull String remoteName) { | ||||||||||||||
|
||||||||||||||
String branchSpecExpandedName = branchSpec.getName(); | ||||||||||||||
if (env != null) { | ||||||||||||||
branchSpecExpandedName = env.expand(branchSpecExpandedName); | ||||||||||||||
} | ||||||||||||||
String refspecExpandedName = refSpec; | ||||||||||||||
if (env != null) { | ||||||||||||||
refspecExpandedName = env.expand(refspecExpandedName); | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
// default to a branch (refs/heads) | ||||||||||||||
String prefix = Constants.R_HEADS; | ||||||||||||||
// check for a tag | ||||||||||||||
if (branchSpecExpandedName.startsWith(Constants.R_TAGS)) { | ||||||||||||||
prefix = Constants.R_TAGS; | ||||||||||||||
} else { | ||||||||||||||
// check for FETCH_HEAD | ||||||||||||||
if (branchSpecExpandedName.equals(Constants.FETCH_HEAD) && !refspecExpandedName.equals("")) { | ||||||||||||||
prefix = null; | ||||||||||||||
} else { | ||||||||||||||
// check for commit-id | ||||||||||||||
final String regex = "^[a-fA-F0-9]{40}$"; | ||||||||||||||
final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE); | ||||||||||||||
final Matcher matcher = pattern.matcher(branchSpecExpandedName); | ||||||||||||||
|
||||||||||||||
if (matcher.find()) { | ||||||||||||||
Comment on lines
+329
to
+333
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is an existing pattern for this here
Suggested change
|
||||||||||||||
// commit-id | ||||||||||||||
prefix = null; | ||||||||||||||
rev = new AbstractGitSCMSource.SCMRevisionImpl(new SCMHead(branchSpecExpandedName), branchSpecExpandedName); | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Overriding arguments like that deserves at least a comment. |
||||||||||||||
} | ||||||||||||||
} | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
String headName; | ||||||||||||||
String headName = branchSpecExpandedName; | ||||||||||||||
if (rev != null && env != null) { | ||||||||||||||
headName = env.expand(rev.getHead().getName()); | ||||||||||||||
} else { | ||||||||||||||
if (branchSpecExpandedName.startsWith(prefix)) { | ||||||||||||||
if (prefix != null && branchSpecExpandedName.startsWith(prefix)) { | ||||||||||||||
headName = branchSpecExpandedName.substring(prefix.length()); | ||||||||||||||
} else if (branchSpecExpandedName.startsWith("*/")) { | ||||||||||||||
headName = branchSpecExpandedName.substring(2); | ||||||||||||||
} else { | ||||||||||||||
headName = branchSpecExpandedName; | ||||||||||||||
} | ||||||||||||||
} | ||||||||||||||
return new HeadNameResult(headName, prefix); | ||||||||||||||
|
||||||||||||||
if (refspecExpandedName == null || refspecExpandedName.equals("")) { | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||
refspecExpandedName = "+" + prefix + headName + ":" + Constants.R_REMOTES + remoteName + "/" + headName; | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This line seems to generate an incorrect refspec expanded name when the In that same test case, the remoteHead value is I think that it would be desirable to handle tags, since the change is already adding the ability to handle other refspecs. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for pointing out, fixed now |
||||||||||||||
} | ||||||||||||||
|
||||||||||||||
String remoteHead = headName; | ||||||||||||||
if (prefix != null && (prefix.equals(Constants.R_HEADS) || prefix.equals(Constants.R_TAGS))) { | ||||||||||||||
remoteHead = Constants.R_REMOTES + remoteName + "/" + headName; | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
return new HeadNameResult(headName, remoteHead, refspecExpandedName, rev); | ||||||||||||||
} | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
|
@@ -399,14 +439,11 @@ public SCMFileSystem build(@NonNull Item owner, @NonNull SCM scm, @CheckForNull | |||||||||||||
listener.getLogger().println("URI syntax exception for '" + remoteName + "' " + ex); | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
HeadNameResult headNameResult = HeadNameResult.calculate(branchSpec, rev, env); | ||||||||||||||
|
||||||||||||||
client.fetch_().prune(true).from(remoteURI, Collections.singletonList(new RefSpec( | ||||||||||||||
"+" + headNameResult.prefix + headNameResult.headName + ":" + Constants.R_REMOTES + remoteName + "/" | ||||||||||||||
+ headNameResult.headName))).execute(); | ||||||||||||||
HeadNameResult headNameResult = HeadNameResult.calculate(branchSpec, rev, config.getRefspec(), env, remoteName); | ||||||||||||||
client.fetch_().prune(true).from(remoteURI, Collections.singletonList(new RefSpec(headNameResult.refspec))).execute(); | ||||||||||||||
|
||||||||||||||
listener.getLogger().println("Done."); | ||||||||||||||
return new GitSCMFileSystem(client, remote, Constants.R_REMOTES + remoteName + "/" + headNameResult.headName, (AbstractGitSCMSource.SCMRevisionImpl) rev); | ||||||||||||||
return new GitSCMFileSystem(client, remote, headNameResult.remoteHeadName, (AbstractGitSCMSource.SCMRevisionImpl) headNameResult.rev); | ||||||||||||||
} finally { | ||||||||||||||
cacheLock.unlock(); | ||||||||||||||
} | ||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Either the annotation is incorrect here or the tests are incorrect. The tests are passing a null
refSpec
but the annotation declares thatrefSpec
is NonNull.I'm surprised that spotbugs did not detect that issue. I'll need to investigate further to understand if there is a suppression
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
refSpec should have the @checkfornull annotation, fixed now