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 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 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 items) { for (Item item : items) { for (Job job : item.getAllJobs()) { - if (job instanceof SCMTriggerItem) { - RunList> runs = job.getBuilds(); + RunList> runs = job.getBuilds(); - for (Run r : runs) { - if (r instanceof RunWithSCM) { - RunWithSCM runWithSCM = (RunWithSCM) r; - for (ChangeLogSet 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 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 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 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; }