You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by hb...@apache.org on 2022/04/01 17:29:03 UTC
[maven-artifact-plugin] branch MARTIFACT-24 updated: add project.build.outputTimestamp check
This is an automated email from the ASF dual-hosted git repository.
hboutemy pushed a commit to branch MARTIFACT-24
in repository https://gitbox.apache.org/repos/asf/maven-artifact-plugin.git
The following commit(s) were added to refs/heads/MARTIFACT-24 by this push:
new 2fd0c4d add project.build.outputTimestamp check
2fd0c4d is described below
commit 2fd0c4d68ebb1abdcd2a791aacfb99cc1c4e777a
Author: Hervé Boutemy <hb...@apache.org>
AuthorDate: Fri Apr 1 19:29:01 2022 +0200
add project.build.outputTimestamp check
---
pom.xml | 2 +-
.../artifact/buildinfo/AbstractBuildinfoMojo.java | 6 +-
.../artifact/buildinfo/CheckBuildPlanMojo.java | 69 +++++++++++++++++++++-
3 files changed, 71 insertions(+), 6 deletions(-)
diff --git a/pom.xml b/pom.xml
index 0bffa4a..cc25afb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -30,7 +30,7 @@
</parent>
<artifactId>maven-artifact-plugin</artifactId>
- <version>3.2.1-SNAPSHOT</version>
+ <version>3.3.0-SNAPSHOT</version>
<packaging>maven-plugin</packaging>
<name>Apache Maven Artifact Plugin</name>
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 ae0afc3..ab29a35 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
@@ -146,17 +146,19 @@ public abstract class AbstractBuildinfoMojo
}
// check if timestamp well defined in a project from reactor
+ boolean parentInReactor = false;
MavenProject reactorParent = project;
while ( reactorProjects.contains( reactorParent.getParent() ) )
{
+ parentInReactor = true;
reactorParent = reactorParent.getParent();
}
String prop =
reactorParent.getOriginalModel().getProperties().getProperty( "project.build.outputTimestamp" );
if ( prop == null )
{
- getLog().warn( "project.build.outputTimestamp property should not be inherited "
- + "but defined in parent POM from reactor " + reactorParent.getFile() );
+ getLog().error( "project.build.outputTimestamp property should not be inherited but defined in "
+ + ( parentInReactor ? "parent POM from reactor " : "POM " ) + reactorParent.getFile() );
}
}
diff --git a/src/main/java/org/apache/maven/plugins/artifact/buildinfo/CheckBuildPlanMojo.java b/src/main/java/org/apache/maven/plugins/artifact/buildinfo/CheckBuildPlanMojo.java
index 0ff366e..983563e 100644
--- a/src/main/java/org/apache/maven/plugins/artifact/buildinfo/CheckBuildPlanMojo.java
+++ b/src/main/java/org/apache/maven/plugins/artifact/buildinfo/CheckBuildPlanMojo.java
@@ -21,11 +21,15 @@ package org.apache.maven.plugins.artifact.buildinfo;
import java.io.IOException;
import java.io.InputStream;
+import java.text.SimpleDateFormat;
+import java.util.Date;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
+import org.apache.maven.archiver.MavenArchiver;
import org.apache.maven.artifact.versioning.ArtifactVersion;
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import org.apache.maven.execution.MavenSession;
@@ -42,11 +46,16 @@ import org.apache.maven.project.MavenProject;
/**
* Check from buildplan that plugins used don't have known reproducible builds issues.
+ *
+ * @since 3.3.0
*/
@Mojo( name = "check-buildplan", threadSafe = true, requiresProject = true )
public class CheckBuildPlanMojo
extends AbstractMojo
{
+ @Parameter( defaultValue = "${reactorProjects}", required = true, readonly = true )
+ private List<MavenProject> reactorProjects;
+
@Parameter( defaultValue = "${project}", readonly = true )
private MavenProject project;
@@ -60,6 +69,14 @@ public class CheckBuildPlanMojo
@Parameter( property = "buildplan.tasks", defaultValue = "deploy" )
private String[] tasks;
+ /**
+ * Timestamp for reproducible output archive entries, either formatted as ISO 8601
+ * <code>yyyy-MM-dd'T'HH:mm:ssXXX</code> or as an int representing seconds since the epoch (like
+ * <a href="https://reproducible-builds.org/docs/source-date-epoch/">SOURCE_DATE_EPOCH</a>).
+ */
+ @Parameter( defaultValue = "${project.build.outputTimestamp}" )
+ private String outputTimestamp;
+
protected MavenExecutionPlan calculateExecutionPlan()
throws MojoExecutionException
{
@@ -77,12 +94,14 @@ public class CheckBuildPlanMojo
public void execute()
throws MojoExecutionException
{
+ boolean fail = hasBadOutputTimestamp();
+ // TODO check maven-jar-plugin module-info.class?
+
Properties issues = loadIssues();
MavenExecutionPlan plan = calculateExecutionPlan();
Set<String> plugins = new HashSet<>();
- boolean fail = false;
for ( MojoExecution exec : plan.getMojoExecutions() )
{
Plugin plugin = exec.getPlugin();
@@ -121,17 +140,61 @@ public class CheckBuildPlanMojo
{
getLog().info( "current module pom.xml is " + project.getBasedir() + "/pom.xml" );
MavenProject parent = project;
- while ( ( parent = parent.getParent() ) != null )
+ while ( true )
{
+ parent = parent.getParent();
+ if ( ( parent == null ) || !reactorProjects.contains( parent ) )
+ {
+ break;
+ }
getLog().info( " parent pom.xml is " + parent.getBasedir() + "/pom.xml" );
}
- throw new MojoExecutionException( "plugin with non-reproducible output found with fix available" );
+ throw new MojoExecutionException( "non-reproducible plugin or configuration found with fix available" );
+ }
+ }
+
+ private boolean hasBadOutputTimestamp()
+ {
+ MavenArchiver archiver = new MavenArchiver();
+ Date timestamp = archiver.parseOutputTimestamp( outputTimestamp );
+ if ( timestamp == null )
+ {
+ getLog().error( "Reproducible Build not activated by project.build.outputTimestamp property: "
+ + "see https://maven.apache.org/guides/mini/guide-reproducible-builds.html" );
+ return true;
+ }
+ else
+ {
+ if ( getLog().isDebugEnabled() )
+ {
+ getLog().debug( "project.build.outputTimestamp = \"" + outputTimestamp + "\" => "
+ + new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ssXXX" ).format( timestamp ) );
+ }
+
+ // check if timestamp well defined in a project from reactor
+ boolean parentInReactor = false;
+ MavenProject reactorParent = project;
+ while ( reactorProjects.contains( reactorParent.getParent() ) )
+ {
+ parentInReactor = true;
+ reactorParent = reactorParent.getParent();
+ }
+ String prop =
+ reactorParent.getOriginalModel().getProperties().getProperty( "project.build.outputTimestamp" );
+ if ( prop == null )
+ {
+ getLog().error( "project.build.outputTimestamp property should not be inherited but defined in "
+ + ( parentInReactor ? "parent POM from reactor " : "POM " ) + reactorParent.getFile() );
+ return true;
+ }
}
+ return false;
}
private Properties loadIssues()
throws MojoExecutionException
{
+ // TODO add issues source override, that downloads from GitHub (disabled by default)
try ( InputStream in = getClass().getResourceAsStream( "not-reproducible-plugins.properties" ) )
{
Properties prop = new Properties();