You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by ol...@apache.org on 2011/11/08 13:46:26 UTC
svn commit: r1199219 - in /maven/archetype/trunk/maven-archetype-plugin/src:
it/build-archetype/pom.xml
main/java/org/apache/maven/archetype/mojos/IntegrationTestMojo.java
Author: olamy
Date: Tue Nov 8 12:46:26 2011
New Revision: 1199219
URL: http://svn.apache.org/viewvc?rev=1199219&view=rev
Log:
[ARCHETYPE-389] add some various options to improve how Maven is invoked in IntegrationTestMojo
feature to be able an interpolated settings.xml as in the invoker plugin.
Modified:
maven/archetype/trunk/maven-archetype-plugin/src/it/build-archetype/pom.xml
maven/archetype/trunk/maven-archetype-plugin/src/main/java/org/apache/maven/archetype/mojos/IntegrationTestMojo.java
Modified: maven/archetype/trunk/maven-archetype-plugin/src/it/build-archetype/pom.xml
URL: http://svn.apache.org/viewvc/maven/archetype/trunk/maven-archetype-plugin/src/it/build-archetype/pom.xml?rev=1199219&r1=1199218&r2=1199219&view=diff
==============================================================================
--- maven/archetype/trunk/maven-archetype-plugin/src/it/build-archetype/pom.xml (original)
+++ maven/archetype/trunk/maven-archetype-plugin/src/it/build-archetype/pom.xml Tue Nov 8 12:46:26 2011
@@ -45,6 +45,11 @@ under the License.
<plugin>
<artifactId>maven-archetype-plugin</artifactId>
<version>@project.version@</version>
+ <configuration>
+ <settingsFile>${basedir}/test-settings.xml</settingsFile>
+ <localRepositoryPath>${basedir}/target/local-repo</localRepositoryPath>
+ </configuration>
+
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
Modified: maven/archetype/trunk/maven-archetype-plugin/src/main/java/org/apache/maven/archetype/mojos/IntegrationTestMojo.java
URL: http://svn.apache.org/viewvc/maven/archetype/trunk/maven-archetype-plugin/src/main/java/org/apache/maven/archetype/mojos/IntegrationTestMojo.java?rev=1199219&r1=1199218&r2=1199219&view=diff
==============================================================================
--- maven/archetype/trunk/maven-archetype-plugin/src/main/java/org/apache/maven/archetype/mojos/IntegrationTestMojo.java (original)
+++ maven/archetype/trunk/maven-archetype-plugin/src/main/java/org/apache/maven/archetype/mojos/IntegrationTestMojo.java Tue Nov 8 12:46:26 2011
@@ -29,6 +29,7 @@ import org.apache.maven.plugin.AbstractM
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.project.MavenProject;
+import org.apache.maven.settings.Settings;
import org.apache.maven.shared.invoker.DefaultInvocationRequest;
import org.apache.maven.shared.invoker.InvocationRequest;
import org.apache.maven.shared.invoker.InvocationResult;
@@ -38,19 +39,28 @@ import org.apache.maven.shared.scriptint
import org.apache.maven.shared.scriptinterpreter.ScriptRunner;
import org.codehaus.plexus.util.FileUtils;
import org.codehaus.plexus.util.IOUtil;
+import org.codehaus.plexus.util.InterpolationFilterReader;
+import org.codehaus.plexus.util.ReaderFactory;
import org.codehaus.plexus.util.StringUtils;
+import org.codehaus.plexus.util.WriterFactory;
+import org.codehaus.plexus.util.introspection.ReflectionValueExtractor;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
+import java.io.Reader;
import java.io.StringWriter;
+import java.io.Writer;
import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
+import java.util.Set;
/**
* <p>Execute the archetype integration tests, consisting in generating projects from the current archetype and
@@ -159,6 +169,7 @@ public class IntegrationTestMojo
/**
* flag to enable show mvn version used for running its (cli option : -V,--show-version )
+ *
* @parameter expression="${archetype.test.showVersion}" default-value="false"
* @since 2.2
*/
@@ -172,6 +183,35 @@ public class IntegrationTestMojo
*/
private boolean debug;
+ /**
+ * A list of additional properties which will be used to filter tokens in settings.xml
+ *
+ * @parameter
+ * @since 2.2
+ */
+ private Map<String, String> filterProperties;
+
+ /**
+ * The current user system settings for use in Maven.
+ *
+ * @parameter expression="${settings}"
+ * @required
+ * @readonly
+ * @since 2.2
+ */
+ private Settings settings;
+
+ /**
+ * Path to an alternate <code>settings.xml</code> to use for Maven invocation with all ITs. Note that the
+ * <code><localRepository></code> element of this settings file is always ignored, i.e. the path given by the
+ * parameter {@link #localRepositoryPath} is dominant.
+ *
+ * @parameter expression="${archetype.test.settingsFile}"
+ * @since 2.2
+ */
+ private File settingsFile;
+
+
public void execute()
throws MojoExecutionException, MojoFailureException
{
@@ -413,6 +453,11 @@ public class IntegrationTestMojo
getLog().info( "Invoking post-archetype-generation goals: " + goals );
+ if ( !localRepositoryPath.exists() )
+ {
+ localRepositoryPath.mkdirs();
+ }
+
InvocationRequest request = new DefaultInvocationRequest().setBaseDirectory( basedir ).setGoals(
Arrays.asList( StringUtils.split( goals, "," ) ) ).setLocalRepositoryDirectory(
localRepositoryPath ).setInteractive( false ).setShowErrors( true );
@@ -428,6 +473,24 @@ public class IntegrationTestMojo
request.setOutputHandler( logger );
}
+ File interpolatedSettingsFile = null;
+ if ( settingsFile != null )
+ {
+ File interpolatedSettingsDirectory =
+ new File( project.getBuild().getOutputDirectory(), "archetype-it" );
+ if ( interpolatedSettingsDirectory.exists() )
+ {
+ FileUtils.deleteDirectory( interpolatedSettingsDirectory );
+ }
+ interpolatedSettingsDirectory.mkdir();
+ interpolatedSettingsFile =
+ new File( interpolatedSettingsDirectory, "interpolated-" + settingsFile.getName() );
+
+ buildInterpolatedFile( settingsFile, interpolatedSettingsFile );
+
+ request.setUserSettingsFile( interpolatedSettingsFile );
+ }
+
try
{
InvocationResult result = invoker.execute( request );
@@ -515,4 +578,294 @@ public class IntegrationTestMojo
super( message, cause );
}
}
+
+ /**
+ * Returns the map-based value source used to interpolate settings and other stuff.
+ *
+ * @return The map-based value source for interpolation, never <code>null</code>.
+ */
+ private Map<String, Object> getInterpolationValueSource()
+ {
+ Map<String, Object> props = new HashMap<String, Object>();
+ if ( filterProperties != null )
+ {
+ props.putAll( filterProperties );
+ }
+ if ( filterProperties != null )
+ {
+ props.putAll( filterProperties );
+ }
+ props.put( "basedir", this.project.getBasedir().getAbsolutePath() );
+ props.put( "baseurl", toUrl( this.project.getBasedir().getAbsolutePath() ) );
+ if ( settings.getLocalRepository() != null )
+ {
+ props.put( "localRepository", settings.getLocalRepository() );
+ props.put( "localRepositoryUrl", toUrl( settings.getLocalRepository() ) );
+ }
+ return new CompositeMap( this.project, props );
+ }
+
+ protected void buildInterpolatedFile( File originalFile, File interpolatedFile )
+ throws MojoExecutionException
+ {
+ getLog().debug( "Interpolate " + originalFile.getPath() + " to " + interpolatedFile.getPath() );
+
+ try
+ {
+ String xml;
+
+ Reader reader = null;
+ try
+ {
+ // interpolation with token @...@
+ Map<String, Object> composite = getInterpolationValueSource();
+ reader = ReaderFactory.newXmlReader( originalFile );
+ reader = new InterpolationFilterReader( reader, composite, "@", "@" );
+ xml = IOUtil.toString( reader );
+ }
+ finally
+ {
+ IOUtil.close( reader );
+ }
+
+ Writer writer = null;
+ try
+ {
+ interpolatedFile.getParentFile().mkdirs();
+ writer = WriterFactory.newXmlWriter( interpolatedFile );
+ writer.write( xml );
+ writer.flush();
+ }
+ finally
+ {
+ IOUtil.close( writer );
+ }
+ }
+ catch ( IOException e )
+ {
+ throw new MojoExecutionException( "Failed to interpolate file " + originalFile.getPath(), e );
+ }
+ }
+
+ private static class CompositeMap
+ implements Map<String, Object>
+ {
+
+ /**
+ * The Maven project from which to extract interpolated values, never <code>null</code>.
+ */
+ private MavenProject mavenProject;
+
+ /**
+ * The set of additional properties from which to extract interpolated values, never <code>null</code>.
+ */
+ private Map<String, Object> properties;
+
+ /**
+ * Creates a new interpolation source backed by the specified Maven project and some user-specified properties.
+ *
+ * @param mavenProject The Maven project from which to extract interpolated values, must not be <code>null</code>.
+ * @param properties The set of additional properties from which to extract interpolated values, may be
+ * <code>null</code>.
+ */
+ protected CompositeMap( MavenProject mavenProject, Map<String, Object> properties )
+ {
+ if ( mavenProject == null )
+ {
+ throw new IllegalArgumentException( "no project specified" );
+ }
+ this.mavenProject = mavenProject;
+ this.properties = properties == null ? (Map) new Properties() : properties;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.util.Map#clear()
+ */
+ public void clear()
+ {
+ // nothing here
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.util.Map#containsKey(java.lang.Object)
+ */
+ public boolean containsKey( Object key )
+ {
+ if ( !( key instanceof String ) )
+ {
+ return false;
+ }
+
+ String expression = (String) key;
+ if ( expression.startsWith( "project." ) || expression.startsWith( "pom." ) )
+ {
+ try
+ {
+ Object evaluated = ReflectionValueExtractor.evaluate( expression, this.mavenProject );
+ if ( evaluated != null )
+ {
+ return true;
+ }
+ }
+ catch ( Exception e )
+ {
+ // uhm do we have to throw a RuntimeException here ?
+ }
+ }
+
+ return properties.containsKey( key ) || mavenProject.getProperties().containsKey( key );
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.util.Map#containsValue(java.lang.Object)
+ */
+ public boolean containsValue( Object value )
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.util.Map#entrySet()
+ */
+ public Set<Entry<String, Object>> entrySet()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.util.Map#get(java.lang.Object)
+ */
+ public Object get( Object key )
+ {
+ if ( !( key instanceof String ) )
+ {
+ return null;
+ }
+
+ String expression = (String) key;
+ if ( expression.startsWith( "project." ) || expression.startsWith( "pom." ) )
+ {
+ try
+ {
+ Object evaluated = ReflectionValueExtractor.evaluate( expression, this.mavenProject );
+ if ( evaluated != null )
+ {
+ return evaluated;
+ }
+ }
+ catch ( Exception e )
+ {
+ // uhm do we have to throw a RuntimeException here ?
+ }
+ }
+
+ Object value = properties.get( key );
+
+ return ( value != null ? value : this.mavenProject.getProperties().get( key ) );
+
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.util.Map#isEmpty()
+ */
+ public boolean isEmpty()
+ {
+ return this.mavenProject == null && this.mavenProject.getProperties().isEmpty()
+ && this.properties.isEmpty();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.util.Map#keySet()
+ */
+ public Set<String> keySet()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.util.Map#put(java.lang.Object, java.lang.Object)
+ */
+ public Object put( String key, Object value )
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.util.Map#putAll(java.util.Map)
+ */
+ public void putAll( Map<? extends String, ? extends Object> t )
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.util.Map#remove(java.lang.Object)
+ */
+ public Object remove( Object key )
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.util.Map#size()
+ */
+ public int size()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.util.Map#values()
+ */
+ public Collection<Object> values()
+ {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+
+ /**
+ * Converts the specified filesystem path to a URL. The resulting URL has no trailing slash regardless whether the
+ * path denotes a file or a directory.
+ *
+ * @param filename The filesystem path to convert, must not be <code>null</code>.
+ * @return The <code>file:</code> URL for the specified path, never <code>null</code>.
+ */
+ private static String toUrl( String filename )
+ {
+ /*
+ * NOTE: Maven fails to properly handle percent-encoded "file:" URLs (WAGON-111) so don't use File.toURI() here
+ * as-is but use the decoded path component in the URL.
+ */
+ String url = "file://" + new File( filename ).toURI().getPath();
+ if ( url.endsWith( "/" ) )
+ {
+ url = url.substring( 0, url.length() - 1 );
+ }
+ return url;
+ }
}