diff --git a/core/src/main/java/hudson/maven/FilteredChangeLogSet.java b/core/src/main/java/hudson/maven/FilteredChangeLogSet.java new file mode 100644 index 0000000000000000000000000000000000000000..bd703bffacfb6b6057b5e7f1a538df1cfe07f43e --- /dev/null +++ b/core/src/main/java/hudson/maven/FilteredChangeLogSet.java @@ -0,0 +1,85 @@ +package hudson.maven; + +import hudson.scm.ChangeLogSet; +import hudson.scm.ChangeLogSet.Entry; + +import java.util.Iterator; +import java.util.List; +import java.util.ArrayList; + +/** + * {@link ChangeLogSet} implementation used for {@link MavenBuild}. + * + * @author Kohsuke Kawaguchi + */ +public class FilteredChangeLogSet extends ChangeLogSet { + private final List master = new ArrayList(); + + public final ChangeLogSet core; + + /*package*/ FilteredChangeLogSet(MavenBuild build) { + super(build); + MavenModule mod = build.getParent(); + + // modules that are under 'mod'. lazily computed + List subsidiaries = null; + + MavenModuleSetBuild parentBuild = build.getParentBuild(); + if(parentBuild==null) { + core = ChangeLogSet.createEmpty(build); + return; + } + + core = parentBuild.getChangeSet(); + + for (Entry e : core) { + boolean belongs = false; + + for (String path : e.getAffectedPaths()) { + if(path.startsWith(mod.getRelativePath())) { + belongs = true; + break; + } + } + + if(belongs) { + // make sure at least one change belongs to this module proper, + // and not its subsidiary module + if(subsidiaries==null) { + subsidiaries = new ArrayList(); + for (MavenModule mm : mod.getParent().getModules()) { + if(mm!=mod && mm.getRelativePath().startsWith(mod.getRelativePath())) + subsidiaries.add(mm); + } + } + + belongs = false; + + for (String path : e.getAffectedPaths()) { + if(!belongsToSubsidiary(subsidiaries, path)) { + belongs = true; + break; + } + } + + if(belongs) + master.add(e); + } + } + } + + private boolean belongsToSubsidiary(List subsidiaries, String path) { + for (MavenModule sub : subsidiaries) + if(path.startsWith(sub.getRelativePath())) + return true; + return false; + } + + public Iterator iterator() { + return master.iterator(); + } + + public boolean isEmptySet() { + return master.isEmpty(); + } +} diff --git a/core/src/main/java/hudson/maven/MavenBuild.java b/core/src/main/java/hudson/maven/MavenBuild.java index 51f650b2b2f5a378892cdac40d0255916627c2d9..1e19357638c66123aaa3b8515e75b3214579a8fe 100644 --- a/core/src/main/java/hudson/maven/MavenBuild.java +++ b/core/src/main/java/hudson/maven/MavenBuild.java @@ -7,12 +7,13 @@ import hudson.model.AbstractBuild; import hudson.model.AbstractProject; import hudson.model.BuildListener; import hudson.model.DependencyGraph; -import hudson.model.Fingerprint.RangeSet; import hudson.model.Hudson; import hudson.model.Result; import hudson.model.Run; import hudson.remoting.Channel; import hudson.remoting.VirtualChannel; +import hudson.scm.ChangeLogSet; +import hudson.scm.ChangeLogSet.Entry; import hudson.util.IOException2; import org.apache.maven.BuildFailureException; import org.apache.maven.embedder.MavenEmbedderException; @@ -53,6 +54,30 @@ public class MavenBuild extends AbstractBuild { super(project, buildDir); } + /** + * Gets the {@link MavenModuleSetBuild} that has the same build number. + * + * @return + * null if no such build exists, which happens when the module build + * is manually triggered. + */ + public MavenModuleSetBuild getParentBuild() { + return getParent().getParent().getBuildByNumber(getNumber()); + } + + @Override + public ChangeLogSet getChangeSet() { + return new FilteredChangeLogSet(this); + } + + /** + * We always get the changeset from {@link MavenModuleSetBuild}. + */ + @Override + public boolean hasChangeSetComputed() { + return true; + } + @Override public void run() { run(new RunnerImpl()); diff --git a/core/src/main/java/hudson/maven/MavenModule.java b/core/src/main/java/hudson/maven/MavenModule.java index ddddb3607060e7398bc01a5bc61dc74a4ef79f33..057442c2d2bd7ff361288ef4765d9ff9977d19fb 100644 --- a/core/src/main/java/hudson/maven/MavenModule.java +++ b/core/src/main/java/hudson/maven/MavenModule.java @@ -40,12 +40,6 @@ public final class MavenModule extends AbstractProject i private transient ModuleName moduleName; - /** - * Relative path to this module's root directory - * from {@link MavenModuleSet#getWorkspace()}. - * - * The path separator is normalized to '/'. - */ private String relativePath; /** @@ -86,6 +80,16 @@ public final class MavenModule extends AbstractProject i dependencies = Collections.emptySet(); } + /** + * Relative path to this module's root directory + * from {@link MavenModuleSet#getWorkspace()}. + * + * The path separator is normalized to '/'. + */ + public String getRelativePath() { + return relativePath; + } + @Override public FilePath getWorkspace() { return getParent().getWorkspace().child(relativePath); diff --git a/core/src/main/java/hudson/scm/CVSChangeLogSet.java b/core/src/main/java/hudson/scm/CVSChangeLogSet.java index 15ffc36b21683e66043abd68f03d817674c0bcc9..1be39b5dceab247d79874545bd75fbaebf4ae6ab 100644 --- a/core/src/main/java/hudson/scm/CVSChangeLogSet.java +++ b/core/src/main/java/hudson/scm/CVSChangeLogSet.java @@ -12,6 +12,8 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; +import java.util.Collection; +import java.util.AbstractList; /** * {@link ChangeLogSet} for CVS. @@ -140,6 +142,18 @@ public final class CVSChangeLogSet extends ChangeLogSet { return author; } + public Collection getAffectedPaths() { + return new AbstractList() { + public String get(int index) { + return files.get(index).getName(); + } + + public int size() { + return files.size(); + } + }; + } + public void setUser(String author) { this.author = User.get(author); } diff --git a/core/src/main/java/hudson/scm/ChangeLogSet.java b/core/src/main/java/hudson/scm/ChangeLogSet.java index b7ba2303dc67607bf0115f63dfd00c1dd6d771ec..309f90d691a052056623606f65f047c6caa393d0 100644 --- a/core/src/main/java/hudson/scm/ChangeLogSet.java +++ b/core/src/main/java/hudson/scm/ChangeLogSet.java @@ -1,10 +1,11 @@ package hudson.scm; -import hudson.model.User; -import hudson.model.AbstractBuild; import hudson.MarkupText; import hudson.Util; +import hudson.model.AbstractBuild; +import hudson.model.User; +import java.util.Collection; import java.util.Collections; /** @@ -71,6 +72,18 @@ public abstract class ChangeLogSet implements Iter */ public abstract User getAuthor(); + /** + * Returns a set of paths in the workspace that was + * affected by this change. + * + *

+ * Contains string like 'foo/bar/zot'. No leading/trailing '/', + * and separator must be normalized to '/'. + * + * @return never null. + */ + public abstract Collection getAffectedPaths(); + /** * Gets the text fully marked up by {@link ChangeLogAnnotator}. */ diff --git a/core/src/main/java/hudson/scm/SubversionChangeLogSet.java b/core/src/main/java/hudson/scm/SubversionChangeLogSet.java index 7a943b1bf2153d8ef61f4a2048aa7c59fc380d29..2bc05c50d07298c73e9d0dc542da5f91409767d9 100644 --- a/core/src/main/java/hudson/scm/SubversionChangeLogSet.java +++ b/core/src/main/java/hudson/scm/SubversionChangeLogSet.java @@ -10,6 +10,8 @@ import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Collection; +import java.util.AbstractList; /** * {@link ChangeLogSet} for Subversion. @@ -72,6 +74,17 @@ public final class SubversionChangeLogSet extends ChangeLogSet { return author; } + public Collection getAffectedPaths() { + return new AbstractList() { + public String get(int index) { + return paths.get(index).value; + } + public int size() { + return paths.size(); + } + }; + } + public void setUser(String author) { this.author = User.get(author); } diff --git a/core/src/main/resources/hudson/maven/FilteredChangeLogSet/digest.jelly b/core/src/main/resources/hudson/maven/FilteredChangeLogSet/digest.jelly new file mode 100644 index 0000000000000000000000000000000000000000..ed5b00b5f186072570e110dd106ded4675af98ac --- /dev/null +++ b/core/src/main/resources/hudson/maven/FilteredChangeLogSet/digest.jelly @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/core/src/main/resources/hudson/maven/FilteredChangeLogSet/index.jelly b/core/src/main/resources/hudson/maven/FilteredChangeLogSet/index.jelly new file mode 100644 index 0000000000000000000000000000000000000000..7269c5e33d57890d593bd1073dc60be8e8ec7365 --- /dev/null +++ b/core/src/main/resources/hudson/maven/FilteredChangeLogSet/index.jelly @@ -0,0 +1,3 @@ + + + \ No newline at end of file