PR: MNG-870

MAke plugin discovery reactor aware



git-svn-id: https://svn.apache.org/repos/asf/maven/components/trunk@290887 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Brett Leslie Porter 2005-09-22 04:34:41 +00:00
parent cbcf2d48e1
commit cebbdaf1ce
12 changed files with 259 additions and 188 deletions

View File

@ -3,3 +3,4 @@ test-component-b/target/test-component-b-0.1.jar
test-component-c/target/test-component-c-0.1.war
test-component-c/target/test-component-c-0.1.war!/WEB-INF/lib/test-component-a-0.1.jar
test-component-c/target/test-component-c-0.1.war!/WEB-INF/lib/test-component-b-0.1.jar
test-component-c/target/my-test

View File

@ -10,5 +10,6 @@
<module>test-component-c</module>
<module>test-component-b</module>
<module>test-component-a</module>
<module>test-plugin</module>
</modules>
</project>

View File

@ -19,4 +19,24 @@
<version>0.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>test</groupId>
<artifactId>test-plugin</artifactId>
<version>0.1</version>
<configuration>
<value>my-test</value>
</configuration>
<executions>
<execution>
<goals>
<goal>test</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,21 @@
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>test-components</artifactId>
<groupId>test</groupId>
<version>0.1</version>
</parent>
<groupId>test</groupId>
<artifactId>test-plugin</artifactId>
<packaging>maven-plugin</packaging>
<version>0.1</version>
<name>Test Plugin</name>
<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>2.0-beta-1</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,77 @@
package org.apache.maven.plugin.coreit;
/*
* Copyright 2001-2004 The Apache Software Foundation.
*
* Licensed 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 org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
/**
* @goal test
*
* @phase process-sources
*
* @description Goal which cleans the build
*/
public class CoreItMojo
extends AbstractMojo
{
/**
* @parameter expression="${project.build.directory}"
* @required
*/
private String outputDirectory;
/**
* @parameter
* @required
*/
private String value;
public void execute()
throws MojoExecutionException
{
touch( new File( outputDirectory ), value );
}
private static void touch( File dir, String file )
throws MojoExecutionException
{
try
{
if ( !dir.exists() )
{
dir.mkdirs();
}
File touch = new File( dir, file );
FileWriter w = new FileWriter( touch );
w.write( file );
w.close();
}
catch ( IOException e )
{
throw new MojoExecutionException( "Error touching file", e );
}
}
}

View File

@ -194,7 +194,7 @@ public class DefaultMaven
Throwable exception = response.getException();
if ( ReactorManager.FAIL_AT_END.equals( rm.getFailureBehavior() ) &&
( exception instanceof ReactorException ) )
exception instanceof ReactorException )
{
logFailure( response, exception, null );
@ -268,12 +268,10 @@ public class DefaultMaven
getLogger().info( "Reactor Summary:" );
line();
for ( Iterator it = rm.getProjectsSortedByDependency().iterator(); it.hasNext(); )
for ( Iterator it = rm.getSortedProjects().iterator(); it.hasNext(); )
{
MavenProject project = (MavenProject) it.next();
String id = project.getId();
if ( rm.hasBuildFailure( project ) )
{
logReactorSummaryLine( project.getName(), "FAILED" );

View File

@ -1,18 +1,27 @@
package org.apache.maven.execution;
/*
* Copyright 2001-2005 The Apache Software Foundation.
*
* Licensed 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 org.apache.maven.artifact.ArtifactUtils;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.Extension;
import org.apache.maven.model.Plugin;
import org.apache.maven.model.ReportPlugin;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.ProjectSorter;
import org.codehaus.plexus.util.dag.CycleDetectedException;
import org.codehaus.plexus.util.dag.DAG;
import org.codehaus.plexus.util.dag.TopologicalSorter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@ -20,136 +29,37 @@ import java.util.Map;
public class ReactorManager
{
public static final String FAIL_FAST = "fail-fast";
public static final String FAIL_AT_END = "fail-at-end";
public static final String FAIL_NEVER = "fail-never";
private DAG reactorDag;
private Map projectMap;
private List projectsByDependency;
private List blackList = new ArrayList();
private MavenProject topLevelProject;
private Map buildFailuresByProject = new HashMap();
private String failureBehavior = FAIL_FAST;
private final ProjectSorter sorter;
public ReactorManager( List projects )
throws CycleDetectedException
{
reactorDag = new DAG();
projectMap = new HashMap();
for ( Iterator i = projects.iterator(); i.hasNext(); )
{
MavenProject project = (MavenProject) i.next();
String id = ArtifactUtils.versionlessKey( project.getGroupId(), project.getArtifactId() );
reactorDag.addVertex( id );
projectMap.put( id, project );
}
for ( Iterator i = projects.iterator(); i.hasNext(); )
{
MavenProject project = (MavenProject) i.next();
String id = ArtifactUtils.versionlessKey( project.getGroupId(), project.getArtifactId() );
for ( Iterator j = project.getDependencies().iterator(); j.hasNext(); )
{
Dependency dependency = (Dependency) j.next();
String dependencyId = ArtifactUtils.versionlessKey( dependency.getGroupId(), dependency.getArtifactId() );
if ( reactorDag.getVertex( dependencyId ) != null )
{
project.addProjectReference( (MavenProject) projectMap.get( dependencyId ) );
reactorDag.addEdge( id, dependencyId );
}
}
MavenProject parent = project.getParent();
if ( parent != null )
{
String parentId = ArtifactUtils.versionlessKey( parent.getGroupId(), parent.getArtifactId() );
if ( reactorDag.getVertex( parentId ) != null )
{
reactorDag.addEdge( id, parentId );
}
}
List buildPlugins = project.getBuildPlugins();
if ( buildPlugins != null )
{
for ( Iterator j = buildPlugins.iterator(); j.hasNext(); )
{
Plugin plugin = (Plugin) j.next();
String pluginId = ArtifactUtils.versionlessKey( plugin.getGroupId(), plugin.getArtifactId() );
if ( reactorDag.getVertex( pluginId ) != null )
{
reactorDag.addEdge( id, pluginId );
}
}
}
List reportPlugins = project.getReportPlugins();
if ( reportPlugins != null )
{
for ( Iterator j = reportPlugins.iterator(); j.hasNext(); )
{
ReportPlugin plugin = (ReportPlugin) j.next();
String pluginId = ArtifactUtils.versionlessKey( plugin.getGroupId(), plugin.getArtifactId() );
if ( reactorDag.getVertex( pluginId ) != null )
{
reactorDag.addEdge( id, pluginId );
}
}
}
for ( Iterator j = project.getBuildExtensions().iterator(); j.hasNext(); )
{
Extension extension = (Extension) j.next();
String extensionId = ArtifactUtils.versionlessKey( extension.getGroupId(), extension.getArtifactId() );
if ( reactorDag.getVertex( extensionId ) != null )
{
reactorDag.addEdge( id, extensionId );
}
}
}
projectsByDependency = new ArrayList();
for ( Iterator i = TopologicalSorter.sort( reactorDag ).iterator(); i.hasNext(); )
{
String id = (String) i.next();
projectsByDependency.add( projectMap.get( id ) );
}
projectsByDependency = Collections.unmodifiableList( projectsByDependency );
this.sorter = new ProjectSorter( projects );
}
public void setFailureBehavior( String failureBehavior )
{
if ( FAIL_FAST.equals( failureBehavior ) || FAIL_AT_END.equals( failureBehavior ) || FAIL_NEVER.equals( failureBehavior ) )
if ( FAIL_FAST.equals( failureBehavior ) || FAIL_AT_END.equals( failureBehavior ) ||
FAIL_NEVER.equals( failureBehavior ) )
{
this.failureBehavior = failureBehavior;
}
else
{
throw new IllegalArgumentException( "Invalid failure behavior (must be one of: \'" + FAIL_FAST + "\', \'"
+ FAIL_AT_END + "\', \'" + FAIL_NEVER + "\')." );
throw new IllegalArgumentException( "Invalid failure behavior (must be one of: \'" + FAIL_FAST + "\', \'" +
FAIL_AT_END + "\', \'" + FAIL_NEVER + "\')." );
}
}
@ -158,30 +68,9 @@ public class ReactorManager
return failureBehavior;
}
public List getProjectsSortedByDependency()
{
return projectsByDependency;
}
// TODO: !![jc; 28-jul-2005] check this; if we're using '-r' and there are aggregator tasks, this will result in weirdness.
public MavenProject getTopLevelProject()
{
if ( topLevelProject == null )
{
List projectsByFile = new ArrayList( projectsByDependency );
Collections.sort(projectsByFile, new ByProjectFileComparator() );
topLevelProject = (MavenProject) projectsByFile.get( 0 );
}
return topLevelProject;
}
public void blackList( MavenProject project )
{
blackList(
ArtifactUtils.versionlessKey( project.getGroupId(), project.getArtifactId() ) );
blackList( ArtifactUtils.versionlessKey( project.getGroupId(), project.getArtifactId() ) );
}
private void blackList( String id )
@ -190,7 +79,7 @@ public class ReactorManager
{
blackList.add( id );
List dependents = reactorDag.getParentLabels( id );
List dependents = sorter.getDependents( id );
if ( dependents != null && !dependents.isEmpty() )
{
@ -206,8 +95,7 @@ public class ReactorManager
public boolean isBlackListed( MavenProject project )
{
return blackList.contains(
ArtifactUtils.versionlessKey( project.getGroupId(), project.getArtifactId() ) );
return blackList.contains( ArtifactUtils.versionlessKey( project.getGroupId(), project.getArtifactId() ) );
}
public void registerBuildFailure( MavenProject project, Exception error, String task )
@ -227,40 +115,18 @@ public class ReactorManager
public boolean hasMultipleProjects()
{
return projectsByDependency.size() > 1;
return sorter.hasMultipleProjects();
}
private static class ByProjectFileComparator implements Comparator
public List getSortedProjects()
{
public int compare( Object first, Object second )
{
MavenProject p1 = (MavenProject) first;
MavenProject p2 = (MavenProject) second;
String p1Path = p1.getFile().getAbsolutePath();
String p2Path = p2.getFile().getAbsolutePath();
int comparison = p1Path.length() - p2Path.length();
if ( comparison > 0 )
{
return 1;
}
else if ( comparison < 0 )
{
return -1;
}
else
{
return 0;
}
}
return sorter.getSortedProjects();
}
private static class BuildFailure
{
private Exception cause;
private String task;
BuildFailure( Exception cause, String task )

View File

@ -48,6 +48,7 @@ import org.apache.maven.plugin.version.PluginVersionResolutionException;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectBuilder;
import org.apache.maven.project.ProjectBuildingException;
import org.apache.maven.project.artifact.ActiveProjectArtifact;
import org.apache.maven.project.path.PathTranslator;
import org.apache.maven.reporting.MavenReport;
import org.apache.maven.settings.Settings;
@ -262,6 +263,18 @@ public class DefaultPluginManager
ArtifactRepository localRepository )
throws ArtifactResolutionException, PlexusContainerException
{
// TODO: share with MMS? Not sure if it belongs here
if ( project.getProjectReferences() != null && !project.getProjectReferences().isEmpty() )
{
// TODO: use MavenProject getProjectReferenceId
String refId = plugin.getGroupId() + ":" + plugin.getArtifactId();
MavenProject ref = (MavenProject) project.getProjectReferences().get( refId );
if ( ref != null && ref.getArtifact() != null )
{
pluginArtifact = new ActiveProjectArtifact( ref, pluginArtifact );
}
}
artifactResolver.resolve( pluginArtifact, project.getPluginArtifactRepositories(), localRepository );
PlexusContainer child = container.createChildContainer( plugin.getKey(),

View File

@ -664,6 +664,8 @@ public class DefaultMavenProjectBuilder
}
project.setRemoteArtifactRepositories( remoteRepositories );
// TODO: these aren't taking active project artifacts into consideration in the reactor
project.setPluginArtifacts( createPluginArtifacts( project.getBuildPlugins() ) );
project.setReportArtifacts( createReportArtifacts( project.getReportPlugins() ) );
project.setExtensionArtifacts( createExtensionArtifacts( project.getBuildExtensions() ) );
@ -1045,6 +1047,7 @@ public class DefaultMavenProjectBuilder
return pluginArtifacts;
}
// TODO: share with createPluginArtifacts?
protected Set createReportArtifacts( List reports )
throws ProjectBuildingException
{
@ -1087,6 +1090,7 @@ public class DefaultMavenProjectBuilder
return pluginArtifacts;
}
// TODO: share with createPluginArtifacts?
protected Set createExtensionArtifacts( List extensions )
throws ProjectBuildingException
{
@ -1112,8 +1116,7 @@ public class DefaultMavenProjectBuilder
try
{
artifact = artifactFactory.createExtensionArtifact( ext.getGroupId(), ext.getArtifactId(),
VersionRange
.createFromVersionSpec( version ) );
VersionRange.createFromVersionSpec( version ) );
}
catch ( InvalidVersionSpecificationException e )
{

View File

@ -1444,4 +1444,9 @@ public class MavenProject
{
return getBuild().getFilters();
}
public Map getProjectReferences()
{
return projectReferences;
}
}

View File

@ -16,6 +16,7 @@ package org.apache.maven.project;
* limitations under the License.
*/
import org.apache.maven.artifact.ArtifactUtils;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.Extension;
import org.apache.maven.model.Plugin;
@ -25,6 +26,8 @@ import org.codehaus.plexus.util.dag.DAG;
import org.codehaus.plexus.util.dag.TopologicalSorter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@ -38,10 +41,11 @@ import java.util.Map;
*/
public class ProjectSorter
{
private ProjectSorter()
{
// no touchy...
}
private final DAG dag;
private final List sortedProjects;
private MavenProject topLevelProject;
/**
* Sort a list of projects.
@ -54,10 +58,10 @@ public class ProjectSorter
* <li>do a topo sort on the graph that remains.</li>
* </ul>
*/
public static List getSortedProjects( List projects )
public ProjectSorter( List projects )
throws CycleDetectedException
{
DAG dag = new DAG();
dag = new DAG();
Map projectMap = new HashMap();
@ -65,7 +69,7 @@ public class ProjectSorter
{
MavenProject project = (MavenProject) i.next();
String id = getId( project.getGroupId(), project.getArtifactId() );
String id = ArtifactUtils.versionlessKey( project.getGroupId(), project.getArtifactId() );
dag.addVertex( id );
@ -76,13 +80,14 @@ public class ProjectSorter
{
MavenProject project = (MavenProject) i.next();
String id = getId( project.getGroupId(), project.getArtifactId() );
String id = ArtifactUtils.versionlessKey( project.getGroupId(), project.getArtifactId() );
for ( Iterator j = project.getDependencies().iterator(); j.hasNext(); )
{
Dependency dependency = (Dependency) j.next();
String dependencyId = getId( dependency.getGroupId(), dependency.getArtifactId() );
String dependencyId = ArtifactUtils.versionlessKey( dependency.getGroupId(),
dependency.getArtifactId() );
if ( dag.getVertex( dependencyId ) != null )
{
@ -95,7 +100,7 @@ public class ProjectSorter
MavenProject parent = project.getParent();
if ( parent != null )
{
String parentId = getId( parent.getGroupId(), parent.getArtifactId() );
String parentId = ArtifactUtils.versionlessKey( parent.getGroupId(), parent.getArtifactId() );
if ( dag.getVertex( parentId ) != null )
{
dag.addEdge( id, parentId );
@ -108,9 +113,11 @@ public class ProjectSorter
for ( Iterator j = buildPlugins.iterator(); j.hasNext(); )
{
Plugin plugin = (Plugin) j.next();
String pluginId = getId( plugin.getGroupId(), plugin.getArtifactId() );
String pluginId = ArtifactUtils.versionlessKey( plugin.getGroupId(), plugin.getArtifactId() );
if ( dag.getVertex( pluginId ) != null )
{
project.addProjectReference( (MavenProject) projectMap.get( pluginId ) );
dag.addEdge( id, pluginId );
}
}
@ -122,9 +129,11 @@ public class ProjectSorter
for ( Iterator j = reportPlugins.iterator(); j.hasNext(); )
{
ReportPlugin plugin = (ReportPlugin) j.next();
String pluginId = getId( plugin.getGroupId(), plugin.getArtifactId() );
String pluginId = ArtifactUtils.versionlessKey( plugin.getGroupId(), plugin.getArtifactId() );
if ( dag.getVertex( pluginId ) != null )
{
project.addProjectReference( (MavenProject) projectMap.get( pluginId ) );
dag.addEdge( id, pluginId );
}
}
@ -133,9 +142,11 @@ public class ProjectSorter
for ( Iterator j = project.getBuildExtensions().iterator(); j.hasNext(); )
{
Extension extension = (Extension) j.next();
String extensionId = getId( extension.getGroupId(), extension.getArtifactId() );
String extensionId = ArtifactUtils.versionlessKey( extension.getGroupId(), extension.getArtifactId() );
if ( dag.getVertex( extensionId ) != null )
{
project.addProjectReference( (MavenProject) projectMap.get( extensionId ) );
dag.addEdge( id, extensionId );
}
}
@ -150,11 +161,66 @@ public class ProjectSorter
sortedProjects.add( projectMap.get( id ) );
}
this.sortedProjects = Collections.unmodifiableList( sortedProjects );
}
// TODO: !![jc; 28-jul-2005] check this; if we're using '-r' and there are aggregator tasks, this will result in weirdness.
public MavenProject getTopLevelProject()
{
if ( topLevelProject == null )
{
List projectsByFile = new ArrayList( sortedProjects );
Collections.sort( projectsByFile, new ByProjectFileComparator() );
topLevelProject = (MavenProject) projectsByFile.get( 0 );
}
return topLevelProject;
}
public List getSortedProjects()
{
return sortedProjects;
}
private static String getId( String groupId, String artifactId )
public boolean hasMultipleProjects()
{
return groupId + ":" + artifactId;
return sortedProjects.size() > 1;
}
public List getDependents( String id )
{
return dag.getParentLabels( id );
}
private static class ByProjectFileComparator
implements Comparator
{
public int compare( Object first, Object second )
{
MavenProject p1 = (MavenProject) first;
MavenProject p2 = (MavenProject) second;
String p1Path = p1.getFile().getAbsolutePath();
String p2Path = p2.getFile().getAbsolutePath();
int comparison = p1Path.length() - p2Path.length();
if ( comparison > 0 )
{
return 1;
}
else if ( comparison < 0 )
{
return -1;
}
else
{
return 0;
}
}
}
}

View File

@ -43,7 +43,7 @@ public class ProjectSorterTest
projects.add( project2 );
project1.getDependencies().add( createDependency( project2 ) );
projects = ProjectSorter.getSortedProjects( projects );
projects = new ProjectSorter( projects ).getSortedProjects();
assertEquals( project2, projects.get( 0 ) );
assertEquals( project1, projects.get( 1 ) );
@ -59,7 +59,7 @@ public class ProjectSorterTest
projects.add( project2 );
project1.getDependencies().add( createDependency( project2 ) );
projects = ProjectSorter.getSortedProjects( projects );
projects = new ProjectSorter( projects ).getSortedProjects();
assertEquals( project2, projects.get( 0 ) );
assertEquals( project1, projects.get( 1 ) );