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 2019/12/04 17:03:56 UTC

[maven-studies] branch maven-buildinfo-plugin created (now ce60e77)

This is an automated email from the ASF dual-hosted git repository.

hboutemy pushed a change to branch maven-buildinfo-plugin
in repository https://gitbox.apache.org/repos/asf/maven-studies.git.


      at ce60e77  initial implementation

This branch includes the following new commits:

     new ce60e77  initial implementation

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[maven-studies] 01/01: initial implementation

Posted by hb...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

hboutemy pushed a commit to branch maven-buildinfo-plugin
in repository https://gitbox.apache.org/repos/asf/maven-studies.git

commit ce60e77a1069600aa3550fa68472dcda8b3126d8
Author: Hervé Boutemy <hb...@apache.org>
AuthorDate: Wed Dec 4 18:02:44 2019 +0100

    initial implementation
---
 .gitignore                                         |  15 ++
 pom.xml                                            | 149 +++++++++++++++++++
 src/it/mono/pom.xml                                |  53 +++++++
 src/it/mono/verify.groovy                          |  23 +++
 src/it/settings.xml                                |  55 ++++++++
 .../maven/plugins/buildinfo/MavenVersion.java      | 103 ++++++++++++++
 .../apache/maven/plugins/buildinfo/SaveMojo.java   | 157 +++++++++++++++++++++
 7 files changed, 555 insertions(+)

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..f79c928
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,15 @@
+target/
+.project
+.classpath
+.settings/
+.svn/
+bin/
+# Intellij
+*.ipr
+*.iml
+.idea
+out/
+.DS_Store
+/bootstrap
+/dependencies.xml
+.java-version
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..0e0df6b
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,149 @@
+<?xml version='1.0' encoding='UTF-8'?>
+
+<!--
+  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 xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <artifactId>maven-plugins</artifactId>
+    <groupId>org.apache.maven.plugins</groupId>
+    <version>33</version>
+    <relativePath>../../pom/maven/maven-plugins/pom.xml</relativePath>
+  </parent>
+
+  <artifactId>maven-buildinfo-plugin</artifactId>
+  <version>1.0-SNAPSHOT</version>
+  <packaging>maven-plugin</packaging>
+
+  <name>Apache Maven Buildinfo Plugin</name>
+  <description>Plugin to manage Reproducible Builds buildinfo file</description>
+
+  <prerequisites>
+    <maven>${maven.version}</maven>
+  </prerequisites>
+
+  <scm>
+    <connection>scm:git:https://gitbox.apache.org/repos/asf/maven-studies.git</connection>
+    <developerConnection>scm:git:https://gitbox.apache.org/repos/asf/maven-studies.git</developerConnection>
+    <url>https://github.com/apache/maven-studies/tree/${project.scm.tag}</url>
+    <tag>maven-buildinfo-plugin</tag>
+  </scm>
+  <!-->issueManagement>
+    <system>JIRA</system>
+    <url>https://issues.apache.org/jira/browse/MJAR</url>
+  </issueManagement>
+  <ciManagement>
+    <system>Jenkins</system>
+    <url>https://builds.apache.org/job/maven-box/job/maven-jar-plugin/</url>
+  </ciManagement-->
+  <distributionManagement>
+    <site>
+      <id>apache.website</id>
+      <url>scm:svn:https://svn.apache.org/repos/asf/maven/website/components/${maven.site.path}</url>
+    </site>
+  </distributionManagement>
+
+  <properties>
+    <mavenVersion>3.0</mavenVersion>
+    <javaVersion>7</javaVersion>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-plugin-api</artifactId>
+      <version>${mavenVersion}</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-core</artifactId>
+      <version>${mavenVersion}</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-embedder</artifactId>
+      <version>${mavenVersion}</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-artifact</artifactId>
+      <version>${mavenVersion}</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.codehaus.plexus</groupId>
+      <artifactId>plexus-utils</artifactId>
+      <version>3.3.0</version>
+    </dependency>
+    <dependency>
+      <groupId>commons-codec</groupId>
+      <artifactId>commons-codec</artifactId>
+      <version>1.13</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-compat</artifactId>
+      <version>${mavenVersion}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven.plugin-tools</groupId>
+      <artifactId>maven-plugin-annotations</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <!--dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>4.12</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven.plugin-testing</groupId>
+      <artifactId>maven-plugin-testing-harness</artifactId>
+      <version>3.3.0</version>
+      <scope>test</scope>
+    </dependency-->
+  </dependencies>
+
+  <profiles>
+    <profile>
+      <id>run-its</id>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-invoker-plugin</artifactId>
+            <configuration>
+              <goals>
+                <goal>verify</goal>
+              </goals>
+              <debug>false</debug>
+            </configuration>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+  </profiles>
+</project>
diff --git a/src/it/mono/pom.xml b/src/it/mono/pom.xml
new file mode 100644
index 0000000..2a53532
--- /dev/null
+++ b/src/it/mono/pom.xml
@@ -0,0 +1,53 @@
+<?xml version='1.0' encoding='UTF-8'?>
+
+<!--
+  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 xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <groupId>org.apache.maven.plugins.it</groupId>
+  <artifactId>mono</artifactId>
+  <version>1.0-SNAPSHOT</version>
+
+  <description>A simple IT verifying the basic use case of buildinfo file for mono-module build.</description>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <project.build.outputTimestamp>2019-12-03T10:04:00Z</project.build.outputTimestamp>
+  </properties>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>@project.groupId@</groupId>
+        <artifactId>@project.artifactId@</artifactId>
+        <version>@project.version@</version>
+        <executions>
+          <execution>
+            <goals>
+              <goal>save</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/src/it/mono/verify.groovy b/src/it/mono/verify.groovy
new file mode 100644
index 0000000..ae5e49a
--- /dev/null
+++ b/src/it/mono/verify.groovy
@@ -0,0 +1,23 @@
+
+/*
+ * 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.
+ */
+
+File touchFile = new File( basedir, "target/buildinfo" );
+
+assert touchFile.isFile()
diff --git a/src/it/settings.xml b/src/it/settings.xml
new file mode 100644
index 0000000..43a94d4
--- /dev/null
+++ b/src/it/settings.xml
@@ -0,0 +1,55 @@
+<?xml version='1.0' encoding='UTF-8'?>
+
+<!--
+  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.
+-->
+
+<settings>
+  <profiles>
+    <profile>
+      <id>it-repo</id>
+      <activation>
+        <activeByDefault>true</activeByDefault>
+      </activation>
+      <repositories>
+        <repository>
+          <id>local.central</id>
+          <url>@localRepositoryUrl@</url>
+          <releases>
+            <enabled>true</enabled>
+          </releases>
+          <snapshots>
+            <enabled>true</enabled>
+          </snapshots>
+        </repository>
+      </repositories>
+      <pluginRepositories>
+        <pluginRepository>
+          <id>local.central</id>
+          <url>@localRepositoryUrl@</url>
+          <releases>
+            <enabled>true</enabled>
+          </releases>
+          <snapshots>
+            <enabled>true</enabled>
+          </snapshots>
+        </pluginRepository>
+      </pluginRepositories>
+    </profile>
+  </profiles>
+</settings>
diff --git a/src/main/java/org/apache/maven/plugins/buildinfo/MavenVersion.java b/src/main/java/org/apache/maven/plugins/buildinfo/MavenVersion.java
new file mode 100644
index 0000000..8c8df52
--- /dev/null
+++ b/src/main/java/org/apache/maven/plugins/buildinfo/MavenVersion.java
@@ -0,0 +1,103 @@
+package org.apache.maven.plugins.buildinfo;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.cli.MavenCli;
+import org.codehaus.plexus.util.StringUtils;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Properties;
+
+/**
+ * Helper to calculate the full Maven version string, as done in Maven Core
+ * in CLIReportingUtils.
+ * @see org.apache.maven.cli.CLIReportingUtils
+ */
+public class MavenVersion
+{
+    static String createMavenVersionString()
+    {
+        return createMavenVersionString( getBuildProperties() );
+    }
+
+    /**
+     * Create a human readable string containing the Maven version, buildnumber, and time of build
+     *
+     * @param buildProperties The build properties
+     * @return Readable build info
+     */
+    private static String createMavenVersionString( Properties buildProperties )
+    {
+        String timestamp = reduce( buildProperties.getProperty( "timestamp" ) );
+        String version = reduce( buildProperties.getProperty( "version" ) );
+        String rev = reduce( buildProperties.getProperty( "buildNumber" ) );
+        String distributionName = reduce( buildProperties.getProperty( "distributionName" ) );
+
+        String msg = distributionName + " ";
+        msg += ( version != null ? version : "<version unknown>" );
+        if ( rev != null || timestamp != null )
+        {
+            msg += " (";
+            msg += ( rev != null ? rev : "" );
+            if ( StringUtils.isNotBlank( timestamp ) )
+            {
+                String ts = formatTimestamp( Long.valueOf( timestamp ) );
+                msg += ( rev != null ? "; " : "" ) + ts;
+            }
+            msg += ")";
+        }
+        return msg;
+    }
+
+    private static String reduce( String s )
+    {
+        return ( s != null ? ( s.startsWith( "${" ) && s.endsWith( "}" ) ? null : s ) : null );
+    }
+
+    private static Properties getBuildProperties()
+    {
+        Properties properties = new Properties();
+
+        try ( InputStream resourceAsStream = MavenCli.class.getResourceAsStream(
+                "/org/apache/maven/messages/build.properties" ) )
+        {
+
+            if ( resourceAsStream != null )
+            {
+                properties.load( resourceAsStream );
+            }
+        }
+        catch ( IOException e )
+        {
+            System.err.println( "Unable determine version from JAR file: " + e.getMessage() );
+        }
+
+        return properties;
+    }
+
+    public static String formatTimestamp( long timestamp )
+    {
+        SimpleDateFormat sdf = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ssXXX" );
+        return sdf.format( new Date( timestamp ) );
+    }
+}
diff --git a/src/main/java/org/apache/maven/plugins/buildinfo/SaveMojo.java b/src/main/java/org/apache/maven/plugins/buildinfo/SaveMojo.java
new file mode 100644
index 0000000..776e0d8
--- /dev/null
+++ b/src/main/java/org/apache/maven/plugins/buildinfo/SaveMojo.java
@@ -0,0 +1,157 @@
+package org.apache.maven.plugins.buildinfo;
+
+/*
+ * 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.
+ */
+
+import org.apache.commons.codec.binary.Hex;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.project.MavenProject;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.List;
+
+/**
+ * Save buildinfo file, as specified in
+ * <a href="https://reproducible-builds.org/docs/jvm/">Reproducible Builds for the JVM</a>.
+ */
+@Mojo( name = "save", defaultPhase = LifecyclePhase.VERIFY )
+public class SaveMojo
+    extends AbstractMojo
+{
+    /**
+     * The Maven project.
+     */
+    @Parameter( defaultValue = "${project}", readonly = true )
+    protected MavenProject project;
+
+    /**
+     * The reactor projects.
+     */
+    @Parameter( defaultValue = "${reactorProjects}", required = true, readonly = true )
+    protected List<MavenProject> reactorProjects;
+
+    /**
+     * Location of the buildinfo file.
+     */
+    @Parameter( defaultValue = "${project.build.directory}/buildinfo", required = true )
+    private File buildinfoFile;
+
+    public void execute() throws MojoExecutionException
+    {
+        try ( PrintWriter p = new PrintWriter( new BufferedWriter( new FileWriter( buildinfoFile ) ) ) )
+        {
+            p.println( "buildinfo.version=1.0-SNAPSHOT" );
+            p.println();
+            p.println( "name=" + project.getName() );
+            p.println( "group-id=" + project.getGroupId() );
+            p.println( "artifact-id=" + project.getArtifactId() );
+            p.println( "version=" + project.getVersion() );
+            p.println();
+            p.println( "# source information" );
+            p.println( "# TBD source.* artifact, url, scm.uri, scm.tag: what part is automatic or parameter?" );
+            p.println();
+            p.println( "# build instructions" );
+            p.println( "build-tool=mvn" );
+            p.println( "# optional build setup url, as plugin parameter" );
+            p.println();
+            p.println( "# effective build environment information" );
+            p.println( "java.version=" + System.getProperty( "java.version" ) );
+            p.println( "java.vendor=" + System.getProperty( "java.vendor" ) );
+            p.println( "os.name=" + System.getProperty( "os.name" ) );
+            p.println( "os.arch=" + System.getProperty( "os.arch" ) );
+            p.println( "os.version=" + System.getProperty( "os.version" ) );
+            p.println( "source.used= TBD" );
+            p.println();
+            p.println( "# Maven rebuild instructions and effective environment" );
+            p.println( "mvn.rebuild-args=package" );
+            p.println( "mvn.version=" + MavenVersion.createMavenVersionString() );
+            p.println();
+            printOutput( p );
+
+            getLog().info( "Saved info on build to " + buildinfoFile );
+        }
+        catch ( IOException e )
+        {
+            throw new MojoExecutionException( "Error creating file " + buildinfoFile, e );
+        }
+    }
+
+    private void printOutput( PrintWriter p )
+            throws MojoExecutionException
+    {
+        p.println( "# output" );
+
+        printArtifact( p, 0, project.getArtifact() );
+
+        int n = 1;
+        for ( Artifact attached : project.getAttachedArtifacts() )
+        {
+            printArtifact( p, n++, attached );
+        }
+    }
+
+    private void printArtifact( PrintWriter p, int i, Artifact artifact )
+            throws MojoExecutionException
+    {
+        File file = artifact.getFile();
+        p.println( "outputs." + i + ".filename=" + file.getName() );
+        p.println( "outputs." + i + ".length=" + file.length() );
+        p.println( "outputs." + i + ".checksums.sha512=" + calculateSha512( file ) );
+    }
+
+    private String calculateSha512( File file )
+            throws MojoExecutionException
+    {
+        try ( FileInputStream fis = new FileInputStream( file ) )
+        {
+            MessageDigest messageDigest = MessageDigest.getInstance( "sha-512" );
+
+            byte[] buffer = new byte[16 * 1024];
+            int size = fis.read( buffer, 0, buffer.length );
+            while ( size >= 0 )
+            {
+                messageDigest.update( buffer, 0, size );
+                size = fis.read( buffer, 0, buffer.length );
+            }
+
+            return Hex.encodeHexString( messageDigest.digest() );
+        }
+        catch ( IOException ioe )
+        {
+            throw new MojoExecutionException( "Error opening file " + file, ioe );
+        }
+        catch ( NoSuchAlgorithmException nsae )
+        {
+            throw new MojoExecutionException( "Could not get hash algorithm", nsae );
+        }
+    }
+}