blob: f745b8d2ea6b117780701d5ee5429a6921af0a63 [file] [log] [blame]
package org.apache.maven.plugins.wrapper;
/*
* 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 java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Map;
import java.util.Properties;
import javax.inject.Inject;
import org.apache.maven.Maven;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.DefaultProjectBuildingRequest;
import org.apache.maven.project.ProjectBuildingRequest;
import org.apache.maven.shared.transfer.artifact.DefaultArtifactCoordinate;
import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolver;
import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolverException;
import org.codehaus.plexus.archiver.UnArchiver;
import org.codehaus.plexus.components.io.fileselectors.FileSelector;
import static org.apache.maven.shared.utils.logging.MessageUtils.buffer;
/**
* Unpacks the maven-wrapper distribution files to the current project source tree.
*
* @author Robert Scholte
* @since 3.0.0
*/
@Mojo( name = "wrapper", aggregator = true, requiresDirectInvocation = true )
public class WrapperMojo extends AbstractMojo
{
// CONFIGURATION PARAMETERS
/**
* The version of Maven to require, default value is the Runtime version of Maven.
* Can be any valid release above 2.0.9
*/
@Parameter( property = "mavenVersion" )
private String mavenVersion;
/**
* Options are:
* <dl>
* <dt>script (default)</dt>
* <dd>only mvnw scripts</dd>
* <dt>bin</dt>
* <dd>precompiled and packaged code</dd>
* <dt>source</dt>
* <dd>sourcecode, will be compiled on the fly</dd>
* </dl>
*
* Value will be used as classifier of the downloaded file
*/
@Parameter( defaultValue = "script", property = "type" )
private String distributionType;
@Parameter( defaultValue = "true", property = "includeDebug" )
private boolean includeDebugScript;
// READONLY PARAMETERS
@Parameter( defaultValue = "${session}", readonly = true, required = true )
private MavenSession session;
// Waiting for org.codehaus.plexus.component.configurator.converters.basic.PathConverter
@Parameter( defaultValue = "${project.basedir}", readonly = true, required = true )
private File basedir;
// CONSTANTS
private static final String WRAPPER_DISTRIBUTION_GROUP_ID = "org.apache.maven.wrapper";
private static final String WRAPPER_DISTRIBUTION_ARTIFACT_ID = "maven-wrapper-distribution";
private static final String WRAPPER_DISTRIBUTION_EXTENSION = "zip";
// COMPONENTS
@Inject
private ArtifactResolver artifactResolver;
@Inject
private Map<String, UnArchiver> unarchivers;
@Override
public void execute() throws MojoExecutionException, MojoFailureException
{
String wrapperVersion = getVersion( null, this.getClass(), "org.apache.maven.plugins/maven-wrapper-plugin" );
Artifact artifact;
try
{
artifact = downloadWrapperDistribution( wrapperVersion );
}
catch ( ArtifactResolverException e )
{
throw new MojoExecutionException( e.getMessage(), e );
}
try
{
unpack( artifact, basedir.toPath() );
getLog().info( "Unpacked " + buffer().strong( distributionType ) + " type wrapper distribution "
+ artifact );
}
catch ( IOException e )
{
throw new MojoExecutionException( e.getMessage(), e );
}
mavenVersion = getVersion( mavenVersion, Maven.class, "org.apache.maven/maven-core" );
try
{
replaceProperties( Files.createDirectories( basedir.toPath().resolve( ".mvn/wrapper" ) ) );
}
catch ( IOException e )
{
throw new MojoExecutionException( "can't create maven-wrapper.properties", e );
}
}
private Artifact downloadWrapperDistribution( String wrapperVersion )
throws ArtifactResolverException
{
ProjectBuildingRequest buildingRequest =
new DefaultProjectBuildingRequest( session.getProjectBuildingRequest() );
DefaultArtifactCoordinate coordinate = new DefaultArtifactCoordinate();
coordinate.setGroupId( WRAPPER_DISTRIBUTION_GROUP_ID );
coordinate.setArtifactId( WRAPPER_DISTRIBUTION_ARTIFACT_ID );
coordinate.setVersion( wrapperVersion );
coordinate.setClassifier( distributionType );
coordinate.setExtension( WRAPPER_DISTRIBUTION_EXTENSION );
return artifactResolver.resolveArtifact( buildingRequest, coordinate ).getArtifact();
}
private void unpack( Artifact artifact, Path targetFolder ) throws IOException
{
targetFolder = Files.createDirectories( targetFolder );
UnArchiver unarchiver = unarchivers.get( WRAPPER_DISTRIBUTION_EXTENSION );
unarchiver.setDestDirectory( targetFolder.toFile() );
unarchiver.setSourceFile( artifact.getFile() );
if ( !includeDebugScript )
{
unarchiver.setFileSelectors( new FileSelector[]
{
f -> !f.getName().contains( "Debug" )
} );
}
unarchiver.extract();
}
/**
* As long as the content only contains the license and the distributionUrl, we can simply replace it.
* No need to look for other properties, restore them, respecting comments, etc.
*
* @param targetFolder the folder containing the wrapper.properties
* @throws IOException if writing fails
*/
private void replaceProperties( Path targetFolder ) throws IOException
{
String repoUrl = "https://repo.maven.apache.org/maven2";
String distributionUrl =
repoUrl + "/org/apache/maven/apache-maven/" + mavenVersion + "/apache-maven-" + mavenVersion + "-bin.zip";
Path wrapperPropertiesFile = targetFolder.resolve( "maven-wrapper.properties" );
getLog().info( "Configuring .mvn/wrapper/maven-wrapper.properties to use "
+ buffer().strong( "Maven " + mavenVersion ) + " and download from " + repoUrl );
final String license = "# Licensed to the Apache Software Foundation (ASF) under one\n"
+ "# or more contributor license agreements. See the NOTICE file\n"
+ "# distributed with this work for additional information\n"
+ "# regarding copyright ownership. The ASF licenses this file\n"
+ "# to you under the Apache License, Version 2.0 (the\n"
+ "# \"License\"); you may not use this file except in compliance\n"
+ "# with the License. You may obtain a copy of the License at\n"
+ "# \n"
+ "# http://www.apache.org/licenses/LICENSE-2.0\n"
+ "# \n"
+ "# Unless required by applicable law or agreed to in writing,\n"
+ "# software distributed under the License is distributed on an\n"
+ "# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n"
+ "# KIND, either express or implied. See the License for the\n"
+ "# specific language governing permissions and limitations\n"
+ "# under the License.\n";
try ( BufferedWriter out = Files.newBufferedWriter( wrapperPropertiesFile ) )
{
out.append( license );
out.append( "distributionUrl=" + distributionUrl + "\n" );
}
}
private String getVersion( String defaultVersion, Class<?> clazz, String path )
{
String version = defaultVersion;
if ( version == null )
{
Properties props = new Properties();
try ( InputStream is =
clazz.getResourceAsStream( "/META-INF/maven/" + path + "/pom.properties" ) )
{
props.load( is );
version = props.getProperty( "version" );
}
catch ( IOException e )
{
// noop
}
}
return version;
}
}