All Downloads are FREE. Search and download functionalities are using the official Maven repository.

hudson.maven.MavenModule Maven / Gradle / Ivy

package hudson.maven;

import hudson.CopyOnWrite;
import hudson.FilePath;
import hudson.Util;
import hudson.Functions;
import hudson.maven.reporters.MavenMailer;
import hudson.model.AbstractProject;
import hudson.model.Action;
import hudson.model.DependencyGraph;
import hudson.model.Descriptor;
import hudson.model.Descriptor.FormException;
import hudson.model.Hudson;
import hudson.model.Item;
import hudson.model.ItemGroup;
import hudson.model.JDK;
import hudson.model.Job;
import hudson.model.Label;
import hudson.model.Node;
import hudson.model.Resource;
import hudson.tasks.LogRotator;
import hudson.tasks.Publisher;
import hudson.tasks.Maven.MavenInstallation;
import hudson.util.DescribableList;
import org.apache.maven.project.MavenProject;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;

import javax.servlet.ServletException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.HashSet;

/**
 * {@link Job} that builds projects based on Maven2.
 * 
 * @author Kohsuke Kawaguchi
 */
public final class MavenModule extends AbstractMavenProject implements DescribableList.Owner {
    private DescribableList> reporters =
        new DescribableList>(this);

    /**
     * Name taken from {@link MavenProject#getName()}.
     */
    private String displayName;

    /**
     * Version number of this module as of fhe last build, taken from {@link MavenProject#getVersion()}.
     *
     * This field can be null if Hudson loaded old data
     * that didn't record this information, so that situation
     * needs to be handled gracefully.
     */
    private String version;

    private transient ModuleName moduleName;

    private String relativePath;

    /**
     * If this module has goals specified by itself.
     * Otherwise leave it null to use the default goals specified in the parent.
     */
    private String goals;

    /**
     * List of modules that this module declares direct dependencies on.
     */
    @CopyOnWrite
    private volatile Set dependencies;

    /**
     * List of child modules as defined by <module> POM element.
     * Used to determine parent/child relationship of modules.
     * 

* For compatibility reason, this field may be null when loading data from old hudson. */ @CopyOnWrite private volatile List children; /** * Nest level used to display this module in the module list. * The root module and orphaned module gets 0. */ /*package*/ volatile transient int nestLevel; /*package*/ MavenModule(MavenModuleSet parent, PomInfo pom, int firstBuildNumber) throws IOException { super(parent, pom.name.toFileSystemName()); reconfigure(pom); updateNextBuildNumber(firstBuildNumber); } /** * {@link MavenModule} follows the same log rotation schedule as its parent. */ @Override public LogRotator getLogRotator() { return getParent().getLogRotator(); } /** * @deprecated * Not allowed to configure log rotation per module. */ @Override public void setLogRotator(LogRotator logRotator) { throw new UnsupportedOperationException(); } @Override public boolean supportsLogRotator() { return false; } /** * Called to update the module with the new POM. *

* This method is invoked on {@link MavenModule} that has the matching * {@link ModuleName}. */ /*package*/ final void reconfigure(PomInfo pom) { this.displayName = pom.displayName; this.version = pom.version; this.relativePath = pom.relativePath; this.dependencies = pom.dependencies; this.children = pom.children; this.nestLevel = pom.getNestLevel(); disabled = false; if (pom.mailNotifier != null) { MavenReporter reporter = getReporters().get(MavenMailer.DescriptorImpl.DESCRIPTOR); if (reporter != null) { MavenMailer mailer = (MavenMailer) reporter; mailer.dontNotifyEveryUnstableBuild = !pom.mailNotifier.isSendOnFailure(); String recipients = pom.mailNotifier.getConfiguration().getProperty("recipients"); if (recipients != null) { mailer.recipients = recipients; } } } } protected void doSetName(String name) { moduleName = ModuleName.fromFileSystemName(name); super.doSetName(moduleName.toString()); } @Override public void onLoad(ItemGroup parent, String name) throws IOException { super.onLoad(parent,name); if(reporters==null) reporters = new DescribableList>(this); reporters.setOwner(this); if(dependencies==null) dependencies = Collections.emptySet(); else { // Until 1.207, we used to have ModuleName in dependencies. So convert. Set deps = new HashSet(dependencies.size()); for (Object d : (Set)dependencies) { if (d instanceof ModuleDependency) { deps.add((ModuleDependency) d); } else { deps.add(new ModuleDependency((ModuleName)d, ModuleDependency.UNKNOWN)); } } dependencies = deps; } } /** * Relative path to this module's root directory * from {@link MavenModuleSet#getWorkspace()}. * * The path separator is normalized to '/'. */ public String getRelativePath() { return relativePath; } /** * Gets the version number in Maven POM as of the last build. * * @return * This method can return null if Hudson loaded old data * that didn't record this information, so that situation * needs to be handled gracefully. */ public String getVersion() { return version; } /** * Gets the list of goals to execute for this module. */ public String getGoals() { if(goals!=null) return goals; return getParent().getGoals(); } /** * Gets the list of goals specified by the user, * without taking inheritance and POM default goals * into account. * *

* This is only used to present the UI screen, and in * all the other cases {@link #getGoals()} should be used. */ public String getUserConfiguredGoals() { return goals; } @Override public FilePath getWorkspace() { return getParent().getModuleRoot().child(relativePath); } public DescribableList> getPublishersList() { // TODO return new DescribableList>(this); } @Override public JDK getJDK() { // share one setting for the whole module set. return getParent().getJDK(); } @Override protected Class getBuildClass() { return MavenBuild.class; } @Override protected MavenBuild newBuild() throws IOException { return super.newBuild(); } public ModuleName getModuleName() { return moduleName; } /** * Gets groupId+artifactId+version as {@link ModuleDependency}. */ public ModuleDependency asDependency() { return new ModuleDependency(moduleName,Functions.defaulted(version,ModuleDependency.UNKNOWN)); } @Override public String getShortUrl() { return moduleName.toFileSystemName()+'/'; } @Override public String getDisplayName() { return displayName; } @Override public String getPronoun() { return Messages.MavenModule_Pronoun(); } @Override public boolean isNameEditable() { return false; } public MavenModuleSet getParent() { return (MavenModuleSet)super.getParent(); } /** * Gets all the child modules (that are listed in the <module> element in our POM.) *

* This method returns null if this information is not recorded. This happens * for compatibility reason. */ public List getChildren() { List l = children; // take a snapshot if(l==null) return null; List modules = new ArrayList(l.size()); for (ModuleName n : l) { MavenModule m = getParent().modules.get(n); if(m!=null) modules.add(m); } return modules; } /** * {@link MavenModule} uses the workspace of the {@link MavenModuleSet}, * so it always needs to be built on the same slave as the parent. */ public Label getAssignedLabel() { Node n = getParent().getLastBuiltOn(); if(n==null) return null; return n.getSelfLabel(); } /** * Workspace of a {@link MavenModule} is a part of the parent's workspace. *

* That is, {@Link MavenModuleSet} builds are incompatible with any {@link MavenModule} * builds, whereas {@link MavenModule} builds are compatible with each other. */ @Override public Resource getWorkspaceResource() { return new Resource(getParent().getWorkspaceResource(),getDisplayName()+" workspace"); } @Override public boolean isFingerprintConfigured() { return true; } protected void buildDependencyGraph(DependencyGraph graph) { if(isDisabled()) return; Map modules = new HashMap(); // when we load old data that doesn't record version in dependency, we'd like // to emulate the old behavior that it tries to identify the upstream by ignoring the version. // do this by always putting groupId:artifactId:UNKNOWN to the modules list. for (MavenModule m : Hudson.getInstance().getAllItems(MavenModule.class)) { if(m.isDisabled()) continue; modules.put(m.asDependency(),m); modules.put(m.asDependency().withUnknownVersion(),m); } // in case two modules with the same name is defined, modules in the same MavenModuleSet // takes precedence. for (MavenModule m : getParent().getModules()) { if(m.isDisabled()) continue; modules.put(m.asDependency(),m); modules.put(m.asDependency().withUnknownVersion(),m); } // if the build style is the aggregator build, define dependencies against project, // not module. AbstractProject dest = getParent().isAggregatorStyleBuild() ? getParent() : this; for (ModuleDependency d : dependencies) { MavenModule src = modules.get(d); if(src!=null) { if(src.getParent().isAggregatorStyleBuild()) graph.addDependency(src.getParent(),dest); else graph.addDependency(src,dest); } } } @Override protected void addTransientActionsFromBuild(MavenBuild build, Set added) { if(build==null) return; List list = build.projectActionReporters; if(list==null) return; for (MavenReporter step : list) { if(!added.add(step.getClass())) continue; // already added Action a = step.getProjectAction(this); if(a!=null) transientActions.add(a); } } @Override public MavenInstallation inferMavenInstallation() { return getParent().inferMavenInstallation(); } /** * List of active {@link MavenReporter}s configured for this module. */ public DescribableList> getReporters() { return reporters; } protected void submit(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, FormException { super.submit(req, rsp); reporters.rebuild(req, req.getSubmittedForm(),MavenReporters.getConfigurableList(),"reporter"); goals = Util.fixEmpty(req.getParameter("goals").trim()); // dependency setting might have been changed by the user, so rebuild. Hudson.getInstance().rebuildDependencyGraph(); } protected void performDelete() throws IOException { super.performDelete(); getParent().onModuleDeleted(this); } /** * Marks this build as disabled. */ public void disable() throws IOException { if(!disabled) { disabled = true; save(); } } /** * Creates a list of {@link MavenReporter}s to be used for a build of this project. */ protected final List createReporters() { List reporters = new ArrayList(); getReporters().addAllTo(reporters); getParent().getReporters().addAllTo(reporters); for (MavenReporterDescriptor d : MavenReporters.LIST) { if(getReporters().contains(d)) continue; // already configured MavenReporter auto = d.newAutoInstance(this); if(auto!=null) reporters.add(auto); } return reporters; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy