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