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();