Author: bentmann Date: Thu Aug 7 04:07:00 2008 New Revision: 683582 URL: http://svn.apache.org/viewvc?rev=683582&view=rev Log: [MINVOKER-36] Support for non-project based Maven invocations
Added: maven/plugins/trunk/maven-invoker-plugin/src/test/resources/unit/no-pom/ Modified: maven/plugins/trunk/maven-invoker-plugin/pom.xml maven/plugins/trunk/maven-invoker-plugin/src/main/java/org/apache/maven/plugin/invoker/InvokerMojo.java maven/plugins/trunk/maven-invoker-plugin/src/test/java/org/apache/maven/plugin/invoker/InvokerMojoTest.java Modified: maven/plugins/trunk/maven-invoker-plugin/pom.xml URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-invoker-plugin/pom.xml?rev=683582&r1=683581&r2=683582&view=diff ============================================================================== --- maven/plugins/trunk/maven-invoker-plugin/pom.xml (original) +++ maven/plugins/trunk/maven-invoker-plugin/pom.xml Thu Aug 7 04:07:00 2008 @@ -27,7 +27,7 @@ </parent> <artifactId>maven-invoker-plugin</artifactId> - <version>1.2.2-SNAPSHOT</version> + <version>1.3-SNAPSHOT</version> <packaging>maven-plugin</packaging> <name>Maven Invoker Plugin</name> 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=683582&r1=683581&r2=683582&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 Thu Aug 7 04:07:00 2008 @@ -154,17 +154,22 @@ private File pom; /** - * Includes for searching the integration test directory. This parameter is meant to be set from the POM. - * If this parameter is not set, the plugin will search for all <code>pom.xml</code> files one directory below - * [EMAIL PROTECTED] #projectsDirectory} (<code>*/pom.xml</code>). - * + * Include patterns for searching the integration test directory for projects. This parameter is meant to be set + * from the POM. If this parameter is not set, the plugin will search for all <code>pom.xml</code> files one + * directory below [EMAIL PROTECTED] #projectsDirectory} (i.e. <code>*/pom.xml</code>).<br> + * <br> + * Starting with version 1.3, mere directories can also be matched by these patterns. For example, the include + * pattern <code>*</code> will run Maven builds on all immediate sub directories of [EMAIL PROTECTED] #projectsDirectory}, + * regardless if they contain a <code>pom.xml</code>. This allows to perform builds that need/should not depend on + * the existence of a POM. + * * @parameter */ private List pomIncludes = Collections.singletonList( "*/pom.xml" ); /** - * Excludes for searching the integration test directory. This parameter is meant to be set from the POM. By - * default, no POM files are excluded. + * Exclude patterns for searching the integration test directory. This parameter is meant to be set from the POM. + * By default, no POM files are excluded. * * @parameter */ @@ -279,7 +284,7 @@ * Specify this parameter to run individual tests by file name, overriding the <code>pomIncludes</code> * and <code>pomExcludes</code> parameters. Each pattern you specify here will be used to create an * include pattern formatted like <code>${projectsDirectory}/${invoker.test}</code>, - * so you can just type "-Dinvoker.test=MyTest" to run a single it in ${projectsDirectory}/${invoker.test}". + * so you can just type "-Dinvoker.test=MyTest" to run a single build in ${projectsDirectory}/MyTest". * * @parameter expression="${invoker.test}" * @since 1.1 @@ -514,23 +519,33 @@ } } - private void cloneProjects( String[] includedPoms ) + /** + * Copies the specified IT projects to the directory given by [EMAIL PROTECTED] #cloneProjectsTo}. A project may either be + * denoted by a path to a POM file or merely by a path to a base directory. + * + * @param includedProjects The paths to the IT projects, relative to the projects directory, must not be + * <code>null</code>. + * @throws IOException The the projects could not be copied. + */ + private void cloneProjects( String[] includedProjects ) throws IOException { List clonedSubpaths = new ArrayList(); - for ( int i = 0; i < includedPoms.length; i++ ) + for ( int i = 0; i < includedProjects.length; i++ ) { - String subpath = includedPoms[i]; - int lastSep = subpath.lastIndexOf( File.separator ); - - if ( lastSep > -1 ) + String subpath = includedProjects[i]; + if ( !new File( projectsDirectory, subpath ).isDirectory() ) { - subpath = subpath.substring( 0, lastSep ); - } - else - { - subpath = "."; + int lastSep = subpath.lastIndexOf( File.separator ); + if ( lastSep > -1 ) + { + subpath = subpath.substring( 0, lastSep ); + } + else + { + subpath = "."; + } } // avoid copying subdirs that are already cloned. @@ -586,8 +601,13 @@ scanner.addDefaultExcludes(); } scanner.scan(); - - String [] includedFiles = scanner.getIncludedFiles(); + + /* + * NOTE: Make sure the destination directory is always there (even if empty) to support POM-less ITs. + */ + destDir.mkdirs(); + + String[] includedFiles = scanner.getIncludedFiles(); for ( int i = 0; i < includedFiles.length; ++i ) { File sourceFile = new File( sourceDir, includedFiles[ i ] ); @@ -611,17 +631,47 @@ return false; } - private void runBuild( final File projectsDir, final String pom, final List failures ) + /** + * Runs the specified IT project. + * + * @param projectsDir The base directory of all IT projects, must not be <code>null</code>. + * @param project The relative path to the IT project, either to a POM file or merely to a directory, must not be + * <code>null</code>. + * @param failures The list to record build failures in, must not be <code>null</code>. + * @throws MojoExecutionException If the IT project could not be launched. + */ + private void runBuild( final File projectsDir, String project, final List failures ) throws MojoExecutionException { + File pomFile = new File( projectsDir, project ); + File basedir; + if ( pomFile.isDirectory() ) + { + basedir = pomFile; + pomFile = new File( basedir, "pom.xml" ); + if ( !pomFile.exists() ) + { + pomFile = null; + } + else + { + project += File.separator + "pom.xml"; + } + } + else + { + basedir = pomFile.getParentFile(); + } + File interpolatedPomFile = null; + if ( pomFile != null ) + { + interpolatedPomFile = buildInterpolatedFile( pomFile, basedir, "interpolated-pom.xml" ); + } - File pomFile = new File( projectsDir, pom ); - final File basedir = pomFile.getParentFile(); - File interpolatedPomFile = buildInterpolatedFile( pomFile, basedir, "interpolated-pom.xml" ); FileLogger logger = null; try { - getLog().info( "Building: " + pom ); + getLog().info( "Building: " + project ); final File outputLog = new File( basedir, "build.log" ); @@ -659,17 +709,17 @@ getLog().debug( "Error initializing build logfile in: " + outputLog, e ); getLog().info( "...FAILED[could not initialize logfile in: " + outputLog + "]" ); - failures.add( pom ); + failures.add( project ); return; } } - if ( !prebuild( basedir, interpolatedPomFile, failures, logger ) ) + if ( !prebuild( basedir, logger ) ) { getLog().info( "...FAILED[pre-build script returned false]" ); - failures.add( pom ); + failures.add( project ); return; } @@ -680,11 +730,11 @@ if ( ( invocationGoals.size() == 1 ) && "_default".equals( invocationGoals.get( 0 ) ) ) { - getLog().debug( "Executing default goal for project in: " + pom ); + getLog().debug( "Executing default goal for project in: " + project ); } else { - getLog().debug( "Executing goals: " + invocationGoals + " for project in: " + pom ); + getLog().debug( "Executing goals: " + invocationGoals + " for project in: " + project ); request.setGoals( invocationGoals ); } @@ -717,7 +767,7 @@ getLog().debug( "Error reading test-properties file in: " + testPropertiesFile, e ); getLog().info( "...FAILED[error reading test properties in: " + testPropertiesFile + "]" ); - failures.add( pom ); + failures.add( project ); return; } @@ -751,7 +801,10 @@ request.setOutputHandler( logger ); } - request.setPomFile( interpolatedPomFile ); + if ( interpolatedPomFile != null ) + { + request.setPomFile( interpolatedPomFile ); + } request.setProfiles( getProfiles( basedir ) ); @@ -788,7 +841,7 @@ getLog().debug( "Error invoking Maven: " + e.getMessage(), e ); getLog().info( "...FAILED[error invoking Maven]" ); - failures.add( pom ); + failures.add( project ); return; } @@ -814,7 +867,7 @@ getLog().info( buffer.toString() ); } - failures.add( pom ); + failures.add( project ); } else if ( ( result.getExitCode() != 0 ) != nonZeroExit ) { @@ -833,16 +886,16 @@ getLog().info( buffer.toString() ); } - failures.add( pom ); + failures.add( project ); } - else if ( !verify( basedir, interpolatedPomFile, failures, logger ) ) + else if ( !verify( basedir, logger ) ) { if ( !suppressSummaries ) { getLog().info( "...FAILED[verify script returned false]." ); } - failures.add( pom ); + failures.add( project ); } else if ( !suppressSummaries ) { @@ -886,7 +939,7 @@ return testProps; } - private boolean verify( final File basedir, final File pom, final List failures, final FileLogger logger ) + private boolean verify( final File basedir, final FileLogger logger ) { boolean result = true; @@ -988,7 +1041,7 @@ return scriptResult; } - private boolean prebuild( final File basedir, final File pom, final List failures, final FileLogger logger ) + private boolean prebuild( final File basedir, final FileLogger logger ) { boolean result = true; @@ -1054,8 +1107,7 @@ for ( int i = 0, size = testRegexes.length; i < size; i++ ) { // user just use -Dinvoker.test=MWAR191,MNG111 to use a directory thats the end is not pom.xml - includes.add( testRegexes[i].endsWith( "pom.xml" ) ? testRegexes[i] : testRegexes[i] - + File.separatorChar + "pom.xml" ); + includes.add( testRegexes[i] ); } final FileSet fs = new FileSet(); @@ -1064,11 +1116,14 @@ //fs.setExcludes( pomExcludes ); fs.setDirectory( projectsDirectory.getCanonicalPath() ); fs.setFollowSymlinks( false ); - fs.setUseDefaultExcludes( false ); + fs.setUseDefaultExcludes( true ); final FileSetManager fsm = new FileSetManager( getLog() ); - poms = fsm.getIncludedFiles( fs ); + List included = new ArrayList(); + included.addAll( Arrays.asList( fsm.getIncludedFiles( fs ) ) ); + included.addAll( Arrays.asList( fsm.getIncludedDirectories( fs ) ) ); + poms = (String[]) included.toArray( new String[included.size()] ); } else { @@ -1078,11 +1133,14 @@ fs.setExcludes( pomExcludes ); fs.setDirectory( projectsDirectory.getCanonicalPath() ); fs.setFollowSymlinks( false ); - fs.setUseDefaultExcludes( false ); + fs.setUseDefaultExcludes( true ); final FileSetManager fsm = new FileSetManager( getLog() ); - poms = fsm.getIncludedFiles( fs ); + List included = new ArrayList(); + included.addAll( Arrays.asList( fsm.getIncludedFiles( fs ) ) ); + included.addAll( Arrays.asList( fsm.getIncludedDirectories( fs ) ) ); + poms = (String[]) included.toArray( new String[included.size()] ); } poms = normalizePomPaths( poms ); 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=683582&r1=683581&r2=683582&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 Thu Aug 7 04:07:00 2008 @@ -125,7 +125,7 @@ setVariableValueToObject( invokerMojo, "invokerTest", "*" ); String[] poms = invokerMojo.getPoms(); System.out.println( Arrays.asList( poms ) ); - assertEquals( 4, poms.length ); + assertEquals( 6, poms.length ); } public void testAlreadyCloned() @@ -169,4 +169,35 @@ assertTrue( new File( cloneProjectsTo, "module-1/sub-module" ).isDirectory() ); } + public void testPomLessMavenInvocation() + throws Exception + { + String dirPath = getBasedir() + "/src/test/resources/unit"; + + File cloneProjectsTo = new File( getBasedir(), "target/unit" ); + if ( cloneProjectsTo.exists() ) + { + FileUtils.deleteDirectory( cloneProjectsTo ); + } + + MavenProjectStub project = new MavenProjectStub(); + project.setTestClasspathElements( Collections.EMPTY_LIST ); + + String pomIndependentMojo = "org.apache.maven.plugins:maven-deploy-plugin:2.4:help"; + + InvokerMojo invokerMojo = new InvokerMojo(); + setVariableValueToObject( invokerMojo, "goals", Collections.singletonList( pomIndependentMojo ) ); + setVariableValueToObject( invokerMojo, "projectsDirectory", new File( dirPath ) ); + setVariableValueToObject( invokerMojo, "pomIncludes", Collections.singletonList( "no-pom" ) ); + setVariableValueToObject( invokerMojo, "cloneProjectsTo", cloneProjectsTo ); + setVariableValueToObject( invokerMojo, "project", project ); + setVariableValueToObject( invokerMojo, "settings", new Settings() ); + setVariableValueToObject( invokerMojo, "invoker", getContainer().lookup( Invoker.ROLE ) ); + + invokerMojo.execute(); + + assertTrue( new File( cloneProjectsTo, "no-pom" ).isDirectory() ); + assertTrue( new File( cloneProjectsTo, "no-pom/build.log" ).isFile() ); + } + }