package org.codehaus.mojo.build; /** * The MIT License * * Copyright (c) 2015 Codehaus * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and * associated documentation files (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, publish, distribute, * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or * substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.TimeZone; import org.apache.maven.model.Resource; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.annotations.Component; 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.MavenProjectHelper; import org.apache.maven.scm.ScmException; import org.codehaus.plexus.util.StringUtils; /** * This mojo discovers latest SCM revision, current timestamp, project version, and project name then write them to one * or more java property files together with a set of user provided properties. It also has option to add the output * file to resource classpath for jar packaging. */ @Mojo( name = "create-metadata", defaultPhase = LifecyclePhase.GENERATE_RESOURCES, requiresProject = true, threadSafe = true, aggregator = true ) public class CreateMetadataMojo extends AbstractScmMojo { /** * Application name * * @since 1.4 */ @Parameter( defaultValue = "${project.name}" ) private String applicationName; /** * Java property name to store the project name * * @since 1.4 */ @Parameter( defaultValue = "name" ) private String applicationPropertyName; /** * Java property name to store the project version * * @since 1.4 */ @Parameter( defaultValue = "version" ) private String versionPropertyName; /** * Version * * @since 1.4 */ @Parameter( defaultValue = "${project.version}" ) private String version; /** * Java property name to store the discovered SCM revision value * * @since 1.4 */ @Parameter( defaultValue = "revision" ) private String revisionPropertyName; /** * Java property name to store the discovered timestamp value * * @since 1.4 */ @Parameter( defaultValue = "timestamp" ) private String timestampPropertyName; /** * java.text.SimpleDateFormat for the discover timestamp, if not given use long integer format * * @since 1.4 */ @Parameter( property = "maven.build.timestamp.format" ) private String timestampFormat; /** * The timezone of the generated timestamp. If blank will default to {@link TimeZone#getDefault()} */ @Parameter( property = "maven.buildNumber.timestampTimeZone", defaultValue = "" ) private String timezone; /** * Output directory * * @since 1.4 */ @Parameter( defaultValue = "${project.build.directory}/generated/build-metadata", required = true ) private File outputDirectory; /** * Output file name * * @since 1.4 */ @Parameter( defaultValue = "build.properties", required = true ) private String outputName; /** * Add outputDirectory to java resource so that <i>outputName</i> will be under runtime classpath. <i>outputName</i> * can contain '/' * * @since 1.4 */ @Parameter( defaultValue = "false" ) private boolean addOutputDirectoryToResources; /** * Install/Deploy to Maven repository * * @since 1.4 */ @Parameter( defaultValue = "false" ) private boolean attach; /** * Artifact classifier name when deploying to Maven repository * * @since 3.0 */ @Parameter( defaultValue = "build" ) private String classifier; /** * Additional output files * * @since 1.4 */ @Parameter private List<File> outputFiles = new ArrayList<File>(); /** * Additional properties to write out * * @since 1.4 */ @Parameter private Map<String, String> properties = new HashMap<String, String>(); /** * Enable output format detection. (Disabled per default for compatibility.) * * @since 3.0 */ @Parameter( defaultValue = "false" ) private boolean autoDetectOutputFormat; /** * Maven ProjectHelper. */ @Component private MavenProjectHelper projectHelper; public void execute() throws MojoExecutionException, MojoFailureException { if ( skip ) { getLog().info( "Skipping execution." ); return; } Properties props = new Properties(); props.put( this.applicationPropertyName, applicationName ); props.put( this.versionPropertyName, version ); props.put( this.timestampPropertyName, Utils.createTimestamp( this.timestampFormat, timezone ) ); props.put( this.revisionPropertyName, this.getRevision() ); for ( String key : properties.keySet() ) { props.put( key, properties.get( key ) ); } File outputFile = new File( outputDirectory, outputName ); outputFiles.add( outputFile ); for ( File file : outputFiles ) { file.getParentFile().mkdirs(); writeToFile( props, file ); } if ( attach ) { projectHelper.attachArtifact( this.project, "properties", this.classifier, outputFile ); } if ( this.addOutputDirectoryToResources ) { Resource resource = new Resource(); resource.setDirectory( outputDirectory.getAbsolutePath() ); project.addResource( resource ); } } private void writeToFile( Properties props, File file ) throws MojoFailureException { try { if ( this.autoDetectOutputFormat ) { OutputFormat outputFormat = OutputFormat.getOutputFormatFor( file.getName() ); writeToFile( props, file, outputFormat ); } else { writeToFile( props, file, OutputFormat.DEFAULT_FORMAT ); } } catch ( IOException e ) { throw new MojoFailureException( "Unable to store output to " + file, e ); } } private void writeToFile( Properties props, File file, OutputFormat outputFormat ) throws IOException { OutputStream out = new FileOutputStream( file ); try { outputFormat.write( props, out ); } finally { out.close(); } } public String getRevision() throws MojoExecutionException { try { return this.getScmRevision(); } catch ( ScmException e ) { if ( !StringUtils.isEmpty( revisionOnScmFailure ) ) { getLog().warn( "Cannot get the revision information from the scm repository, proceeding with " + "revision of " + revisionOnScmFailure + " : \n" + e.getLocalizedMessage() ); return revisionOnScmFailure; } throw new MojoExecutionException( "Cannot get the revision information from the scm repository : \n" + e.getLocalizedMessage(), e ); } } }