diff --git a/core/src/main/java/hudson/model/AbstractBuild.java b/core/src/main/java/hudson/model/AbstractBuild.java
index 5fd3ef4006..168505f29a 100644
--- a/core/src/main/java/hudson/model/AbstractBuild.java
+++ b/core/src/main/java/hudson/model/AbstractBuild.java
@@ -181,12 +181,6 @@ public abstract class AbstractBuild
,R extends Abs
return runMixIn;
}
- @Override
- @Nonnull public List> getChangeSets() {
- ChangeLogSet extends Entry> cs = getChangeSet();
- return cs.isEmptySet() ? Collections.emptyList() : Collections.singletonList(cs);
- }
-
@Override protected final BuildReference createReference() {
return getRunMixIn().createReference();
}
@@ -849,6 +843,12 @@ public abstract class AbstractBuild,R extends Abs
return cs;
}
+ @Override
+ @Nonnull public List> getChangeSets() {
+ ChangeLogSet extends Entry> cs = getChangeSet();
+ return cs.isEmptySet() ? Collections.emptyList() : Collections.singletonList(cs);
+ }
+
/**
* Returns true if the changelog is already computed.
*/
diff --git a/core/src/main/java/hudson/model/View.java b/core/src/main/java/hudson/model/View.java
index 68dd95299f..ac15a8569a 100644
--- a/core/src/main/java/hudson/model/View.java
+++ b/core/src/main/java/hudson/model/View.java
@@ -773,18 +773,16 @@ public abstract class View extends AbstractModelObject implements AccessControll
public static boolean isApplicable(Collection extends Item> items) {
for (Item item : items) {
for (Job job : item.getAllJobs()) {
- if (job instanceof SCMTriggerItem) {
- RunList extends Run, ?>> runs = job.getBuilds();
+ RunList extends Run, ?>> runs = job.getBuilds();
- for (Run,?> r : runs) {
- if (r instanceof RunWithSCM) {
- RunWithSCM,?> runWithSCM = (RunWithSCM,?>) r;
- for (ChangeLogSet extends Entry> c : runWithSCM.getChangeSets()) {
- for (Entry entry : c) {
- User user = entry.getAuthor();
- if (user != null)
- return true;
- }
+ for (Run,?> r : runs) {
+ if (r instanceof RunWithSCM) {
+ RunWithSCM,?> runWithSCM = (RunWithSCM,?>) r;
+ for (ChangeLogSet extends Entry> c : runWithSCM.getChangeSets()) {
+ for (Entry entry : c) {
+ User user = entry.getAuthor();
+ if (user != null)
+ return true;
}
}
}
diff --git a/core/src/main/java/hudson/scm/SCM.java b/core/src/main/java/hudson/scm/SCM.java
index 01b0c2e2b2..4c9f7b0ec8 100644
--- a/core/src/main/java/hudson/scm/SCM.java
+++ b/core/src/main/java/hudson/scm/SCM.java
@@ -522,10 +522,10 @@ public abstract class SCM implements Describable, ExtensionPoint {
* (for example, SVN revision number.)
*
*
- * This method is invoked whenever someone does {@link Run#getEnvironment(TaskListener)}, which
- * can be before/after your checkout method is invoked. So if you are going to provide information about
- * check out (like SVN revision number that was checked out), be prepared for the possibility that the
- * check out hasn't happened yet.
+ * This method is invoked whenever someone does {@link AbstractBuild#getEnvironment(TaskListener)}, via
+ * {@link #buildEnvVars(AbstractBuild, Map)}, whichvcan be before/after your checkout method is invoked. So if you
+ * are going to provide information aboutvcheck out (like SVN revision number that was checked out), be prepared
+ * for the possibility that thevcheck out hasn't happened yet.
*
* @since FIXME
*/
diff --git a/core/src/main/java/jenkins/scm/RunWithSCM.java b/core/src/main/java/jenkins/scm/RunWithSCM.java
index e56d636138..7797f8c88d 100644
--- a/core/src/main/java/jenkins/scm/RunWithSCM.java
+++ b/core/src/main/java/jenkins/scm/RunWithSCM.java
@@ -1,7 +1,7 @@
/*
* The MIT License
*
- * Copyright 2014 Jesse Glick.
+ * Copyright 2017 CloudBees, inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -24,6 +24,7 @@
package jenkins.scm;
+import com.google.common.collect.ImmutableSet;
import hudson.model.Job;
import hudson.model.Queue;
import hudson.model.Result;
@@ -31,7 +32,6 @@ import hudson.model.Run;
import hudson.model.User;
import hudson.scm.ChangeLogSet;
import hudson.util.AdaptedIterator;
-import jenkins.util.SystemProperties;
import org.kohsuke.stapler.export.Exported;
import javax.annotation.CheckForNull;
@@ -50,11 +50,27 @@ import java.util.logging.Logger;
public interface RunWithSCM & Queue.Task,
RunT extends Run & RunWithSCM & Queue.Executable> {
+ /**
+ * Gets all {@link ChangeLogSet}s currently associated with this item.
+ *
+ * @return A possibly empty list of {@link ChangeLogSet}s.
+ */
+ @Nonnull
List> getChangeSets();
+ /**
+ * Gets the ids for all {@link User}s included in {@link #getChangeSets()} for this item.
+ *
+ * @return A possibly null set of user IDs.
+ */
@CheckForNull
Set getCulpritIds();
+ /**
+ * Determines whether culprits should be recalcuated or the existing {@link #getCulpritIds()} should be used instead.
+ *
+ * @return True if culprits should be recalcuated, false otherwise.
+ */
boolean shouldCalculateCulprits();
/**
@@ -74,8 +90,10 @@ public interface RunWithSCM & Queue.Task,
}
return new AbstractSet() {
+ private Set culpritIds = ImmutableSet.copyOf(getCulpritIds());
+
public Iterator iterator() {
- return new AdaptedIterator(getCulpritIds().iterator()) {
+ return new AdaptedIterator(culpritIds.iterator()) {
protected User adapt(String id) {
return User.get(id);
}
@@ -83,14 +101,21 @@ public interface RunWithSCM & Queue.Task,
}
public int size() {
- return getCulpritIds().size();
+ return culpritIds.size();
}
};
}
+ /**
+ * Internal method used for actually calculating the culprits from scratch. Called by {@link #getCulprits()} and
+ * overrides of {@link #getCulprits()}. Does not persist culprits information.
+ *
+ * @return a non-null {@link Set} of {@link User}s associated with this item.
+ */
@SuppressWarnings("unchecked")
+ @Nonnull
default Set calculateCulprits() {
- Set r = new HashSet();
+ Set r = new HashSet<>();
RunT p = ((RunT)this).getPreviousCompletedBuild();
if (p != null && ((RunT)this).isBuilding()) {
Result pr = p.getResult();
@@ -103,8 +128,9 @@ public interface RunWithSCM & Queue.Task,
}
}
for (ChangeLogSet extends ChangeLogSet.Entry> c : getChangeSets()) {
- for (ChangeLogSet.Entry e : c)
+ for (ChangeLogSet.Entry e : c) {
r.add(e.getAuthor());
+ }
}
return r;
@@ -116,14 +142,16 @@ public interface RunWithSCM & Queue.Task,
@SuppressWarnings("unchecked")
default boolean hasParticipant(User user) {
for (ChangeLogSet extends ChangeLogSet.Entry> c : getChangeSets()) {
- for (ChangeLogSet.Entry e : c)
+ for (ChangeLogSet.Entry e : c) {
try {
- if (e.getAuthor() == user)
+ if (e.getAuthor() == user) {
return true;
+ }
} catch (RuntimeException re) {
Logger LOGGER = Logger.getLogger(RunWithSCM.class.getName());
- LOGGER.log(Level.INFO, "Failed to determine author of changelog " + e.getCommitId() + "for " + ((RunT)this).getParent().getDisplayName() + ", " + ((RunT)this).getDisplayName(), re);
+ LOGGER.log(Level.INFO, "Failed to determine author of changelog " + e.getCommitId() + "for " + ((RunT) this).getParent().getDisplayName() + ", " + ((RunT) this).getDisplayName(), re);
}
+ }
}
return false;
}