Skip to content
Permalink
Browse files

[JENKINS-43507] Give GitSCMSource a BranchDiscoveryTrait in preparati…

…on for JENKINS-33445
  • Loading branch information...
stephenc committed Jun 23, 2017
1 parent 15f218a commit 1c1c664d1a18c600443a3ffe66f2a30ec2bd47ef
@@ -61,6 +61,8 @@
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -81,6 +83,7 @@
import jenkins.plugins.git.traits.RemoteNameSCMSourceTrait;
import jenkins.scm.api.SCMFile;
import jenkins.scm.api.SCMHead;
import jenkins.scm.api.SCMHeadCategory;
import jenkins.scm.api.SCMHeadEvent;
import jenkins.scm.api.SCMHeadObserver;
import jenkins.scm.api.SCMProbe;
@@ -408,108 +411,119 @@ protected void retrieve(@CheckForNull SCMSourceCriteria criteria,
@Override
public Void run(GitClient client, String remoteName) throws IOException, InterruptedException {
final Repository repository = client.getRepository();
listener.getLogger().println("Getting remote branches...");
try (RevWalk walk = new RevWalk(repository);
GitSCMSourceRequest request = context.newRequest(AbstractGitSCMSource.this, listener)) {
walk.setRetainBody(false);
int count = 0;
for (final Branch b : client.getRemoteBranches()) {
if (!b.getName().startsWith(remoteName + "/")) {
continue;
}
count++;
final String branchName = StringUtils.removeStart(b.getName(), remoteName + "/");
if (request.process(new SCMHead(branchName),
new SCMSourceRequest.IntermediateLambda<ObjectId>() {
@Nullable
@Override
public ObjectId create() throws IOException, InterruptedException {
listener.getLogger().println(" Checking branch " + branchName);
return b.getSHA1();
}
},
new SCMSourceRequest.ProbeLambda<SCMHead, ObjectId>() {
@NonNull
@Override
public SCMSourceCriteria.Probe create(@NonNull SCMHead head,
@Nullable ObjectId revisionInfo)
throws IOException, InterruptedException {
RevCommit commit = walk.parseCommit(revisionInfo);
final long lastModified = TimeUnit.SECONDS.toMillis(commit.getCommitTime());
final RevTree tree = commit.getTree();
return new SCMProbe() {
@Override
public void close() throws IOException {
// no-op
}
if (context.wantBranches()) {
discoverBranches(client, remoteName, repository, walk, request);
}
if (context.wantTags()) {
// TODO
}
}
return null;
}

@Override
public String name() {
return branchName;
}
private void discoverBranches(GitClient client, String remoteName, final Repository repository,
final RevWalk walk, GitSCMSourceRequest request)
throws IOException, InterruptedException {
listener.getLogger().println("Getting remote branches...");
walk.setRetainBody(false);
int count = 0;
for (final Branch b : client.getRemoteBranches()) {
if (!b.getName().startsWith(remoteName + "/")) {
continue;
}
count++;
final String branchName = StringUtils.removeStart(b.getName(), remoteName + "/");
if (request.process(new SCMHead(branchName),
new SCMSourceRequest.IntermediateLambda<ObjectId>() {
@Nullable
@Override
public ObjectId create() throws IOException, InterruptedException {
listener.getLogger().println(" Checking branch " + branchName);
return b.getSHA1();
}
},
new SCMSourceRequest.ProbeLambda<SCMHead, ObjectId>() {
@NonNull
@Override
public SCMSourceCriteria.Probe create(@NonNull SCMHead head,
@Nullable ObjectId revisionInfo)
throws IOException, InterruptedException {
RevCommit commit = walk.parseCommit(revisionInfo);
final long lastModified = TimeUnit.SECONDS.toMillis(commit.getCommitTime());
final RevTree tree = commit.getTree();
return new SCMProbe() {
@Override
public void close() throws IOException {
// no-op
}

@Override
public long lastModified() {
return lastModified;
}
@Override
public String name() {
return branchName;
}

@Override
public long lastModified() {
return lastModified;
}

@Override
@NonNull
@SuppressFBWarnings(value = "NP_LOAD_OF_KNOWN_NULL_VALUE",
justification =
"TreeWalk.forPath can return null, compiler "
+ "generated code for try with resources handles it")
public SCMProbeStat stat(@NonNull String path) throws IOException {
try (TreeWalk tw = TreeWalk.forPath(repository, path, tree)) {
if (tw == null) {
return SCMProbeStat.fromType(SCMFile.Type.NONEXISTENT);
}
FileMode fileMode = tw.getFileMode(0);
if (fileMode == FileMode.MISSING) {
return SCMProbeStat.fromType(SCMFile.Type.NONEXISTENT);
}
if (fileMode == FileMode.EXECUTABLE_FILE) {
return SCMProbeStat.fromType(SCMFile.Type.REGULAR_FILE);
}
if (fileMode == FileMode.REGULAR_FILE) {
return SCMProbeStat.fromType(SCMFile.Type.REGULAR_FILE);
}
if (fileMode == FileMode.SYMLINK) {
return SCMProbeStat.fromType(SCMFile.Type.LINK);
}
if (fileMode == FileMode.TREE) {
return SCMProbeStat.fromType(SCMFile.Type.DIRECTORY);
}
return SCMProbeStat.fromType(SCMFile.Type.OTHER);
@Override
@NonNull
@SuppressFBWarnings(value = "NP_LOAD_OF_KNOWN_NULL_VALUE",
justification =
"TreeWalk.forPath can return null, compiler "
+ "generated code for try with resources handles it")
public SCMProbeStat stat(@NonNull String path) throws IOException {
try (TreeWalk tw = TreeWalk.forPath(repository, path, tree)) {
if (tw == null) {
return SCMProbeStat.fromType(SCMFile.Type.NONEXISTENT);
}
FileMode fileMode = tw.getFileMode(0);
if (fileMode == FileMode.MISSING) {
return SCMProbeStat.fromType(SCMFile.Type.NONEXISTENT);
}
if (fileMode == FileMode.EXECUTABLE_FILE) {
return SCMProbeStat.fromType(SCMFile.Type.REGULAR_FILE);
}
if (fileMode == FileMode.REGULAR_FILE) {
return SCMProbeStat.fromType(SCMFile.Type.REGULAR_FILE);
}
if (fileMode == FileMode.SYMLINK) {
return SCMProbeStat.fromType(SCMFile.Type.LINK);
}
if (fileMode == FileMode.TREE) {
return SCMProbeStat.fromType(SCMFile.Type.DIRECTORY);
}
return SCMProbeStat.fromType(SCMFile.Type.OTHER);
}
};
}
}, new SCMSourceRequest.LazyRevisionLambda<SCMHead, SCMRevision, ObjectId>() {
@NonNull
@Override
public SCMRevision create(@NonNull SCMHead head, @Nullable ObjectId intermediate)
throws IOException, InterruptedException {
return new SCMRevisionImpl(head, b.getSHA1String());
}
}, new SCMSourceRequest.Witness() {
@Override
public void record(@NonNull SCMHead head, SCMRevision revision, boolean isMatch) {
if (isMatch) {
listener.getLogger().println(" Met criteria");
} else {
listener.getLogger().println(" Does not meet criteria");
}
};
}
}, new SCMSourceRequest.LazyRevisionLambda<SCMHead, SCMRevision, ObjectId>() {
@NonNull
@Override
public SCMRevision create(@NonNull SCMHead head, @Nullable ObjectId intermediate)
throws IOException, InterruptedException {
return new SCMRevisionImpl(head, b.getSHA1String());
}
}, new SCMSourceRequest.Witness() {
@Override
public void record(@NonNull SCMHead head, SCMRevision revision, boolean isMatch) {
if (isMatch) {
listener.getLogger().println(" Met criteria");
} else {
listener.getLogger().println(" Does not meet criteria");
}
}
)) {
listener.getLogger().format("Processed %d branches (query complete)%n", count);
return null;
}
}
)) {
listener.getLogger().format("Processed %d branches (query complete)%n", count);
return;
}
listener.getLogger().format("Processed %d branches%n", count);
return null;
}
listener.getLogger().format("Processed %d branches%n", count);
}
}, context, listener, true);
}
@@ -62,6 +62,7 @@
import java.util.logging.Logger;
import java.util.regex.Pattern;
import jenkins.model.Jenkins;
import jenkins.plugins.git.traits.BranchDiscoveryTrait;
import jenkins.plugins.git.traits.GitBrowserSCMSourceTrait;
import jenkins.plugins.git.traits.GitSCMExtensionTrait;
import jenkins.plugins.git.traits.GitSCMExtensionTraitDescriptor;
@@ -154,12 +155,6 @@ public GitSCMSource(String remote) {
this.remote = remote;
}

@Deprecated
public GitSCMSource(String id, String remote) {
this(remote);
setId(id);
}

@DataBoundSetter
public void setCredentialsId(@CheckForNull String credentialsId) {
this.credentialsId = credentialsId;
@@ -178,6 +173,7 @@ public GitSCMSource(String id, String remote, String credentialsId, String remot
this.remote = remote;
this.credentialsId = credentialsId;
this.traits = new ArrayList<>();
this.traits.add(new BranchDiscoveryTrait());
if (!DEFAULT_INCLUDES.equals(includes) || !DEFAULT_EXCLUDES.equals(excludes)) {
traits.add(new WildcardSCMHeadFilterTrait(includes, excludes));
}
@@ -203,6 +199,7 @@ public GitSCMSource(String id, String remote, String credentialsId, String inclu
private Object readResolve() throws ObjectStreamException {
if (traits == null) {
traits = new ArrayList<>();
traits.add(new BranchDiscoveryTrait());
if ((includes != null && !DEFAULT_INCLUDES.equals(includes))
|| (excludes != null && !DEFAULT_EXCLUDES.equals(excludes))) {
traits.add(new WildcardSCMHeadFilterTrait(includes, excludes));
@@ -240,6 +237,9 @@ private Object readResolve() throws ObjectStreamException {
if (browser != null) {
traits.add(new GitBrowserSCMSourceTrait(browser));
}
if (ignoreOnPushNotifications) {
traits.add(new IgnoreOnPushNotificationTrait());
}
RefSpecsSCMSourceTrait trait = asRefSpecsSCMSourceTrait(rawRefSpecs, remoteName);
if (trait != null) {
traits.add(trait);
@@ -528,7 +528,7 @@ public ListBoxModel doFillGitToolItems() {
}

public List<SCMSourceTrait> getTraitsDefaults() {
return Collections.emptyList();
return Collections.<SCMSourceTrait>singletonList(new BranchDiscoveryTrait());
}
}

@@ -51,7 +51,14 @@
*/
public class GitSCMSourceContext<C extends GitSCMSourceContext<C, R>, R extends GitSCMSourceRequest>
extends SCMSourceContext<C, R> {

/**
* {@code true} if the {@link GitSCMSourceRequest} will need information about branches.
*/
private boolean wantBranches;
/**
* {@code true} if the {@link GitSCMSourceRequest} will need information about tags.
*/
private boolean wantTags;
/**
* The name of the {@link GitTool} to use or {@code null} to use the default.
*/
@@ -82,6 +89,24 @@ public GitSCMSourceContext(@CheckForNull SCMSourceCriteria criteria, @NonNull SC
super(criteria, observer);
}

/**
* Returns {@code true} if the {@link GitSCMSourceRequest} will need information about branches.
*
* @return {@code true} if the {@link GitSCMSourceRequest} will need information about branches.
*/
public final boolean wantBranches() {
return wantBranches;
}

/**
* Returns {@code true} if the {@link GitSCMSourceRequest} will need information about tags.
*
* @return {@code true} if the {@link GitSCMSourceRequest} will need information about tags.
*/
public final boolean wantTags() {
return wantTags;
}

/**
* Returns the name of the {@link GitTool} to use or {@code null} to use the default.
*
@@ -124,6 +149,34 @@ public final String remoteName() {
return remoteName;
}

/**
* Adds a requirement for branch details to any {@link GitSCMSourceRequest} for this context.
*
* @param include {@code true} to add the requirement or {@code false} to leave the requirement as is (makes
* simpler with method chaining)
* @return {@code this} for method chaining.
*/
@SuppressWarnings("unchecked")
@NonNull
public C wantBranches(boolean include) {
wantBranches = wantBranches || include;
return (C) this;
}

/**
* Adds a requirement for tag details to any {@link GitSCMSourceRequest} for this context.
*
* @param include {@code true} to add the requirement or {@code false} to leave the requirement as is (makes
* simpler with method chaining)
* @return {@code this} for method chaining.
*/
@SuppressWarnings("unchecked")
@NonNull
public C wantTags(boolean include) {
wantTags = wantTags || include;
return (C) this;
}

/**
* Configures the {@link GitTool#getName()} to use.
*

0 comments on commit 1c1c664

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