package hudson.plugins.blame_upstream_commiters;
import hudson.Extension;
import hudson.Launcher;
import hudson.model.AbstractBuild;
import hudson.model.AbstractProject;
import hudson.model.BuildListener;
import hudson.model.Result;
import hudson.tasks.ArtifactArchiver;
import hudson.tasks.BuildStepDescriptor;
import hudson.tasks.BuildStepMonitor;
import hudson.tasks.MailSender;
import hudson.tasks.Mailer;
import hudson.tasks.Notifier;
import hudson.tasks.Publisher;
import java.io.File;
import java.util.ArrayList;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.lang.StringUtils;
import org.apache.tools.ant.types.selectors.SelectorUtils;
import org.kohsuke.stapler.DataBoundConstructor;
@SuppressWarnings({ "unchecked" })
public class BlameUpstreamCommitersPublisher extends Notifier {
//public static final DescriptorImpl DESCRIPTOR = new DescriptorImpl();
protected static final Logger LOGGER = Logger.getLogger(Mailer.class.getName());
public boolean sendToIndividuals = false;
@DataBoundConstructor
public BlameUpstreamCommitersPublisher()
{
}
public BuildStepMonitor getRequiredMonitorService() {
return BuildStepMonitor.NONE;
}
@Override
public boolean needsToRunAfterFinalized() {
return true;
}
@Override
public boolean perform(AbstractBuild<?,?> build, Launcher launcher, BuildListener listener) throws InterruptedException {
if (build.getResult() != Result.SUCCESS)
{
ArrayList<String> recipientUpstreamProjects=this.getUpstreamRecipients(build);
if (recipientUpstreamProjects.size() > 0) {
String recipentString="";
recipentString = "upstream-individuals:"+StringUtils.join(recipientUpstreamProjects, " upstream-individuals:");
listener.getLogger().println("Upstream projects changes detected. Mailing upstream committers in the following projects:");
listener.getLogger().println(StringUtils.join(recipientUpstreamProjects,","));
return new MailSender(recipentString,false,sendToIndividuals) {
/** Check whether a path (/-separated) will be archived. */
@Override
public boolean artifactMatches(String path, AbstractBuild<?,?> build) {
ArtifactArchiver aa = build.getProject().getPublishersList().get(ArtifactArchiver.class);
if (aa == null) {
LOGGER.finer("No ArtifactArchiver found");
return false;
}
String artifacts = aa.getArtifacts();
for (String include : artifacts.split("[, ]+")) {
String pattern = include.replace(File.separatorChar, '/');
if (pattern.endsWith("/")) {
pattern += "**";
}
if (SelectorUtils.matchPath(pattern, path)) {
LOGGER.log(Level.FINER, "DescriptorImpl.artifactMatches true for {0} against {1}", new Object[] {path, pattern});
return true;
}
}
LOGGER.log(Level.FINER, "DescriptorImpl.artifactMatches for {0} matched none of {1}", new Object[] {path, artifacts});
return false;
}
}.execute(build,listener);
}
}
return true;
}
private ArrayList<String> getUpstreamRecipients (AbstractBuild<?,?> build)
{
ArrayList<String> recipientList =new ArrayList<String>();
Map <AbstractProject,Integer> upstreamBuilds = build.getUpstreamBuilds();
if (upstreamBuilds != null) {
for (AbstractProject project : upstreamBuilds.keySet()) {
recipientList.add(project.getName().replaceAll(" ", "\\ "));
}
}
return recipientList;
}
@Extension
public static final class DescriptorImpl extends BuildStepDescriptor<Publisher> {
public DescriptorImpl() {
super(BlameUpstreamCommitersPublisher.class);
}
public String getDisplayName() {
return "Mail upstream committers when the build fails";
}
public boolean isApplicable(Class<? extends AbstractProject> jobType) {
return true;
}
}
}