diff --git a/src/it/compare-ignore/invoker.properties b/src/it/compare-ignore/invoker.properties
new file mode 100644
index 0000000..6350e3b
--- /dev/null
+++ b/src/it/compare-ignore/invoker.properties
@@ -0,0 +1,21 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# initial reference build: install
+invoker.goals.1=clean install
+# second build: verify (could be package, but not install to avoid overriding reference)
+invoker.goals.2=clean verify artifact:compare
diff --git a/src/it/compare-ignore/modA/pom.xml b/src/it/compare-ignore/modA/pom.xml
new file mode 100644
index 0000000..5a65571
--- /dev/null
+++ b/src/it/compare-ignore/modA/pom.xml
@@ -0,0 +1,61 @@
+
+
+
+
+
+ 4.0.0
+
+
+ org.apache.maven.plugins.it
+ ignore
+ 1.0-SNAPSHOT
+
+ ignore-modA
+ jar
+ ignore module A
+
+
+
+
+ src/main/resources
+ true
+
+
+
+
+
+ @project.groupId@
+ @project.artifactId@
+ @project.version@
+
+ */ignore-modA-*.jar
+
+
+
+
+ compare
+
+
+
+
+
+
+
diff --git a/src/it/compare-ignore/modA/src/main/resources/filtered.properties b/src/it/compare-ignore/modA/src/main/resources/filtered.properties
new file mode 100644
index 0000000..3fa6b09
--- /dev/null
+++ b/src/it/compare-ignore/modA/src/main/resources/filtered.properties
@@ -0,0 +1,18 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+project.build.outputTimestamp=${project.build.outputTimestamp}
diff --git a/src/it/compare-ignore/modB/pom.xml b/src/it/compare-ignore/modB/pom.xml
new file mode 100644
index 0000000..18e0e2f
--- /dev/null
+++ b/src/it/compare-ignore/modB/pom.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+ 4.0.0
+
+
+ org.apache.maven.plugins.it
+ ignore
+ 1.0-SNAPSHOT
+
+ ignore-modB
+ pom
+ ignore module B
+
+
+
+ org.apache.maven.plugins.it
+ ignore-modA
+ 1.0-SNAPSHOT
+
+
+
diff --git a/src/it/compare-ignore/pom.xml b/src/it/compare-ignore/pom.xml
new file mode 100644
index 0000000..d580e61
--- /dev/null
+++ b/src/it/compare-ignore/pom.xml
@@ -0,0 +1,70 @@
+
+
+
+
+
+ 4.0.0
+
+ org.apache.maven.plugins.it
+ ignore
+ 1.0-SNAPSHOT
+ pom
+
+ An IT verifying compare works when resuming a multi-module build.
+
+
+ UTF-8
+
+
+
+ 3.0.5
+
+
+
+
+ local-snapshots
+ file://${basedir}/target/remote-repo
+ false
+
+
+
+
+ modB
+ modA
+
+
+
+
+
+ @project.groupId@
+ @project.artifactId@
+ @project.version@
+
+
+
+ compare
+
+
+
+
+
+
+
diff --git a/src/it/settings.xml b/src/it/settings.xml
index 43a94d4..2592384 100644
--- a/src/it/settings.xml
+++ b/src/it/settings.xml
@@ -26,6 +26,9 @@
true
+
+ nexus
+
local.central
diff --git a/src/main/java/org/apache/maven/plugins/artifact/buildinfo/AbstractBuildinfoMojo.java b/src/main/java/org/apache/maven/plugins/artifact/buildinfo/AbstractBuildinfoMojo.java
index 76f8678..f647548 100644
--- a/src/main/java/org/apache/maven/plugins/artifact/buildinfo/AbstractBuildinfoMojo.java
+++ b/src/main/java/org/apache/maven/plugins/artifact/buildinfo/AbstractBuildinfoMojo.java
@@ -76,14 +76,14 @@ public abstract class AbstractBuildinfoMojo extends AbstractMojo {
* Ignore javadoc attached artifacts from buildinfo generation.
*/
@Parameter(property = "buildinfo.ignoreJavadoc", defaultValue = "true")
- private boolean ignoreJavadoc;
+ boolean ignoreJavadoc;
/**
* Artifacts to ignore, specified as a glob matching against ${groupId}/${filename}, for example
* *>/*.xml.
*/
@Parameter(property = "buildinfo.ignore", defaultValue = "")
- private List ignore;
+ List ignore;
/**
* Detect projects/modules with install or deploy skipped: avoid taking fingerprints.
@@ -148,6 +148,8 @@ public void execute() throws MojoExecutionException {
hasBadOutputTimestamp(outputTimestamp, getLog(), project, session.getProjects(), diagnose);
+ initModuleBuildInfo();
+
if (!mono) {
// if module skips install and/or deploy
if (isSkip(project)) {
@@ -171,6 +173,10 @@ public void execute() throws MojoExecutionException {
execute(artifacts);
}
+ protected void initModuleBuildInfo() {
+ BuildInfoWriter.addModuleBuildInfo(getPluginContext(), ignore, ignoreJavadoc);
+ }
+
static boolean hasBadOutputTimestamp(
String outputTimestamp,
Log log,
@@ -303,9 +309,9 @@ protected void copyAggregateToRoot(File aggregate) throws MojoExecutionException
protected BuildInfoWriter newBuildInfoWriter(PrintWriter p, boolean mono) {
BuildInfoWriter bi = new BuildInfoWriter(getLog(), p, mono, rtInformation);
- bi.setIgnoreJavadoc(ignoreJavadoc);
- bi.setIgnore(ignore);
bi.setToolchain(getToolchain());
+ bi.setSession(session);
+ bi.setPluginContext(getPluginContext());
return bi;
}
@@ -329,11 +335,11 @@ protected Map generateBuildinfo(boolean mono) throws MojoExecu
// artifact(s) fingerprints
if (mono) {
- bi.printArtifacts(project);
+ bi.printArtifacts(project, project);
} else {
- for (MavenProject project : session.getProjects()) {
- if (!isSkip(project)) {
- bi.printArtifacts(project);
+ for (MavenProject moduleProject : session.getProjects()) {
+ if (!isSkip(moduleProject)) {
+ bi.printArtifacts(moduleProject, project);
}
}
}
diff --git a/src/main/java/org/apache/maven/plugins/artifact/buildinfo/BuildInfoWriter.java b/src/main/java/org/apache/maven/plugins/artifact/buildinfo/BuildInfoWriter.java
index bcb3c52..9ede247 100644
--- a/src/main/java/org/apache/maven/plugins/artifact/buildinfo/BuildInfoWriter.java
+++ b/src/main/java/org/apache/maven/plugins/artifact/buildinfo/BuildInfoWriter.java
@@ -37,7 +37,9 @@
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.maven.RepositoryUtils;
+import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.project.MavenProject;
import org.apache.maven.rtinfo.RuntimeInformation;
@@ -46,19 +48,26 @@
import org.eclipse.aether.artifact.DefaultArtifact;
import org.eclipse.aether.util.artifact.ArtifactIdUtils;
+import static java.util.Objects.requireNonNull;
+
/**
* Buildinfo content writer.
*/
class BuildInfoWriter {
+
+ private static final String MODULE_BUILD_INFO_KEY = "moduleBuildInfo";
+
private final Log log;
private final PrintWriter p;
private final boolean mono;
private final RuntimeInformation rtInformation;
private final Map artifacts = new LinkedHashMap<>();
private int projectCount = -1;
- private boolean ignoreJavadoc = true;
- private List ignore;
private Toolchain toolchain;
+ private MavenSession session;
+
+ @SuppressWarnings("rawtypes")
+ private Map pluginContext;
BuildInfoWriter(Log log, PrintWriter p, boolean mono, RuntimeInformation rtInformation) {
this.log = log;
@@ -151,7 +160,7 @@ private void printSourceInformation(MavenProject project) {
}
}
- void printArtifacts(MavenProject project) throws MojoExecutionException {
+ void printArtifacts(MavenProject project, MavenProject aggregator) throws MojoExecutionException {
String prefix = "outputs.";
if (!mono) {
// aggregated buildinfo output
@@ -209,8 +218,15 @@ void printArtifacts(MavenProject project) throws MojoExecutionException {
return;
}
+ final ModuleBuildInfo moduleBuildInfo = getModuleBuildInfo(project, aggregator);
if (project.getArtifact().getFile() != null) {
- printArtifact(prefix, n++, RepositoryUtils.toArtifact(project.getArtifact()));
+ Artifact artifact = RepositoryUtils.toArtifact(project.getArtifact());
+ if (moduleBuildInfo.isIgnore(artifact)) {
+ p.println("# ignored " + getArtifactFilename(artifact));
+ artifacts.put(artifact, null);
+ } else {
+ printArtifact(prefix, n++, RepositoryUtils.toArtifact(project.getArtifact()));
+ }
}
for (Artifact attached : RepositoryUtils.toArtifacts(project.getAttachedArtifacts())) {
@@ -222,11 +238,11 @@ void printArtifacts(MavenProject project) throws MojoExecutionException {
// ignore pgp signatures
continue;
}
- if (ignoreJavadoc && "javadoc".equals(attached.getClassifier())) {
+ if (moduleBuildInfo.ignoreJavadoc && "javadoc".equals(attached.getClassifier())) {
// TEMPORARY ignore javadoc, waiting for MJAVADOC-627 in m-javadoc-p 3.2.0
continue;
}
- if (isIgnore(attached)) {
+ if (moduleBuildInfo.isIgnore(attached)) {
p.println("# ignored " + getArtifactFilename(attached));
artifacts.put(attached, null);
continue;
@@ -320,25 +336,108 @@ static Properties loadOutputProperties(File buildinfo) throws MojoExecutionExcep
return prop;
}
- boolean getIgnoreJavadoc() {
- return ignoreJavadoc;
+ boolean getIgnoreJavadoc(MavenProject project) {
+ // atm this is only called by DescribeBuildOutputMojo, where aggregator is always the same as project
+ return getModuleBuildInfo(project, project).ignoreJavadoc;
}
- void setIgnoreJavadoc(boolean ignoreJavadoc) {
- this.ignoreJavadoc = ignoreJavadoc;
+ boolean isIgnore(MavenProject project, Artifact attached) {
+ // atm this is only called by DescribeBuildOutputMojo, where aggregator is always the same as project
+ return getModuleBuildInfo(project, project).isIgnore(attached);
}
- void setIgnore(List ignore) {
- FileSystem fs = FileSystems.getDefault();
- this.ignore = ignore.stream().map(i -> fs.getPathMatcher("glob:" + i)).collect(Collectors.toList());
+ public void setToolchain(Toolchain toolchain) {
+ this.toolchain = toolchain;
}
- boolean isIgnore(Artifact attached) {
- Path path = Paths.get(attached.getGroupId() + '/' + getArtifactFilename(attached));
- return ignore.stream().anyMatch(m -> m.matches(path));
+ public void setSession(MavenSession session) {
+ this.session = session;
}
- public void setToolchain(Toolchain toolchain) {
- this.toolchain = toolchain;
+ public void setPluginContext(Map pluginContext) {
+ this.pluginContext = pluginContext;
+ }
+
+ private ModuleBuildInfo getModuleBuildInfo(MavenProject project, MavenProject aggregator) {
+ // pluginContext is project-specific
+ PluginDescriptor pluginDescriptor = requireNonNull(
+ (PluginDescriptor) pluginContext.get("pluginDescriptor"),
+ "pluginDescriptor not found in pluginContext");
+ ModuleBuildInfo moduleBuildInfo = tryGetModuleBuildInfo(project, pluginDescriptor);
+ if (moduleBuildInfo == null) {
+ // fallback to aggregator if not found for module - this can happen e.g. if the plugin
+ // did not run for the module (e.g. we're resuming the reactor build). the aggregator
+ // should be the project we're actually running in, it should always be available).
+ moduleBuildInfo = requireNonNull(
+ tryGetModuleBuildInfo(aggregator, pluginDescriptor),
+ "moduleBuildInfo not found for project: " + aggregator);
+ }
+ return moduleBuildInfo;
+ }
+
+ @SuppressWarnings("rawtypes")
+ private ModuleBuildInfo tryGetModuleBuildInfo(MavenProject project, PluginDescriptor pluginDescriptor) {
+ Map projectPluginContext = session.getPluginContext(pluginDescriptor, project);
+ return ModuleBuildInfo.tryLoad(projectPluginContext);
+ }
+
+ /**
+ * {@code static} because we invoke it at times when no {@code BuildInfoWriter} is available.
+ */
+ @SuppressWarnings("rawtypes")
+ static void addModuleBuildInfo(Map pluginContext, List ignore, boolean ignoreJavadoc) {
+ new ModuleBuildInfo(ignore, ignoreJavadoc).store(pluginContext);
+ }
+
+ /**
+ * Stores module-specific buildInfo configuration - this is used in the aggregator to ensure that
+ * the aggregator respects each module's configuration. For clarify the modules of a
+ * multi-module are exposed in the code as {@link MavenProject MavenProjects}.
+ */
+ static class ModuleBuildInfo {
+
+ @SuppressWarnings({"rawtypes", "unchecked"})
+ public static ModuleBuildInfo tryLoad(Map pluginContext) {
+ Object[] params;
+ synchronized (pluginContext) {
+ params = (Object[]) pluginContext.get(MODULE_BUILD_INFO_KEY);
+ }
+ if (params == null) {
+ return null;
+ }
+ return new ModuleBuildInfo((List) params[0], (Boolean) params[1]);
+ }
+
+ private final List ignore;
+ final boolean ignoreJavadoc;
+
+ ModuleBuildInfo(List ignore, boolean ignoreJavadoc) {
+ FileSystem fs = FileSystems.getDefault();
+ this.ignore =
+ ignore.stream().map(i -> fs.getPathMatcher("glob:" + i)).collect(Collectors.toList());
+ this.ignoreJavadoc = ignoreJavadoc;
+ }
+
+ private ModuleBuildInfo(List ignore, Boolean ignoreJavadoc) {
+ this.ignore = ignore;
+ this.ignoreJavadoc = ignoreJavadoc;
+ }
+
+ public boolean isIgnore(Artifact attached) {
+ Path path = Paths.get(attached.getGroupId() + '/' + getArtifactFilename(attached));
+ return ignore.stream().anyMatch(m -> m.matches(path));
+ }
+
+ /**
+ * It's possible for the plugin to be executed in different classloaders for different modules, so because
+ * we're storing data in the session for use by different modules (i.e. the individual modules, and at the end
+ * the aggregator module), we can't store a class specific to this plugin. Use primitives/jdk classes.
+ */
+ @SuppressWarnings("rawtypes")
+ public void store(Map pluginContext) {
+ synchronized (pluginContext) {
+ pluginContext.put(MODULE_BUILD_INFO_KEY, new Object[] {ignore, ignoreJavadoc});
+ }
+ }
}
}
diff --git a/src/main/java/org/apache/maven/plugins/artifact/buildinfo/CompareMojo.java b/src/main/java/org/apache/maven/plugins/artifact/buildinfo/CompareMojo.java
index 9cfd262..5da2ef7 100644
--- a/src/main/java/org/apache/maven/plugins/artifact/buildinfo/CompareMojo.java
+++ b/src/main/java/org/apache/maven/plugins/artifact/buildinfo/CompareMojo.java
@@ -100,7 +100,7 @@ public class CompareMojo extends AbstractBuildinfoMojo {
private boolean fail;
@Override
- public void execute(Map artifacts) throws MojoExecutionException {
+ void execute(Map artifacts) throws MojoExecutionException {
getLog().info("Checking against reference build from " + referenceRepo + "...");
checkAgainstReference(artifacts, session.getProjects().size() == 1);
}
diff --git a/src/main/java/org/apache/maven/plugins/artifact/buildinfo/DescribeBuildOutputMojo.java b/src/main/java/org/apache/maven/plugins/artifact/buildinfo/DescribeBuildOutputMojo.java
index 88f6681..8284ad1 100644
--- a/src/main/java/org/apache/maven/plugins/artifact/buildinfo/DescribeBuildOutputMojo.java
+++ b/src/main/java/org/apache/maven/plugins/artifact/buildinfo/DescribeBuildOutputMojo.java
@@ -60,6 +60,7 @@ public void execute() throws MojoExecutionException {
diagnose(outputTimestamp, getLog(), project, session.getProjects(), effective);
getLog().info("");
+ initModuleBuildInfo();
describeBuildOutput();
}
@@ -142,13 +143,16 @@ private void describeBuildOutput() throws MojoExecutionException {
}
private boolean isIgnore(Artifact a) {
+ // because this is an aggregator mojo it only runs in the aggregator project so it's the only
+ // one that will have `ModuleBuildInfo` available (i.e. none of the other session.projects
+ // will have it).
if (a.getExtension().endsWith(".asc")) {
return true;
}
- if (bi.getIgnoreJavadoc() && "javadoc".equals(a.getClassifier())) {
+ if (bi.getIgnoreJavadoc(project) && "javadoc".equals(a.getClassifier())) {
return true;
}
- return bi.isIgnore(a);
+ return bi.isIgnore(project, a);
}
private String describeArtifact(Artifact a) throws MojoExecutionException {