You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by jv...@apache.org on 2014/01/06 18:01:36 UTC
git commit: MNG-5557: Constrain the set of projects that are passed
into the ReactorReader as specified by --projects
Updated Branches:
refs/heads/master 3929f55c3 -> 7c3052dde
MNG-5557: Constrain the set of projects that are passed into the ReactorReader as specified by --projects
- Add some documentation about the lifecycle within DefaultMaven
- Remove the use of DelegatingLocalArtifactRepository in DefaultMaven as it has been replaced with the use of the
ReactorReader which is an implementation of Aether's WorkspaceReader
- Localize the manipulation of the ProjectBuildingRequest to getProjectsFromReactor()
- Deprecated getLogger()
Project: http://git-wip-us.apache.org/repos/asf/maven/repo
Commit: http://git-wip-us.apache.org/repos/asf/maven/commit/7c3052dd
Tree: http://git-wip-us.apache.org/repos/asf/maven/tree/7c3052dd
Diff: http://git-wip-us.apache.org/repos/asf/maven/diff/7c3052dd
Branch: refs/heads/master
Commit: 7c3052ddebbb655c86a74a252472f9f753ccf822
Parents: 3929f55
Author: Jason van Zyl <ja...@tesla.io>
Authored: Mon Jan 6 10:37:17 2014 -0500
Committer: Jason van Zyl <ja...@tesla.io>
Committed: Mon Jan 6 10:55:01 2014 -0500
----------------------------------------------------------------------
.../java/org/apache/maven/DefaultMaven.java | 276 +++++++++++--------
.../java/org/apache/maven/ReactorReader.java | 25 +-
.../org/apache/maven/project/ProjectSorter.java | 3 +-
3 files changed, 174 insertions(+), 130 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/maven/blob/7c3052dd/maven-core/src/main/java/org/apache/maven/DefaultMaven.java
----------------------------------------------------------------------
diff --git a/maven-core/src/main/java/org/apache/maven/DefaultMaven.java b/maven-core/src/main/java/org/apache/maven/DefaultMaven.java
index 68e4011..152bd4b 100644
--- a/maven-core/src/main/java/org/apache/maven/DefaultMaven.java
+++ b/maven-core/src/main/java/org/apache/maven/DefaultMaven.java
@@ -59,7 +59,6 @@ import org.apache.maven.project.ProjectBuildingException;
import org.apache.maven.project.ProjectBuildingRequest;
import org.apache.maven.project.ProjectBuildingResult;
import org.apache.maven.project.ProjectSorter;
-import org.apache.maven.repository.DelegatingLocalArtifactRepository;
import org.apache.maven.repository.LocalRepositoryNotAccessibleException;
import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
import org.apache.maven.settings.Mirror;
@@ -162,8 +161,8 @@ public class DefaultMaven
catch ( RuntimeException e )
{
result =
- addExceptionToResult( new DefaultMavenExecutionResult(),
- new InternalErrorException( "Internal error: " + e, e ) );
+ addExceptionToResult( new DefaultMavenExecutionResult(), new InternalErrorException( "Internal error: "
+ + e, e ) );
}
finally
{
@@ -173,17 +172,42 @@ public class DefaultMaven
return result;
}
+ //
+ // 1) Setup initial properties.
+ //
+ // 2) Validate local repository directory is accessible.
+ //
+ // 3) Create RepositorySystemSession.
+ //
+ // 4) Create MavenSession.
+ //
+ // 5) Execute AbstractLifecycleParticipant.afterSessionStart(session)
+ //
+ // 6) Get reactor projects looking for read errors, and duplicate declarations
+ //
+ // 7) Create ProjectDependencyGraph using trimming which takes into account --projects and reactor mode. This ensures
+ // that the projects passed into the ReactorReader are only those specified.
+ //
+ // 8) Create ReactorReader with the project map created in 7)
+ //
+ // 9) Execute AbstractLifecycleParticipant.afterProjectsRead(session)
+ //
+ // 10) Create ProjectDependencyGraph without trimming (as trimming was done in 7). A new topological sort is required after
+ // the execution of 9) as the AbstractLifecycleParticipants are free to mutate the MavenProject instances, which may change
+ // dependencies which can, in turn, affect the build order.
+ //
+ // 11) Execute LifecycleStarter.start()
+ //
private MavenExecutionResult doExecute( MavenExecutionRequest request )
{
- //TODO: Need a general way to inject standard properties
if ( request.getStartTime() != null )
{
request.getSystemProperties().put( "${build.timestamp}",
new SimpleDateFormat( "yyyyMMdd-hhmm" ).format( request.getStartTime() ) );
- }
-
+ }
+
request.setStartTime( new Date() );
-
+
MavenExecutionResult result = new DefaultMavenExecutionResult();
try
@@ -195,11 +219,6 @@ public class DefaultMaven
return addExceptionToResult( result, e );
}
- DelegatingLocalArtifactRepository delegatingLocalArtifactRepository =
- new DelegatingLocalArtifactRepository( request.getLocalRepository() );
-
- request.setLocalRepository( delegatingLocalArtifactRepository );
-
DefaultRepositorySystemSession repoSession = (DefaultRepositorySystemSession) newRepositorySession( request );
MavenSession session = new MavenSession( container, repoSession, request, result );
@@ -219,46 +238,50 @@ public class DefaultMaven
eventCatapult.fire( ExecutionEvent.Type.ProjectDiscoveryStarted, session, null );
- request.getProjectBuildingRequest().setRepositorySession( session.getRepositorySession() );
-
- //TODO: optimize for the single project or no project
-
List<MavenProject> projects;
try
{
- projects = getProjectsForMavenReactor( request );
+ projects = getProjectsForMavenReactor( session );
}
catch ( ProjectBuildingException e )
{
return addExceptionToResult( result, e );
}
- session.setProjects( projects );
+ //
+ // This creates the graph and trims the projects down based on the user request using something like:
+ //
+ // -pl project0,project2 eclipse:eclipse
+ //
+ ProjectDependencyGraph projectDependencyGraph = createProjectDependencyGraph( projects, request, result, true );
- result.setTopologicallySortedProjects( session.getProjects() );
+ session.setProjects( projectDependencyGraph.getSortedProjects() );
- result.setProject( session.getTopLevelProject() );
+ if ( result.hasExceptions() )
+ {
+ return result;
+ }
+ //
+ // Desired order of precedence for local artifact repositories
+ //
+ // Reactor
+ // Workspace
+ // User Local Repository
+ //
+ ReactorReader reactorRepository = null;
try
{
- Map<String, MavenProject> projectMap;
- projectMap = getProjectMap( session.getProjects() );
-
- // Desired order of precedence for local artifact repositories
- //
- // Reactor
- // Workspace
- // User Local Repository
- ReactorReader reactorRepository = new ReactorReader( projectMap );
-
- repoSession.setWorkspaceReader( ChainedWorkspaceReader.newInstance( reactorRepository,
- repoSession.getWorkspaceReader() ) );
+ reactorRepository = new ReactorReader( session, getProjectMap( session.getProjects() ) );
}
catch ( DuplicateProjectException e )
{
return addExceptionToResult( result, e );
}
+ repoSession.setWorkspaceReader( ChainedWorkspaceReader.newInstance( reactorRepository,
+ repoSession.getWorkspaceReader() ) );
+
repoSession.setReadOnly();
ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
@@ -280,39 +303,28 @@ public class DefaultMaven
Thread.currentThread().setContextClassLoader( originalClassLoader );
}
- try
- {
- ProjectSorter projectSorter = new ProjectSorter( session.getProjects() );
-
- ProjectDependencyGraph projectDependencyGraph = createDependencyGraph( projectSorter, request );
-
- session.setProjects( projectDependencyGraph.getSortedProjects() );
-
- session.setProjectDependencyGraph( projectDependencyGraph );
- }
- catch ( CycleDetectedException e )
- {
- String message = "The projects in the reactor contain a cyclic reference: " + e.getMessage();
-
- ProjectCycleException error = new ProjectCycleException( message, e );
+ //
+ // The projects need to be topologically after the participants have run their afterProjectsRead(session)
+ // because the participant is free to change the dependencies of a project which can potentially change the
+ // topological order of the projects, and therefore can potentially change the build order.
+ //
+ // Note that participants may affect the topological order of the projects but it is
+ // not expected that a participant will add or remove projects from the session.
+ //
+ projectDependencyGraph = createProjectDependencyGraph( session.getProjects(), request, result, false );
- return addExceptionToResult( result, error );
- }
- catch ( org.apache.maven.project.DuplicateProjectException e )
- {
- return addExceptionToResult( result, e );
- }
- catch ( MavenExecutionException e )
+ if ( result.hasExceptions() )
{
- return addExceptionToResult( result, e );
+ return result;
}
+
+ session.setProjects( projectDependencyGraph.getSortedProjects() );
+
+ session.setProjectDependencyGraph( projectDependencyGraph );
result.setTopologicallySortedProjects( session.getProjects() );
- if ( result.hasExceptions() )
- {
- return result;
- }
+ result.setProject( session.getTopLevelProject() );
lifecycleStarter.execute( session );
@@ -465,8 +477,7 @@ public class DefaultMaven
private String getUserAgent()
{
- return "Apache-Maven/" + getMavenVersion()
- + " (Java " + System.getProperty( "java.version" ) + "; "
+ return "Apache-Maven/" + getMavenVersion() + " (Java " + System.getProperty( "java.version" ) + "; "
+ System.getProperty( "os.name" ) + " " + System.getProperty( "os.version" ) + ")";
}
@@ -563,11 +574,15 @@ public class DefaultMaven
return result;
}
-
- private List<MavenProject> getProjectsForMavenReactor( MavenExecutionRequest request )
+
+ private List<MavenProject> getProjectsForMavenReactor( MavenSession session )
throws ProjectBuildingException
{
- List<MavenProject> projects = new ArrayList<MavenProject>();
+ MavenExecutionRequest request = session.getRequest();
+
+ request.getProjectBuildingRequest().setRepositorySession( session.getRepositorySession() );
+
+ List<MavenProject> projects = new ArrayList<MavenProject>();
// We have no POM file.
//
@@ -582,12 +597,54 @@ public class DefaultMaven
return projects;
}
- List<File> files = Arrays.asList( request.getPom().getAbsoluteFile() );
+ List<File> files = Arrays.asList( request.getPom().getAbsoluteFile() );
collectProjects( projects, files, request );
return projects;
}
- private Map<String, MavenProject> getProjectMap( List<MavenProject> projects )
+ private void collectProjects( List<MavenProject> projects, List<File> files, MavenExecutionRequest request )
+ throws ProjectBuildingException
+ {
+ ProjectBuildingRequest projectBuildingRequest = request.getProjectBuildingRequest();
+
+ List<ProjectBuildingResult> results =
+ projectBuilder.build( files, request.isRecursive(), projectBuildingRequest );
+
+ boolean problems = false;
+
+ for ( ProjectBuildingResult result : results )
+ {
+ projects.add( result.getProject() );
+
+ if ( !result.getProblems().isEmpty() && logger.isWarnEnabled() )
+ {
+ logger.warn( "" );
+ logger.warn( "Some problems were encountered while building the effective model for "
+ + result.getProject().getId() );
+
+ for ( ModelProblem problem : result.getProblems() )
+ {
+ String location = ModelProblemUtils.formatLocation( problem, result.getProjectId() );
+ logger.warn( problem.getMessage() + ( StringUtils.isNotEmpty( location ) ? " @ " + location : "" ) );
+ }
+
+ problems = true;
+ }
+ }
+
+ if ( problems )
+ {
+ logger.warn( "" );
+ logger.warn( "It is highly recommended to fix these problems"
+ + " because they threaten the stability of your build." );
+ logger.warn( "" );
+ logger.warn( "For this reason, future Maven versions might no"
+ + " longer support building such malformed projects." );
+ logger.warn( "" );
+ }
+ }
+
+ private Map<String, MavenProject> getProjectMap( Collection<MavenProject> projects )
throws DuplicateProjectException
{
Map<String, MavenProject> index = new LinkedHashMap<String, MavenProject>();
@@ -629,47 +686,6 @@ public class DefaultMaven
return index;
}
- private void collectProjects( List<MavenProject> projects, List<File> files, MavenExecutionRequest request )
- throws ProjectBuildingException
- {
- ProjectBuildingRequest projectBuildingRequest = request.getProjectBuildingRequest();
-
- List<ProjectBuildingResult> results = projectBuilder.build( files, request.isRecursive(), projectBuildingRequest );
-
- boolean problems = false;
-
- for ( ProjectBuildingResult result : results )
- {
- projects.add( result.getProject() );
-
- if ( !result.getProblems().isEmpty() && logger.isWarnEnabled() )
- {
- logger.warn( "" );
- logger.warn( "Some problems were encountered while building the effective model for "
- + result.getProject().getId() );
-
- for ( ModelProblem problem : result.getProblems() )
- {
- String location = ModelProblemUtils.formatLocation( problem, result.getProjectId() );
- logger.warn( problem.getMessage() + ( StringUtils.isNotEmpty( location ) ? " @ " + location : "" ) );
- }
-
- problems = true;
- }
- }
-
- if ( problems )
- {
- logger.warn( "" );
- logger.warn( "It is highly recommended to fix these problems"
- + " because they threaten the stability of your build." );
- logger.warn( "" );
- logger.warn( "For this reason, future Maven versions might no"
- + " longer support building such malformed projects." );
- logger.warn( "" );
- }
- }
-
private void validateActivatedProfiles( List<MavenProject> projects, List<String> activeProfileIds )
{
Collection<String> notActivatedProfileIds = new LinkedHashSet<String>( activeProfileIds );
@@ -689,27 +705,55 @@ public class DefaultMaven
}
}
+ @Deprecated // 5 January 2014
protected Logger getLogger()
{
return logger;
}
- private ProjectDependencyGraph createDependencyGraph( ProjectSorter sorter, MavenExecutionRequest request )
- throws MavenExecutionException
+ private ProjectDependencyGraph createProjectDependencyGraph( Collection<MavenProject> projects, MavenExecutionRequest request,
+ MavenExecutionResult result, boolean trimming )
{
- ProjectDependencyGraph graph = new DefaultProjectDependencyGraph( sorter );
+ ProjectDependencyGraph projectDependencyGraph = null;
- List<MavenProject> activeProjects = sorter.getSortedProjects();
+ try
+ {
+ ProjectSorter projectSorter = new ProjectSorter( projects );
+
+ projectDependencyGraph = new DefaultProjectDependencyGraph( projectSorter );
- activeProjects = trimSelectedProjects( activeProjects, graph, request );
- activeProjects = trimResumedProjects( activeProjects, request );
+ if ( trimming )
+ {
+ List<MavenProject> activeProjects = projectSorter.getSortedProjects();
- if ( activeProjects.size() != sorter.getSortedProjects().size() )
+ activeProjects = trimSelectedProjects( activeProjects, projectDependencyGraph, request );
+ activeProjects = trimResumedProjects( activeProjects, request );
+
+ if ( activeProjects.size() != projectSorter.getSortedProjects().size() )
+ {
+ projectDependencyGraph =
+ new FilteredProjectDependencyGraph( projectDependencyGraph, activeProjects );
+ }
+ }
+ }
+ catch ( CycleDetectedException e )
+ {
+ String message = "The projects in the reactor contain a cyclic reference: " + e.getMessage();
+
+ ProjectCycleException error = new ProjectCycleException( message, e );
+
+ addExceptionToResult( result, error );
+ }
+ catch ( org.apache.maven.project.DuplicateProjectException e )
+ {
+ addExceptionToResult( result, e );
+ }
+ catch ( MavenExecutionException e )
{
- graph = new FilteredProjectDependencyGraph( graph, activeProjects );
+ addExceptionToResult( result, e );
}
- return graph;
+ return projectDependencyGraph;
}
private List<MavenProject> trimSelectedProjects( List<MavenProject> projects, ProjectDependencyGraph graph,
http://git-wip-us.apache.org/repos/asf/maven/blob/7c3052dd/maven-core/src/main/java/org/apache/maven/ReactorReader.java
----------------------------------------------------------------------
diff --git a/maven-core/src/main/java/org/apache/maven/ReactorReader.java b/maven-core/src/main/java/org/apache/maven/ReactorReader.java
index bc37eb7..b96bbed 100644
--- a/maven-core/src/main/java/org/apache/maven/ReactorReader.java
+++ b/maven-core/src/main/java/org/apache/maven/ReactorReader.java
@@ -30,6 +30,7 @@ import java.util.List;
import java.util.Map;
import org.apache.maven.artifact.ArtifactUtils;
+import org.apache.maven.execution.MavenSession;
import org.apache.maven.project.MavenProject;
import org.eclipse.aether.artifact.Artifact;
import org.eclipse.aether.repository.WorkspaceReader;
@@ -52,7 +53,7 @@ class ReactorReader
private WorkspaceRepository repository;
- public ReactorReader( Map<String, MavenProject> reactorProjects )
+ public ReactorReader( MavenSession session, Map<String, MavenProject> reactorProjects )
{
projectsByGAV = reactorProjects;
@@ -72,18 +73,18 @@ class ReactorReader
projects.add( project );
}
- repository = new WorkspaceRepository( "reactor", new HashSet<String>( projectsByGAV.keySet() ) );
+ repository = new WorkspaceRepository( "reactor", new HashSet<String>( projectsByGAV.keySet() ) );
}
//
// Public API
//
-
+
public WorkspaceRepository getRepository()
{
return repository;
}
-
+
public File findArtifact( Artifact artifact )
{
String projectKey = ArtifactUtils.key( artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion() );
@@ -124,12 +125,12 @@ class ReactorReader
}
return Collections.unmodifiableList( versions );
- }
-
+ }
+
//
// Implementation
//
-
+
private File find( MavenProject project, Artifact artifact )
{
if ( "pom".equals( artifact.getExtension() ) )
@@ -143,7 +144,7 @@ class ReactorReader
{
return projectArtifact.getFile();
}
- else if ( !hasBeenPackaged( project ) )
+ else if ( !hasBeenPackaged( project ) )
{
// fallback to loose class files only if artifacts haven't been packaged yet
// and only for plain old jars. Not war files, not ear files, not anything else.
@@ -186,9 +187,7 @@ class ReactorReader
*
* @param project The project to try to resolve the artifact from, must not be <code>null</code>.
* @param requestedArtifact The artifact to resolve, must not be <code>null</code>.
- * @return The matching artifact from the project or <code>null</code> if not found.
- *
- * Note that this
+ * @return The matching artifact from the project or <code>null</code> if not found. Note that this
*/
private Artifact findMatchingArtifact( MavenProject project, Artifact requestedArtifact )
{
@@ -202,7 +201,7 @@ class ReactorReader
for ( Artifact attachedArtifact : RepositoryUtils.toArtifacts( project.getAttachedArtifacts() ) )
{
- if ( attachedArtifactComparison ( requestedArtifact, attachedArtifact ) )
+ if ( attachedArtifactComparison( requestedArtifact, attachedArtifact ) )
{
return attachedArtifact;
}
@@ -222,7 +221,7 @@ class ReactorReader
&& requested.getVersion().equals( attached.getVersion() )
&& requested.getExtension().equals( attached.getExtension() )
&& requested.getClassifier().equals( attached.getClassifier() );
- }
+ }
/**
* Determines whether the specified artifact refers to test classes.
http://git-wip-us.apache.org/repos/asf/maven/blob/7c3052dd/maven-core/src/main/java/org/apache/maven/project/ProjectSorter.java
----------------------------------------------------------------------
diff --git a/maven-core/src/main/java/org/apache/maven/project/ProjectSorter.java b/maven-core/src/main/java/org/apache/maven/project/ProjectSorter.java
index d0ffa71..16985e2 100644
--- a/maven-core/src/main/java/org/apache/maven/project/ProjectSorter.java
+++ b/maven-core/src/main/java/org/apache/maven/project/ProjectSorter.java
@@ -20,6 +20,7 @@ package org.apache.maven.project;
*/
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
@@ -70,7 +71,7 @@ public class ProjectSorter
// In this case, both the verify and the report goals are called
// in a different lifecycle. Though the compiler-plugin has a valid usecase, although
// that seems to work fine. We need to take versions and lifecycle into account.
- public ProjectSorter( List<MavenProject> projects )
+ public ProjectSorter( Collection<MavenProject> projects )
throws CycleDetectedException, DuplicateProjectException
{
dag = new DAG();