View Javadoc

1   package org.apache.maven.plugin.reactor;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.File;
23  import java.util.ArrayList;
24  import java.util.Arrays;
25  import java.util.HashSet;
26  import java.util.List;
27  import java.util.Set;
28  
29  import org.apache.maven.artifact.ArtifactUtils;
30  import org.apache.maven.plugin.AbstractMojo;
31  import org.apache.maven.plugin.MojoExecutionException;
32  import org.apache.maven.plugin.MojoFailureException;
33  import org.apache.maven.project.MavenProject;
34  import org.apache.maven.shared.invoker.Invoker;
35  import org.codehaus.plexus.util.StringUtils;
36  import org.codehaus.plexus.util.dag.DAG;
37  import org.codehaus.plexus.util.dag.Vertex;
38  
39  /**
40   * Goal to build a project X and all of the reactor projects on which X depends 
41   *
42   * @author <a href="mailto:dfabulich@apache.org">Dan Fabulich</a>
43   * @goal make
44   * @aggregator
45   * @phase process-sources
46   */
47  public class MakeMojo
48      extends AbstractMojo
49  {
50      /**
51       * Location of the POM file; provided by Maven
52       * @parameter expression="${basedir}"
53       * 
54       */
55      File baseDir;
56      
57      /**
58       * A list of every project in this reactor; provided by Maven
59       * @parameter expression="${project.collectedProjects}"
60       */
61      List collectedProjects;
62      
63      /**
64       * If you don't specify a groupId in your artifactList, we'll use this as the default groupId.
65       * @parameter expression="${make.group}" default-value="${project.groupId}"
66       * 
67       */
68      String defaultGroup;
69      
70      /**
71       * A list of artifacts to build, e.g. "com.mycompany:bar,com.mycompany:foo" or just "foo,bar", or just "foo" 
72       * @parameter expression="${make.artifacts}" default-value=""
73       * @required
74       */
75      String artifactList;
76      
77      /**
78       * A list of relative paths to build, e.g. "foo,baz/bar"
79       * @parameter expression="${make.folders}" default-value=""
80       * @required
81       */
82      String folderList;
83      
84      /**
85       * Goals to run on subproject.
86       * @parameter expression="${make.goals}" default-value="install"
87       */
88      String goals;
89      
90      /**
91       * Provided by Maven
92       * @component
93       */
94      Invoker invoker;
95      
96      /**
97       * Don't really do anything; just print a command that describes what the command would have done
98       * @parameter expression="${make.printOnly}"
99       */
100     private boolean printOnly = false;
101     
102     /**
103      * @component
104      */
105     SimpleInvoker simpleInvoker;
106     
107     /**
108      * The artifact from which we'll resume, e.g. "com.mycompany:foo" or just "foo"
109      * @parameter expression="${fromArtifact}"
110      */
111     String continueFromProject;
112     
113     /**
114      * The project folder from which we'll resume
115      * @parameter expression="${from}"
116      */
117     File continueFromFolder;
118     
119     public void execute()
120         throws MojoExecutionException, MojoFailureException
121     {
122         if ( artifactList == null && folderList == null ) {
123             throw new MojoFailureException("You must specify either folders or projects with -Dmake.folders=foo,baz/bar or -Dmake.projects=com.mycompany:foo,com.mycompany:bar");
124         }
125         String[] reactorIncludes;
126         List sortedProjects;
127         try
128         {
129             if (collectedProjects.size() == 0) {
130                 throw new NonReactorException();
131             }
132             SuperProjectSorter ps = new SuperProjectSorter( collectedProjects );
133             DAG dag = ps.getDAG();
134             
135             // gather projects
136             collectArtifactListFromFolderList( collectedProjects );
137             String[] artifacts = StringUtils.split( artifactList, "," );
138             Set visited = new HashSet();
139             Set out = new HashSet();
140             for (int i = 0; i < artifacts.length; i++) {
141                 String project = artifacts[i];
142                 if ( project.indexOf(':') == -1 ) {
143                     project = defaultGroup + ":" + project;
144                 }
145                 Vertex projectVertex = dag.getVertex( project );
146                 if ( projectVertex == null ) throw new MissingProjectException(project);
147                 gatherProjects( projectVertex, ps, visited, out );
148             }
149             
150             // sort them again
151             ps = new SuperProjectSorter( new ArrayList( out ) );
152             sortedProjects = ps.getSortedProjects();
153             
154             // construct array of relative POM paths
155             reactorIncludes = new String[sortedProjects.size()];
156             for ( int i = 0; i < sortedProjects.size(); i++ )
157             {
158                 MavenProject mp = (MavenProject) sortedProjects.get( i );
159                 String path = RelativePather.getRelativePath( baseDir, mp.getFile() );
160                 reactorIncludes[i] = path;
161             }
162         }
163         catch (MojoFailureException e) {
164             throw e;
165         }        
166         catch ( Exception e )
167         {
168             throw new MojoExecutionException( "Problem generating dependency tree", e );
169         }
170 
171         if (continueFromFolder != null || continueFromProject != null) {
172             ResumeMojo resumer = new ResumeMojo();
173             resumer.baseDir = baseDir;
174             resumer.collectedProjects = sortedProjects;
175             resumer.continueFromFolder = continueFromFolder;
176             resumer.continueFromProject = continueFromProject;
177             resumer.goals = goals;
178             resumer.invoker = invoker;
179             resumer.simpleInvoker = simpleInvoker;
180             resumer.printOnly = printOnly;
181             resumer.continueFromGroup = defaultGroup;
182             resumer.execute();
183         } else {
184             simpleInvoker.runReactor( reactorIncludes, Arrays.asList( goals.split( "," ) ), invoker, printOnly, getLog() );
185         }
186 
187     }
188 
189     void collectArtifactListFromFolderList(List collectedProjects) throws MojoFailureException
190     {
191         if ( folderList == null )
192             return;
193         String[] folders = StringUtils.split( folderList, "," );
194         Set pathSet = new HashSet();
195         for ( int i = 0; i < folders.length; i++ )
196         {
197             File file = new File( baseDir, folders[i] );
198             if ( !file.exists() )
199             {
200                 throw new MojoFailureException("Folder doesn't exist: " + file.getAbsolutePath() );
201             }
202             String path = file.getAbsolutePath();
203             pathSet.add( path );
204         }
205         if (artifactList == null) artifactList = "";
206         StringBuffer artifactBuffer = new StringBuffer(artifactList);
207         for ( int i = 0; i < collectedProjects.size(); i++ )
208         {
209             MavenProject mp = (MavenProject) collectedProjects.get( i );
210             if ( pathSet.contains( mp.getFile().getParentFile().getAbsolutePath() ) )
211             {
212                 if ( artifactBuffer.length() > 0 )
213                 {
214                     artifactBuffer.append( ',' );
215                 }
216                 String id = ArtifactUtils.versionlessKey( mp.getGroupId(), mp.getArtifactId() );
217                 artifactBuffer.append( id );
218             }
219         }
220         if ( artifactBuffer.length() == 0 )
221         {
222             throw new MojoFailureException("No folders matched: " + folderList);
223         }
224         artifactList = artifactBuffer.toString();
225     }
226 
227     protected Set gatherProjects( Vertex v, SuperProjectSorter ps, Set visited, Set out )
228     {
229         visited.add( v );
230         out.add( ps.getProjectMap().get( v.getLabel() ) );
231         List children = v.getChildren();
232         for ( int i = 0; i < children.size(); i++ )
233         {
234             Vertex child = (Vertex) children.get( i );
235             if ( visited.contains( child ) )
236                 continue;
237             gatherProjects( child, ps, visited, out );
238         }
239         return out;
240     }
241 }