package com.attask.jenkins.templates; import com.attask.jenkins.BuildWrapperUtils; import com.google.common.collect.ImmutableSet; import hudson.Extension; import hudson.Launcher; import hudson.model.*; import hudson.tasks.BuildWrapper; import hudson.tasks.BuildWrapperDescriptor; import hudson.util.DescribableList; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; import java.io.*; import java.util.List; import java.util.Set; /** * User: Joel Johnson * Date: 6/18/12 * Time: 8:30 PM */ @ExportedBean public class TemplateBuildWrapper extends BuildWrapper implements Syncable { private final String templateName; /** * Needed for backward compatibility with systems that used an older version of this plugin */ public transient boolean synced; @DataBoundConstructor public TemplateBuildWrapper(String templateName) { this.templateName = templateName; } public void sync() throws IOException { AbstractProject templateProject = null; try { templateProject = Project.findNearest(templateName); } catch(NullPointerException ignore) { //unfortunately, on jenkins load we get null pointer exceptions here } if(templateProject != null) { Set<AbstractProject> implementingProjects = getImplementers(); for (AbstractProject implementingProject : implementingProjects) { ImplementationBuildWrapper implementationBuildWrapper = BuildWrapperUtils.findBuildWrapper(ImplementationBuildWrapper.class, implementingProject); implementationBuildWrapper.syncFromTemplate(templateProject, implementingProject); } } } public String getProjectName() { return templateName; } public Set<ImplementationBuildWrapper> findImplementersBuildWrappers() { ImmutableSet.Builder<ImplementationBuildWrapper> builder = ImmutableSet.builder(); List<AbstractProject> allProjects = Hudson.getInstance().getAllItems(AbstractProject.class); for (AbstractProject project : allProjects) { if(project instanceof BuildableItemWithBuildWrappers) { DescribableList<BuildWrapper,Descriptor<BuildWrapper>> buildWrappersList = ((BuildableItemWithBuildWrappers) project).getBuildWrappersList(); for (BuildWrapper buildWrapper : buildWrappersList) { if(buildWrapper instanceof ImplementationBuildWrapper) { builder.add((ImplementationBuildWrapper) buildWrapper); } } } } return builder.build(); } public Set<AbstractProject> getImplementers() { ImmutableSet.Builder<AbstractProject> builder = ImmutableSet.builder(); List<AbstractProject> allProjects = Hudson.getInstance().getAllItems(AbstractProject.class); for (AbstractProject project : allProjects) { if(project instanceof BuildableItemWithBuildWrappers) { DescribableList<BuildWrapper,Descriptor<BuildWrapper>> buildWrappersList = ((BuildableItemWithBuildWrappers) project).getBuildWrappersList(); for (BuildWrapper buildWrapper : buildWrappersList) { if(buildWrapper instanceof ImplementationBuildWrapper) { if(templateName.equals(((ImplementationBuildWrapper) buildWrapper).getTemplateName())) { builder.add(project); } } } } } return builder.build(); } @Exported public String getTemplateName() { return templateName; } @Override public Environment setUp(AbstractBuild build, Launcher launcher, BuildListener listener) throws IOException, InterruptedException { return new Environment() { @Override public boolean tearDown(AbstractBuild build, BuildListener listener) throws IOException, InterruptedException { return true; } }; } @Extension public static class DescriptorImpl extends BuildWrapperDescriptor { @Override public boolean isApplicable(AbstractProject<?, ?> item) { return item instanceof Describable && item instanceof BuildableItemWithBuildWrappers; } @Override public String getDisplayName() { return "Make this a Template"; } } }