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