1 package org.apache.maven.plugin.invoker;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.File;
23 import java.io.IOException;
24 import java.util.Collection;
25 import java.util.Collections;
26 import java.util.HashMap;
27 import java.util.HashSet;
28 import java.util.LinkedHashSet;
29 import java.util.List;
30 import java.util.Map;
31 import java.util.Set;
32
33 import org.apache.maven.artifact.Artifact;
34 import org.apache.maven.artifact.factory.ArtifactFactory;
35 import org.apache.maven.artifact.installer.ArtifactInstaller;
36 import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
37 import org.apache.maven.artifact.repository.ArtifactRepository;
38 import org.apache.maven.artifact.repository.ArtifactRepositoryFactory;
39 import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
40 import org.apache.maven.artifact.resolver.ArtifactResolver;
41 import org.apache.maven.model.Model;
42 import org.apache.maven.model.Parent;
43 import org.apache.maven.plugin.AbstractMojo;
44 import org.apache.maven.plugin.MojoExecutionException;
45 import org.apache.maven.plugins.annotations.Component;
46 import org.apache.maven.plugins.annotations.LifecyclePhase;
47 import org.apache.maven.plugins.annotations.Mojo;
48 import org.apache.maven.plugins.annotations.Parameter;
49 import org.apache.maven.plugins.annotations.ResolutionScope;
50 import org.apache.maven.project.MavenProject;
51 import org.codehaus.plexus.util.FileUtils;
52
53
54
55
56
57
58
59
60
61
62
63 @Mojo( name = "install", defaultPhase = LifecyclePhase.PRE_INTEGRATION_TEST, requiresDependencyResolution = ResolutionScope.RUNTIME, threadSafe = true )
64 public class InstallMojo
65 extends AbstractMojo
66 {
67
68
69
70
71 @Component
72 private ArtifactInstaller installer;
73
74
75
76
77 @Component
78 private ArtifactFactory artifactFactory;
79
80
81
82
83 @Component
84 private ArtifactRepositoryFactory repositoryFactory;
85
86
87
88 @Parameter( property = "localRepository", required = true, readonly = true )
89 private ArtifactRepository localRepository;
90
91
92
93
94
95
96
97 @Parameter( property = "invoker.localRepositoryPath" )
98 private File localRepositoryPath;
99
100
101
102
103 @Component
104 private MavenProject project;
105
106
107
108
109 @Parameter( defaultValue = "${reactorProjects}", readonly = true )
110 private Collection<MavenProject> reactorProjects;
111
112
113
114
115
116
117
118 @Parameter( property = "invoker.skip", defaultValue = "false" )
119 private boolean skipInstallation;
120
121
122
123
124 private Collection<String> installedArtifacts;
125
126
127
128
129 private Collection<String> copiedArtifacts;
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151 @Parameter
152 private String[] extraArtifacts;
153
154
155
156 @Component
157 private ArtifactResolver resolver;
158
159
160
161 @Parameter( defaultValue = "${project.remoteArtifactRepositories}", readonly = true )
162 private List<ArtifactRepository> remoteArtifactRepositories;
163
164
165
166 @Parameter( defaultValue = "${project.pluginArtifactRepositories}", readonly = true )
167 private List<ArtifactRepository> remotePluginRepositories;
168
169
170
171 @Component
172 private ArtifactMetadataSource artifactMetadataSource;
173
174
175
176
177
178
179 public void execute()
180 throws MojoExecutionException
181 {
182 if ( skipInstallation )
183 {
184 getLog().info( "Skipping artifact installation per configuration." );
185 return;
186 }
187
188 ArtifactRepository testRepository = createTestRepository();
189
190 installedArtifacts = new HashSet<String>();
191 copiedArtifacts = new HashSet<String>();
192
193 installProjectDependencies( project, reactorProjects, testRepository );
194 installProjectParents( project, testRepository );
195 installProjectArtifacts( project, testRepository );
196
197 installExtraArtifacts( testRepository, extraArtifacts );
198 }
199
200
201
202
203
204
205
206
207
208
209 private ArtifactRepository createTestRepository()
210 throws MojoExecutionException
211 {
212 ArtifactRepository testRepository = localRepository;
213
214 if ( localRepositoryPath != null )
215 {
216 try
217 {
218 if ( !localRepositoryPath.exists() && !localRepositoryPath.mkdirs() )
219 {
220 throw new IOException( "Failed to create directory: " + localRepositoryPath );
221 }
222
223 testRepository =
224 repositoryFactory.createArtifactRepository( localRepository.getId(),
225 localRepositoryPath.toURL().toExternalForm(),
226 localRepository.getLayout(),
227 localRepository.getSnapshots(),
228 localRepository.getReleases() );
229 }
230 catch ( Exception e )
231 {
232 throw new MojoExecutionException( "Failed to create local repository: " + localRepositoryPath, e );
233 }
234 }
235
236 return testRepository;
237 }
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252 private void installArtifact( File file, Artifact artifact, ArtifactRepository testRepository )
253 throws MojoExecutionException
254 {
255 try
256 {
257 if ( file == null )
258 {
259 throw new IllegalStateException( "Artifact has no associated file: " + artifact.getId() );
260 }
261 if ( !file.isFile() )
262 {
263 throw new IllegalStateException( "Artifact is not fully assembled: " + file );
264 }
265
266 if ( installedArtifacts.add( artifact.getId() ) )
267 {
268 installer.install( file, artifact, testRepository );
269 }
270 else
271 {
272 getLog().debug( "Not re-installing " + artifact + ", " + file );
273 }
274 }
275 catch ( Exception e )
276 {
277 throw new MojoExecutionException( "Failed to install artifact: " + artifact, e );
278 }
279 }
280
281
282
283
284
285
286
287
288
289
290
291
292
293 private void copyArtifact( File file, Artifact artifact, ArtifactRepository testRepository )
294 throws MojoExecutionException
295 {
296 try
297 {
298 if ( file == null )
299 {
300 throw new IllegalStateException( "Artifact has no associated file: " + artifact.getId() );
301 }
302 if ( !file.isFile() )
303 {
304 throw new IllegalStateException( "Artifact is not fully assembled: " + file );
305 }
306
307 if ( copiedArtifacts.add( artifact.getId() ) )
308 {
309 File destination = new File( testRepository.getBasedir(), testRepository.pathOf( artifact ) );
310
311 getLog().debug( "Installing " + file + " to " + destination );
312
313 copyFileIfDifferent( file, destination );
314
315 MetadataUtils.createMetadata( destination, artifact );
316 }
317 else
318 {
319 getLog().debug( "Not re-installing " + artifact + ", " + file );
320 }
321 }
322 catch ( Exception e )
323 {
324 throw new MojoExecutionException( "Failed to stage artifact: " + artifact, e );
325 }
326 }
327
328 private void copyFileIfDifferent( File src, File dst )
329 throws IOException
330 {
331 if ( src.lastModified() != dst.lastModified() || src.length() != dst.length() )
332 {
333 FileUtils.copyFile( src, dst );
334 dst.setLastModified( src.lastModified() );
335 }
336 }
337
338
339
340
341
342
343
344
345 private void installProjectArtifacts( MavenProject mvnProject, ArtifactRepository testRepository )
346 throws MojoExecutionException
347 {
348 try
349 {
350
351 installProjectPom( mvnProject, testRepository );
352
353
354 Artifact mainArtifact = mvnProject.getArtifact();
355 if ( mainArtifact.getFile() != null )
356 {
357 installArtifact( mainArtifact.getFile(), mainArtifact, testRepository );
358 }
359
360
361 Collection<Artifact> attachedArtifacts = (Collection<Artifact>) mvnProject.getAttachedArtifacts();
362 for ( Artifact attachedArtifact : attachedArtifacts )
363 {
364 installArtifact( attachedArtifact.getFile(), attachedArtifact, testRepository );
365 }
366 }
367 catch ( Exception e )
368 {
369 throw new MojoExecutionException( "Failed to install project artifacts: " + mvnProject, e );
370 }
371 }
372
373
374
375
376
377
378
379
380
381 private void installProjectParents( MavenProject mvnProject, ArtifactRepository testRepository )
382 throws MojoExecutionException
383 {
384 try
385 {
386 for ( MavenProject parent = mvnProject.getParent(); parent != null; parent = parent.getParent() )
387 {
388 if ( parent.getFile() == null )
389 {
390 copyParentPoms( parent.getGroupId(), parent.getArtifactId(), parent.getVersion(), testRepository );
391 break;
392 }
393 installProjectPom( parent, testRepository );
394 }
395 }
396 catch ( Exception e )
397 {
398 throw new MojoExecutionException( "Failed to install project parents: " + mvnProject, e );
399 }
400 }
401
402
403
404
405
406
407
408
409 private void installProjectPom( MavenProject mvnProject, ArtifactRepository testRepository )
410 throws MojoExecutionException
411 {
412 try
413 {
414 Artifact pomArtifact = null;
415 if ( "pom".equals( mvnProject.getPackaging() ) )
416 {
417 pomArtifact = mvnProject.getArtifact();
418 }
419 if ( pomArtifact == null )
420 {
421 pomArtifact =
422 artifactFactory.createProjectArtifact( mvnProject.getGroupId(), mvnProject.getArtifactId(),
423 mvnProject.getVersion() );
424 }
425 installArtifact( mvnProject.getFile(), pomArtifact, testRepository );
426 }
427 catch ( Exception e )
428 {
429 throw new MojoExecutionException( "Failed to install POM: " + mvnProject, e );
430 }
431 }
432
433
434
435
436
437
438
439
440
441
442 private void installProjectDependencies( MavenProject mvnProject, Collection<MavenProject> reactorProjects,
443 ArtifactRepository testRepository )
444 throws MojoExecutionException
445 {
446
447 boolean foundCurrent = false;
448
449
450 Collection<String> dependencyProjects = new LinkedHashSet<String>();
451
452
453 Map<String, MavenProject> projects = new HashMap<String, MavenProject>();
454 for ( MavenProject reactorProject : reactorProjects )
455 {
456 String projectId =
457 reactorProject.getGroupId() + ':' + reactorProject.getArtifactId() + ':' + reactorProject.getVersion();
458
459 projects.put( projectId, reactorProject );
460
461
462 if ( !( foundCurrent |= ( mvnProject.equals( reactorProject ) ) ) )
463 {
464 dependencyProjects.add( projectId );
465 }
466 }
467
468
469 Collection<Artifact> artifacts = (Collection<Artifact>) mvnProject.getArtifacts();
470
471 Collection<Artifact> dependencyArtifacts = new LinkedHashSet<Artifact>();
472
473 for ( Artifact artifact : artifacts )
474 {
475
476 artifact.isSnapshot();
477
478 String projectId = artifact.getGroupId() + ':' + artifact.getArtifactId() + ':' + artifact.getBaseVersion();
479
480 if ( !projects.containsKey( projectId ) )
481 {
482 dependencyArtifacts.add( artifact );
483 }
484 }
485
486
487 try
488 {
489
490 for ( Artifact artifact : dependencyArtifacts )
491 {
492 copyArtifact( artifact, testRepository );
493 }
494
495
496 for ( String projectId : dependencyProjects )
497 {
498 MavenProject dependencyProject = projects.get( projectId );
499
500 installProjectArtifacts( dependencyProject, testRepository );
501 installProjectParents( dependencyProject, testRepository );
502 }
503 }
504 catch ( Exception e )
505 {
506 throw new MojoExecutionException( "Failed to install project dependencies: " + mvnProject, e );
507 }
508 }
509
510 private void copyArtifact( Artifact artifact, ArtifactRepository testRepository )
511 throws MojoExecutionException
512 {
513 copyPoms( artifact, testRepository );
514
515 Artifact depArtifact =
516 artifactFactory.createArtifactWithClassifier( artifact.getGroupId(), artifact.getArtifactId(),
517 artifact.getBaseVersion(), artifact.getType(),
518 artifact.getClassifier() );
519
520 File artifactFile = artifact.getFile();
521
522 copyArtifact( artifactFile, depArtifact, testRepository );
523 }
524
525 private void copyPoms( Artifact artifact, ArtifactRepository testRepository )
526 throws MojoExecutionException
527 {
528 Artifact pomArtifact =
529 artifactFactory.createProjectArtifact( artifact.getGroupId(), artifact.getArtifactId(),
530 artifact.getBaseVersion() );
531
532 File pomFile = new File( localRepository.getBasedir(), localRepository.pathOf( pomArtifact ) );
533
534 if ( pomFile.isFile() )
535 {
536 copyArtifact( pomFile, pomArtifact, testRepository );
537 copyParentPoms( pomFile, testRepository );
538 }
539 }
540
541
542
543
544
545
546
547
548 private void copyParentPoms( File pomFile, ArtifactRepository testRepository )
549 throws MojoExecutionException
550 {
551 Model model = PomUtils.loadPom( pomFile );
552 Parent parent = model.getParent();
553 if ( parent != null )
554 {
555 copyParentPoms( parent.getGroupId(), parent.getArtifactId(), parent.getVersion(), testRepository );
556 }
557 }
558
559
560
561
562
563
564
565
566
567
568 private void copyParentPoms( String groupId, String artifactId, String version, ArtifactRepository testRepository )
569 throws MojoExecutionException
570 {
571 Artifact pomArtifact = artifactFactory.createProjectArtifact( groupId, artifactId, version );
572
573 if ( installedArtifacts.contains( pomArtifact.getId() ) || copiedArtifacts.contains( pomArtifact.getId() ) )
574 {
575 getLog().debug( "Not re-installing " + pomArtifact );
576 return;
577 }
578
579 File pomFile = new File( localRepository.getBasedir(), localRepository.pathOf( pomArtifact ) );
580 if ( pomFile.isFile() )
581 {
582 copyArtifact( pomFile, pomArtifact, testRepository );
583 copyParentPoms( pomFile, testRepository );
584 }
585 }
586
587 private void installExtraArtifacts( ArtifactRepository testRepository, String[] extraArtifacts )
588 throws MojoExecutionException
589 {
590 if ( extraArtifacts == null )
591 {
592 return;
593 }
594
595 Artifact originatingArtifact = project.getArtifact();
596
597 for ( String extraArtifact : extraArtifacts )
598 {
599 String[] gav = extraArtifact.split( ":" );
600 if ( gav.length < 3 || gav.length > 5 )
601 {
602 throw new MojoExecutionException( "Invalid artifact " + extraArtifact );
603 }
604
605 String groupId = gav[0];
606 String artifactId = gav[1];
607 String version = gav[2];
608
609 String type = "jar";
610 if ( gav.length > 3 )
611 {
612 type = gav[3];
613 }
614
615 String classifier = null;
616 if ( gav.length == 5 )
617 {
618 classifier = gav[4];
619 }
620
621 List<ArtifactRepository> remoteRepositories;
622 if ( "maven-plugin".equals( type ) )
623 {
624 remoteRepositories = this.remotePluginRepositories;
625 }
626 else
627 {
628 remoteRepositories = this.remoteArtifactRepositories;
629 }
630
631 Artifact artifact = null;
632 try
633 {
634 artifact =
635 artifactFactory.createArtifactWithClassifier( groupId, artifactId, version, type, classifier );
636
637 ArtifactResolutionResult arr =
638 resolver.resolveTransitively( Collections.singleton( artifact ), originatingArtifact,
639 remoteRepositories, localRepository, artifactMetadataSource );
640
641 if ( !groupId.equals( artifact.getGroupId() ) || !artifactId.equals( artifact.getArtifactId() )
642 || !version.equals( artifact.getVersion() ) )
643 {
644 artifact =
645 artifactFactory.createArtifactWithClassifier( groupId, artifactId, version, type, classifier );
646 copyPoms( artifact, testRepository );
647 }
648
649 for ( Artifact arrArtifact : (Set<Artifact>) arr.getArtifacts() )
650 {
651 copyArtifact( arrArtifact, testRepository );
652 }
653 }
654 catch ( Exception e )
655 {
656 throw new MojoExecutionException( "Unable to resolve dependencies for: " + artifact, e );
657 }
658 }
659 }
660
661 }