You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by be...@apache.org on 2008/08/09 01:40:18 UTC
svn commit: r684144 - in /maven/plugins/trunk/maven-invoker-plugin/src:
main/java/org/apache/maven/plugin/invoker/ site/ site/apt/
site/apt/examples/ test/java/org/apache/maven/plugin/invoker/
Author: bentmann
Date: Fri Aug 8 16:40:17 2008
New Revision: 684144
URL: http://svn.apache.org/viewvc?rev=684144&view=rev
Log:
[MINVOKER-46] Allow multiple invocations of Maven on the same project
Added:
maven/plugins/trunk/maven-invoker-plugin/src/site/apt/examples/invoker-properties.apt.vm (with props)
Modified:
maven/plugins/trunk/maven-invoker-plugin/src/main/java/org/apache/maven/plugin/invoker/InvokerMojo.java
maven/plugins/trunk/maven-invoker-plugin/src/site/apt/index.apt
maven/plugins/trunk/maven-invoker-plugin/src/site/site.xml
maven/plugins/trunk/maven-invoker-plugin/src/test/java/org/apache/maven/plugin/invoker/InvokerMojoTest.java
Modified: maven/plugins/trunk/maven-invoker-plugin/src/main/java/org/apache/maven/plugin/invoker/InvokerMojo.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-invoker-plugin/src/main/java/org/apache/maven/plugin/invoker/InvokerMojo.java?rev=684144&r1=684143&r2=684144&view=diff
==============================================================================
--- maven/plugins/trunk/maven-invoker-plugin/src/main/java/org/apache/maven/plugin/invoker/InvokerMojo.java (original)
+++ maven/plugins/trunk/maven-invoker-plugin/src/main/java/org/apache/maven/plugin/invoker/InvokerMojo.java Fri Aug 8 16:40:17 2008
@@ -61,7 +61,6 @@
import org.codehaus.plexus.util.ReaderFactory;
import org.codehaus.plexus.util.StringUtils;
import org.codehaus.plexus.util.WriterFactory;
-import org.codehaus.plexus.util.cli.CommandLineException;
import org.codehaus.plexus.interpolation.InterpolationException;
import org.codehaus.plexus.interpolation.Interpolator;
import org.codehaus.plexus.interpolation.MapBasedValueSource;
@@ -378,7 +377,10 @@
* <pre>
* # A comma or space separated list of goals/phases to execute, may
* # specify an empty list to execute the default goal of the IT project
- * invoker.goals=clean package site
+ * invoker.goals=clean install
+ *
+ * # Optionally, a list of goals to run during further invocations of Maven
+ * invoker.goals.2=${project.groupId}:${project.artifactId}:${project.version}:run
*
* # A comma or space separated list of profiles to activate
* invoker.profiles=its,jdk15
@@ -486,6 +488,16 @@
projectsDir = cloneProjectsTo;
}
+ if ( localRepositoryPath != null )
+ {
+ getLog().debug( "Using local repository: " + localRepositoryPath );
+
+ if ( !localRepositoryPath.exists() )
+ {
+ localRepositoryPath.mkdirs();
+ }
+ }
+
final List failures = new ArrayList();
for ( int i = 0; i < includedPoms.length; i++ )
@@ -495,7 +507,6 @@
runBuild( projectsDir, pom, failures );
}
-
if ( !suppressSummaries )
{
final StringBuffer summary = new StringBuffer();
@@ -744,6 +755,10 @@
}
}
+ List goals = getGoals( basedir );
+
+ List profiles = getProfiles( basedir );
+
Properties systemProperties = getTestProperties( basedir );
FileLogger logger = setupLogger( basedir );
@@ -760,44 +775,27 @@
final InvocationRequest request = new DefaultInvocationRequest();
- final List invocationGoals = getGoals( basedir );
-
- if ( invocationGoals.isEmpty()
- || ( invocationGoals.size() == 1 && "_default".equals( invocationGoals.get( 0 ) ) ) )
+ if ( localRepositoryPath != null )
{
- getLog().debug( "Executing default goal for project in: " + project );
+ request.setLocalRepositoryDirectory( localRepositoryPath );
}
- else
- {
- getLog().debug( "Executing goals: " + invocationGoals + " for project in: " + project );
- request.setGoals( invocationGoals );
+ if ( settingsFile != null )
+ {
+ File interpolatedSettingsFile =
+ new File( settingsFile.getParentFile(), "interpolated-" + settingsFile.getName() );
+ buildInterpolatedFile( settingsFile, interpolatedSettingsFile );
+ request.setUserSettingsFile( interpolatedSettingsFile );
}
request.setProperties( systemProperties );
- if ( localRepositoryPath != null )
- {
- File localRepoDir = localRepositoryPath;
-
- getLog().debug( "Using local repository: " + localRepoDir );
-
- if ( ! localRepositoryPath.exists() )
- {
- localRepositoryPath.mkdirs();
- }
-
- request.setLocalRepositoryDirectory( localRepoDir );
- }
-
request.setInteractive( false );
request.setShowErrors( showErrors );
request.setDebug( debug );
- request.setBaseDirectory( basedir );
-
if ( logger != null )
{
request.setErrorHandler( logger );
@@ -805,98 +803,108 @@
request.setOutputHandler( logger );
}
+ request.setBaseDirectory( basedir );
+
if ( pomFile != null )
{
request.setPomFile( pomFile );
}
- request.setProfiles( getProfiles( basedir ) );
-
- if ( settingsFile != null )
+ for ( int invocationIndex = 1;; invocationIndex++ )
{
- File interpolatedSettingsFile =
- new File( settingsFile.getParentFile(), "interpolated-" + settingsFile.getName() );
- buildInterpolatedFile( settingsFile, interpolatedSettingsFile );
- request.setUserSettingsFile( interpolatedSettingsFile );
- }
+ if ( invocationIndex > 1
+ && invokerProperties.getProperty( "invoker.goals." + invocationIndex ) == null )
+ {
+ break;
+ }
- request.setMavenOpts( mavenOpts );
+ request.setGoals( goals );
- configureInvocation( request, invokerProperties );
+ request.setProfiles( profiles );
- try
- {
- getLog().debug( "Using MAVEN_OPTS: " + request.getMavenOpts() );
- getLog().debug( "Executing: " + new MavenCommandLineBuilder().build( request ) );
- }
- catch ( CommandLineConfigurationException e )
- {
- getLog().debug( "Failed to display command line: " + e.getMessage() );
- }
+ request.setMavenOpts( mavenOpts );
- InvocationResult result = null;
+ configureInvocation( request, invocationIndex, invokerProperties );
- try
- {
- result = invoker.execute( request );
- }
- catch ( final MavenInvocationException e )
- {
- getLog().debug( "Error invoking Maven: " + e.getMessage(), e );
- getLog().info( "...FAILED[error invoking Maven]" );
+ try
+ {
+ getLog().debug( "Using MAVEN_OPTS: " + request.getMavenOpts() );
+ getLog().debug( "Executing: " + new MavenCommandLineBuilder().build( request ) );
+ }
+ catch ( CommandLineConfigurationException e )
+ {
+ getLog().debug( "Failed to display command line: " + e.getMessage() );
+ }
- failures.add( project );
+ InvocationResult result;
- return;
- }
+ try
+ {
+ result = invoker.execute( request );
+ }
+ catch ( final MavenInvocationException e )
+ {
+ getLog().debug( "Error invoking Maven: " + e.getMessage(), e );
+ getLog().info( "...FAILED[error invoking Maven]" );
- final CommandLineException executionException = result.getExecutionException();
- final boolean nonZeroExit =
- "failure".equalsIgnoreCase( invokerProperties.getProperty( "invoker.buildResult" ) );
+ failures.add( project );
- if ( executionException != null )
- {
- if ( !suppressSummaries )
- {
- StringBuffer buffer = new StringBuffer( 256 );
- buffer.append( "...FAILED. " );
- if ( logger != null )
- {
- buffer.append( "See " );
- buffer.append( logger.getOutputFile().getAbsolutePath() );
- buffer.append( " for details." );
- }
- else
- {
- buffer.append( "See console output for details." );
- }
- getLog().info( buffer.toString() );
+ return;
}
- failures.add( project );
- }
- else if ( ( result.getExitCode() != 0 ) != nonZeroExit )
- {
- if ( !suppressSummaries )
+ final boolean nonZeroExit =
+ "failure".equalsIgnoreCase( getInvokerProperty( invokerProperties, "invoker.buildResult",
+ invocationIndex ) );
+
+ if ( result.getExecutionException() != null )
{
- StringBuffer buffer = new StringBuffer( 256 );
- buffer.append( "...FAILED[code=" ).append( result.getExitCode() ).append( "]. " );
- if ( logger != null )
+ if ( !suppressSummaries )
{
- buffer.append( "See " );
- buffer.append( logger.getOutputFile().getAbsolutePath() );
- buffer.append( " for details." );
+ StringBuffer buffer = new StringBuffer( 256 );
+ buffer.append( "...FAILED. " );
+ if ( logger != null )
+ {
+ buffer.append( "See " );
+ buffer.append( logger.getOutputFile().getAbsolutePath() );
+ buffer.append( " for details." );
+ }
+ else
+ {
+ buffer.append( "See console output for details." );
+ }
+ getLog().info( buffer.toString() );
}
- else
+
+ failures.add( project );
+
+ return;
+ }
+ else if ( ( result.getExitCode() != 0 ) != nonZeroExit )
+ {
+ if ( !suppressSummaries )
{
- buffer.append( "See console output for details." );
+ StringBuffer buffer = new StringBuffer( 256 );
+ buffer.append( "...FAILED[code=" ).append( result.getExitCode() ).append( "]. " );
+ if ( logger != null )
+ {
+ buffer.append( "See " );
+ buffer.append( logger.getOutputFile().getAbsolutePath() );
+ buffer.append( " for details." );
+ }
+ else
+ {
+ buffer.append( "See console output for details." );
+ }
+ getLog().info( buffer.toString() );
}
- getLog().info( buffer.toString() );
- }
- failures.add( project );
+ failures.add( project );
+
+ return;
+ }
}
- else if ( !verify( basedir, logger ) )
+
+ if ( !verify( basedir, logger ) )
{
if ( !suppressSummaries )
{
@@ -1529,42 +1537,66 @@
* invoker properties will be left unchanged in the invocation request.
*
* @param request The invocation request to configure, must not be <code>null</code>.
+ * @param index The one-based index of the invocation to configure, must be positive.
* @param properties The invoker properties used to configure the invocation, must not be <code>null</code>.
- * @return The configured invocation request.
*/
- private InvocationRequest configureInvocation( InvocationRequest request, Properties properties )
+ private void configureInvocation( InvocationRequest request, int index, Properties properties )
{
- String goals = properties.getProperty( "invoker.goals" );
+ if ( index < 1 )
+ {
+ throw new IllegalArgumentException( "invalid invocation index: " + index );
+ }
+
+ String goals = getInvokerProperty( properties, "invoker.goals", index );
if ( goals != null )
{
request.setGoals( new ArrayList( Arrays.asList( goals.split( "[,\\s]+" ) ) ) );
}
- String profiles = properties.getProperty( "invoker.profiles" );
+ String profiles = getInvokerProperty( properties, "invoker.profiles", index );
if ( profiles != null )
{
request.setProfiles( new ArrayList( Arrays.asList( profiles.split( "[,\\s]+" ) ) ) );
}
- String opts = properties.getProperty( "invoker.mavenOpts" );
- if ( opts != null )
+ String mvnOpts = getInvokerProperty( properties, "invoker.mavenOpts", index );
+ if ( mvnOpts != null )
{
- request.setMavenOpts( opts );
+ request.setMavenOpts( mvnOpts );
}
- String failureBehavior = properties.getProperty( "invoker.failureBehavior" );
+ String failureBehavior = getInvokerProperty( properties, "invoker.failureBehavior", index );
if ( failureBehavior != null )
{
request.setFailureBehavior( failureBehavior );
}
- String nonRecursive = properties.getProperty( "invoker.nonRecursive" );
+ String nonRecursive = getInvokerProperty( properties, "invoker.nonRecursive", index );
if ( nonRecursive != null )
{
request.setRecursive( !Boolean.valueOf( nonRecursive ).booleanValue() );
}
+ }
- return request;
+ /**
+ * Gets a value from the invoker properties. The invoker properties are intended to describe the invocation settings
+ * for multiple builds of the same project. For this reason, the properties are indexed. First, a property named
+ * <code>key.index</code> will be queried. If this property does not exist, the value of the property named
+ * <code>key</code> will finally be returned.
+ *
+ * @param properties The invoker properties from which to lookup the value, must not be <code>null</code>.
+ * @param key The (base) key for the invoker property to lookup, must not be <code>null</code>.
+ * @param index The index of the invocation for which to retrieve the value, must not be negative.
+ * @return The value for the requested invoker property or <code>null</code> if not defined.
+ */
+ static String getInvokerProperty( Properties properties, String key, int index )
+ {
+ String value = properties.getProperty( key + '.' + index );
+ if ( value == null )
+ {
+ value = properties.getProperty( key );
+ }
+ return value;
}
}
Added: maven/plugins/trunk/maven-invoker-plugin/src/site/apt/examples/invoker-properties.apt.vm
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-invoker-plugin/src/site/apt/examples/invoker-properties.apt.vm?rev=684144&view=auto
==============================================================================
--- maven/plugins/trunk/maven-invoker-plugin/src/site/apt/examples/invoker-properties.apt.vm (added)
+++ maven/plugins/trunk/maven-invoker-plugin/src/site/apt/examples/invoker-properties.apt.vm Fri Aug 8 16:40:17 2008
@@ -0,0 +1,109 @@
+ ------
+ Invoker Properties
+ ------
+ Benjamin Bentmann
+ ------
+ 2008-08-09
+ ------
+
+ ~~ 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.
+
+ ~~ NOTE: For help with the syntax of this file, see:
+ ~~ http://maven.apache.org/doxia/references/apt-format.html
+
+Invoker Properties
+
+ The various parameters in the plugin configuration provide a means to globally configure the goals, profiles etc.
+ used to run a Maven build on the projects. However, for certain projects you might want to specify different settings.
+ To avoid the hassle of multiple plugin executions, you can simply use a file named <<<invoker.properties>>> to
+ control the build settings on a per project basis. The exact name of this properties file is configurable but it needs
+ to reside in the base directory of the respective project as shown below:
+
+-------------------
+./
++- src/
+ +- it/
+ +- test-project/
+ +- pom.xml
+ +- invoker.properties
+ +- src/
+-------------------
+
+ There are only a few keys supported in this file and their names typically match the corresponding parameters in the
+ plugin configuration. The snippet below provides a complete overview of supported properties:
+
++----
+# A comma or space separated list of goals/phases to execute, may
+# specify an empty list to execute the default goal of the project
+invoker.goals=clean install
+
+# Optionally, a list of goals to run during further invocations of Maven
+invoker.goals.2=\${project.groupId}:\${project.artifactId}:\${project.version}:run
+
+# A comma or space separated list of profiles to activate
+invoker.profiles=its,jdk15
+
+# The value for the environment variable MAVEN_OPTS
+invoker.mavenOpts=-Dfile.encoding=UTF-16 -Xms32m -Xmx256m
+
+# Possible values are "fail-fast" (default), "fail-at-end" and "fail-never"
+invoker.failureBehavior=fail-never
+
+# The expected result of the build, possible values are "success" (default) and "failure"
+invoker.buildResult=failure
+
+# A boolean value controlling the -N flag, defaults to "false"
+invoker.nonRecursive=false
++----
+
+ The comments given in the example should be rather self-explanatory. Looking closely, you can also notice that the
+ syntax <<<$\{expression\}>>> can be used to filter the property values. What deserves some more description is the
+ possibility to perform several Maven builds on the same project. By default, the Invoker Plugin will perform the
+ following steps for each project:
+
+ * Run the pre build hook script if existent
+
+ * Invoke Maven in the project directory
+
+ * Run the post build hook script if existent
+
+ []
+
+ Since plugin version 1.3, you can append a one-based index to the invoker properties in order to enable/configure
+ further invocations of Maven. More precisely, <<<invoker.goals.1>>> specifies the goals for the first build,
+ <<<invoker.goals.2>>> lists the goals for the second build and so on. These builds will be performed one after the
+ other:
+
+ * Run the pre build hook script if existent
+
+ * Invoke Maven in the project directory
+
+ * Invoke Maven in the project directory
+
+ * ...
+
+ * Invoke Maven in the project directory
+
+ * Run the post build hook script if existent
+
+ []
+
+ All the properties can be indexed this way, e.g. <<<invoker.profiles.3>>> would specify the profiles to use for the
+ third invocation. If the property <<<invoker.profiles.3>>> was not defined, the plugin would query the property
+ <<<invoker.profiles>>> as a fallback to determine the profiles for the third build. This build loop ends after
+ invocation <i> if the property <<<invoker.goals.>>><i+1> is undefined.
Propchange: maven/plugins/trunk/maven-invoker-plugin/src/site/apt/examples/invoker-properties.apt.vm
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: maven/plugins/trunk/maven-invoker-plugin/src/site/apt/examples/invoker-properties.apt.vm
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Modified: maven/plugins/trunk/maven-invoker-plugin/src/site/apt/index.apt
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-invoker-plugin/src/site/apt/index.apt?rev=684144&r1=684143&r2=684144&view=diff
==============================================================================
--- maven/plugins/trunk/maven-invoker-plugin/src/site/apt/index.apt (original)
+++ maven/plugins/trunk/maven-invoker-plugin/src/site/apt/index.apt Fri Aug 8 16:40:17 2008
@@ -50,15 +50,17 @@
* Examples
The following example configurations are available:
-
+
* {{{examples/clone-projects.html}Clone projects}} to a new directory before running.
* {{{examples/install-artifacts.html}Install}} projects artifacts to a local repository before running.
-
+
* {{{examples/post-build-script.html}Run a BeanShell or Groovy script}} to verify project output.
-
+
* {{{examples/fast-use.html}Fast Invoker Plugin configuration}} to accelerate test execution.
-
+
* {{{examples/access-test-classes.html}Access test classes}} to share code between IT scripts.
-
+
+ * {{{examples/invoker-properties.html}Using Invoker Properties}} to configure goals, profiles etc. for individual projects.
+
[]
Modified: maven/plugins/trunk/maven-invoker-plugin/src/site/site.xml
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-invoker-plugin/src/site/site.xml?rev=684144&r1=684143&r2=684144&view=diff
==============================================================================
--- maven/plugins/trunk/maven-invoker-plugin/src/site/site.xml (original)
+++ maven/plugins/trunk/maven-invoker-plugin/src/site/site.xml Fri Aug 8 16:40:17 2008
@@ -34,6 +34,7 @@
<item name="Cloning Projects" href="examples/clone-projects.html"/>
<item name="Fast Build Configuration" href="examples/fast-use.html"/>
<item name="Installing Artifacts" href="examples/install-artifacts.html"/>
+ <item name="Invoker Properties" href="examples/invoker-properties.html"/>
<item name="Using a Post Build Script" href="examples/post-build-script.html"/>
</menu>
Modified: maven/plugins/trunk/maven-invoker-plugin/src/test/java/org/apache/maven/plugin/invoker/InvokerMojoTest.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-invoker-plugin/src/test/java/org/apache/maven/plugin/invoker/InvokerMojoTest.java?rev=684144&r1=684143&r2=684144&view=diff
==============================================================================
--- maven/plugins/trunk/maven-invoker-plugin/src/test/java/org/apache/maven/plugin/invoker/InvokerMojoTest.java (original)
+++ maven/plugins/trunk/maven-invoker-plugin/src/test/java/org/apache/maven/plugin/invoker/InvokerMojoTest.java Fri Aug 8 16:40:17 2008
@@ -24,6 +24,7 @@
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
+import java.util.Properties;
import org.apache.maven.plugin.testing.AbstractMojoTestCase;
import org.apache.maven.plugin.testing.stubs.MavenProjectStub;
@@ -205,4 +206,18 @@
assertTrue( new File( cloneProjectsTo, "no-pom/build.log" ).isFile() );
}
+ public void testGetInvokerProperty()
+ {
+ Properties props = new Properties();
+
+ assertNull( InvokerMojo.getInvokerProperty( props, "undefined-key", 0 ) );
+
+ props.setProperty( "key", "value" );
+ assertEquals( "value", InvokerMojo.getInvokerProperty( props, "key", 1 ) );
+
+ props.setProperty( "key.1", "another-value" );
+ assertEquals( "another-value", InvokerMojo.getInvokerProperty( props, "key", 1 ) );
+ assertEquals( "value", InvokerMojo.getInvokerProperty( props, "key", 2 ) );
+ }
+
}