View Javadoc
1   package org.apache.maven.project;
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 static org.hamcrest.Matchers.hasItem;
23  import static org.junit.Assert.assertEquals;
24  import static org.junit.Assert.assertThat;
25  
26  import java.util.ArrayList;
27  import java.util.Collections;
28  import java.util.List;
29  
30  import org.apache.maven.model.Build;
31  import org.apache.maven.model.Dependency;
32  import org.apache.maven.model.Extension;
33  import org.apache.maven.model.Model;
34  import org.apache.maven.model.Parent;
35  import org.apache.maven.model.Plugin;
36  import org.apache.maven.model.PluginManagement;
37  import org.junit.Rule;
38  import org.junit.Test;
39  import org.junit.rules.ExpectedException;
40  
41  /**
42   * Test sorting projects by dependencies.
43   *
44   * @author <a href="mailto:brett@apache.org">Brett Porter</a>
45   */
46  public class ProjectSorterTest
47  {
48      @Rule
49      public ExpectedException expectedException = ExpectedException.none();
50  
51      private Parent createParent( MavenProject project )
52      {
53          return createParent( project.getGroupId(), project.getArtifactId(), project.getVersion() );
54      }
55  
56      private Parent createParent( String groupId, String artifactId, String version )
57      {
58          Parent plugin = new Parent();
59          plugin.setGroupId( groupId );
60          plugin.setArtifactId( artifactId );
61          plugin.setVersion( version );
62          return plugin;
63      }
64  
65      private Dependency createDependency( MavenProject project )
66      {
67          return createDependency( project.getGroupId(), project.getArtifactId(), project.getVersion() );
68      }
69  
70      private Dependency createDependency( String groupId, String artifactId, String version )
71      {
72          Dependency dependency = new Dependency();
73          dependency.setGroupId( groupId );
74          dependency.setArtifactId( artifactId );
75          dependency.setVersion( version );
76          return dependency;
77      }
78  
79      private Plugin createPlugin( MavenProject project )
80      {
81          return createPlugin( project.getGroupId(), project.getArtifactId(), project.getVersion() );
82      }
83  
84      private Plugin createPlugin( String groupId, String artifactId, String version )
85      {
86          Plugin plugin = new Plugin();
87          plugin.setGroupId( groupId );
88          plugin.setArtifactId( artifactId );
89          plugin.setVersion( version );
90          return plugin;
91      }
92  
93      private Extension createExtension( String groupId, String artifactId, String version )
94      {
95          Extension extension = new Extension();
96          extension.setGroupId( groupId );
97          extension.setArtifactId( artifactId );
98          extension.setVersion( version );
99          return extension;
100     }
101 
102     private static MavenProject createProject( String groupId, String artifactId, String version )
103     {
104         Model model = new Model();
105         model.setGroupId( groupId );
106         model.setArtifactId( artifactId );
107         model.setVersion( version );
108         model.setBuild( new Build() );
109         return new MavenProject( model );
110     }
111 
112     @Test
113     public void testShouldNotFailWhenPluginDepReferencesCurrentProject()
114         throws Exception
115     {
116         MavenProject project = createProject( "group", "artifact", "1.0" );
117 
118         Build build = project.getModel().getBuild();
119 
120         Plugin plugin = createPlugin( "other.group", "other-artifact", "1.0" );
121 
122         Dependency dep = createDependency( "group", "artifact", "1.0" );
123 
124         plugin.addDependency( dep );
125 
126         build.addPlugin( plugin );
127 
128         new ProjectSorter( Collections.singletonList( project ) );
129     }
130 
131     @Test
132     public void testShouldNotFailWhenManagedPluginDepReferencesCurrentProject()
133         throws Exception
134     {
135         MavenProject project = createProject( "group", "artifact", "1.0" );
136 
137         Build build = project.getModel().getBuild();
138 
139         PluginManagement pMgmt = new PluginManagement();
140 
141         Plugin plugin = createPlugin( "other.group", "other-artifact", "1.0" );
142 
143         Dependency dep = createDependency( "group", "artifact", "1.0" );
144 
145         plugin.addDependency( dep );
146 
147         pMgmt.addPlugin( plugin );
148 
149         build.setPluginManagement( pMgmt );
150 
151         new ProjectSorter( Collections.singletonList( project ) );
152     }
153 
154     @Test
155     public void testShouldNotFailWhenProjectReferencesNonExistentProject()
156         throws Exception
157     {
158         MavenProject project = createProject( "group", "artifact", "1.0" );
159 
160         Build build = project.getModel().getBuild();
161 
162         Extension extension = createExtension( "other.group", "other-artifact", "1.0" );
163 
164         build.addExtension( extension );
165 
166         new ProjectSorter( Collections.singletonList( project ) );
167     }
168 
169     @Test
170     public void testMatchingArtifactIdsDifferentGroupIds()
171         throws Exception
172     {
173         List<MavenProject> projects = new ArrayList<>();
174         MavenProject project1 = createProject( "groupId1", "artifactId", "1.0" );
175         projects.add( project1 );
176         MavenProject project2 = createProject( "groupId2", "artifactId", "1.0" );
177         projects.add( project2 );
178         project1.getDependencies().add( createDependency( project2 ) );
179 
180         projects = new ProjectSorter( projects ).getSortedProjects();
181 
182         assertEquals( project2, projects.get( 0 ) );
183         assertEquals( project1, projects.get( 1 ) );
184     }
185 
186     @Test
187     public void testMatchingGroupIdsDifferentArtifactIds()
188         throws Exception
189     {
190         List<MavenProject> projects = new ArrayList<>();
191         MavenProject project1 = createProject( "groupId", "artifactId1", "1.0" );
192         projects.add( project1 );
193         MavenProject project2 = createProject( "groupId", "artifactId2", "1.0" );
194         projects.add( project2 );
195         project1.getDependencies().add( createDependency( project2 ) );
196 
197         projects = new ProjectSorter( projects ).getSortedProjects();
198 
199         assertEquals( project2, projects.get( 0 ) );
200         assertEquals( project1, projects.get( 1 ) );
201     }
202 
203     @Test
204     public void testMatchingIdsAndVersions()
205         throws Exception
206     {
207         List<MavenProject> projects = new ArrayList<>();
208         MavenProject project1 = createProject( "groupId", "artifactId", "1.0" );
209         projects.add( project1 );
210         MavenProject project2 = createProject( "groupId", "artifactId", "1.0" );
211         projects.add( project2 );
212         
213         expectedException.expect( DuplicateProjectException.class );
214         expectedException.reportMissingExceptionWithMessage( "Duplicate projects should fail" );
215 
216         new ProjectSorter( projects ).getSortedProjects();
217     }
218 
219     @Test
220     public void testMatchingIdsAndDifferentVersions()
221         throws Exception
222     {
223         List<MavenProject> projects = new ArrayList<>();
224         MavenProject project1 = createProject( "groupId", "artifactId", "1.0" );
225         projects.add( project1 );
226         MavenProject project2 = createProject( "groupId", "artifactId", "2.0" );
227         projects.add( project2 );
228 
229         projects = new ProjectSorter( projects ).getSortedProjects();
230         assertEquals( project1, projects.get( 0 ) );
231         assertEquals( project2, projects.get( 1 ) );
232     }
233 
234     @Test
235     public void testPluginDependenciesInfluenceSorting()
236         throws Exception
237     {
238         List<MavenProject> projects = new ArrayList<>();
239 
240         MavenProject parentProject = createProject( "groupId", "parent", "1.0" );
241         projects.add( parentProject );
242 
243         MavenProject declaringProject = createProject( "groupId", "declarer", "1.0" );
244         declaringProject.setParent( parentProject );
245         declaringProject.getModel().setParent( createParent( parentProject ) );
246         projects.add( declaringProject );
247 
248         MavenProject pluginLevelDepProject = createProject( "groupId", "plugin-level-dep", "1.0" );
249         pluginLevelDepProject.setParent( parentProject );
250         pluginLevelDepProject.getModel().setParent( createParent( parentProject ) );
251         projects.add( pluginLevelDepProject );
252 
253         MavenProject pluginProject = createProject( "groupId", "plugin", "1.0" );
254         pluginProject.setParent( parentProject );
255         pluginProject.getModel().setParent( createParent( parentProject ) );
256         projects.add( pluginProject );
257 
258         Plugin plugin = createPlugin( pluginProject );
259 
260         plugin.addDependency( createDependency( pluginLevelDepProject ) );
261 
262         Build build = declaringProject.getModel().getBuild();
263 
264         build.addPlugin( plugin );
265 
266         projects = new ProjectSorter( projects ).getSortedProjects();
267 
268         assertEquals( parentProject, projects.get( 0 ) );
269 
270         // the order of these two is non-deterministic, based on when they're added to the reactor.
271         assertThat( projects, hasItem( pluginProject ) );
272         assertThat( projects, hasItem( pluginLevelDepProject ) );
273 
274         // the declaring project MUST be listed after the plugin and its plugin-level dep, though.
275         assertEquals( declaringProject, projects.get( 3 ) );
276     }
277 
278     @Test
279     public void testPluginDependenciesInfluenceSorting_DeclarationInParent()
280         throws Exception
281     {
282         List<MavenProject> projects = new ArrayList<>();
283 
284         MavenProject parentProject = createProject( "groupId", "parent-declarer", "1.0" );
285         projects.add( parentProject );
286 
287         MavenProject pluginProject = createProject( "groupId", "plugin", "1.0" );
288         pluginProject.setParent( parentProject );
289         pluginProject.getModel().setParent( createParent( parentProject ) );
290         projects.add( pluginProject );
291 
292         MavenProject pluginLevelDepProject = createProject( "groupId", "plugin-level-dep", "1.0" );
293         pluginLevelDepProject.setParent( parentProject );
294         pluginLevelDepProject.getModel().setParent( createParent( parentProject ) );
295         projects.add( pluginLevelDepProject );
296 
297         Plugin plugin = createPlugin( pluginProject );
298 
299         plugin.addDependency( createDependency( pluginLevelDepProject ) );
300 
301         Build build = parentProject.getModel().getBuild();
302 
303         build.addPlugin( plugin );
304 
305         projects = new ProjectSorter( projects ).getSortedProjects();
306 
307         assertEquals( parentProject, projects.get( 0 ) );
308 
309         // the order of these two is non-deterministic, based on when they're added to the reactor.
310         assertThat( projects, hasItem( pluginProject ) );
311         assertThat( projects, hasItem( pluginLevelDepProject ) );
312     }
313 
314     @Test
315     public void testPluginVersionsAreConsidered()
316         throws Exception
317     {
318         List<MavenProject> projects = new ArrayList<>();
319 
320         MavenProject pluginProjectA = createProject( "group", "plugin-a", "2.0-SNAPSHOT" );
321         projects.add( pluginProjectA );
322         pluginProjectA.getModel().getBuild().addPlugin( createPlugin( "group", "plugin-b", "1.0" ) );
323 
324         MavenProject pluginProjectB = createProject( "group", "plugin-b", "2.0-SNAPSHOT" );
325         projects.add( pluginProjectB );
326         pluginProjectB.getModel().getBuild().addPlugin( createPlugin( "group", "plugin-a", "1.0" ) );
327 
328         projects = new ProjectSorter( projects ).getSortedProjects();
329 
330         assertThat( projects, hasItem( pluginProjectA ) );
331         assertThat( projects, hasItem( pluginProjectB ) );
332     }
333 
334     @Test
335     public void testDependencyPrecedesProjectThatUsesSpecificDependencyVersion()
336         throws Exception
337     {
338         List<MavenProject> projects = new ArrayList<>();
339 
340         MavenProject usingProject = createProject( "group", "project", "1.0" );
341         projects.add( usingProject );
342         usingProject.getModel().addDependency( createDependency( "group", "dependency", "1.0" ) );
343 
344         MavenProject pluginProject = createProject( "group", "dependency", "1.0" );
345         projects.add( pluginProject );
346 
347         projects = new ProjectSorter( projects ).getSortedProjects();
348 
349         assertEquals( pluginProject, projects.get( 0 ) );
350         assertEquals( usingProject, projects.get( 1 ) );
351     }
352 
353     @Test
354     public void testDependencyPrecedesProjectThatUsesUnresolvedDependencyVersion()
355         throws Exception
356     {
357         List<MavenProject> projects = new ArrayList<>();
358 
359         MavenProject usingProject = createProject( "group", "project", "1.0" );
360         projects.add( usingProject );
361         usingProject.getModel().addDependency( createDependency( "group", "dependency", "[1.0,)" ) );
362 
363         MavenProject pluginProject = createProject( "group", "dependency", "1.0" );
364         projects.add( pluginProject );
365 
366         projects = new ProjectSorter( projects ).getSortedProjects();
367 
368         assertEquals( pluginProject, projects.get( 0 ) );
369         assertEquals( usingProject, projects.get( 1 ) );
370     }
371 
372 }