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 org.apache.maven.artifact.Artifact; |
23 | |
import org.apache.maven.model.Model; |
24 | |
import org.apache.maven.model.Profile; |
25 | |
import org.apache.maven.plugin.AbstractMojo; |
26 | |
import org.apache.maven.plugin.MojoExecutionException; |
27 | |
import org.apache.maven.plugin.MojoFailureException; |
28 | |
import org.apache.maven.plugin.invoker.model.BuildJob; |
29 | |
import org.apache.maven.plugin.invoker.model.io.xpp3.BuildJobXpp3Writer; |
30 | |
import org.apache.maven.plugin.registry.TrackableBase; |
31 | |
import org.apache.maven.plugins.annotations.Component; |
32 | |
import org.apache.maven.plugins.annotations.Parameter; |
33 | |
import org.apache.maven.project.MavenProject; |
34 | |
import org.apache.maven.settings.Settings; |
35 | |
import org.apache.maven.settings.SettingsUtils; |
36 | |
import org.apache.maven.settings.io.xpp3.SettingsXpp3Reader; |
37 | |
import org.apache.maven.settings.io.xpp3.SettingsXpp3Writer; |
38 | |
import org.apache.maven.shared.invoker.CommandLineConfigurationException; |
39 | |
import org.apache.maven.shared.invoker.DefaultInvocationRequest; |
40 | |
import org.apache.maven.shared.invoker.InvocationRequest; |
41 | |
import org.apache.maven.shared.invoker.InvocationResult; |
42 | |
import org.apache.maven.shared.invoker.Invoker; |
43 | |
import org.apache.maven.shared.invoker.MavenCommandLineBuilder; |
44 | |
import org.apache.maven.shared.invoker.MavenInvocationException; |
45 | |
import org.apache.maven.shared.scriptinterpreter.RunErrorException; |
46 | |
import org.apache.maven.shared.scriptinterpreter.RunFailureException; |
47 | |
import org.apache.maven.shared.scriptinterpreter.ScriptRunner; |
48 | |
import org.codehaus.plexus.interpolation.InterpolationException; |
49 | |
import org.codehaus.plexus.interpolation.Interpolator; |
50 | |
import org.codehaus.plexus.interpolation.MapBasedValueSource; |
51 | |
import org.codehaus.plexus.interpolation.RegexBasedInterpolator; |
52 | |
import org.codehaus.plexus.util.DirectoryScanner; |
53 | |
import org.codehaus.plexus.util.FileUtils; |
54 | |
import org.codehaus.plexus.util.IOUtil; |
55 | |
import org.codehaus.plexus.util.InterpolationFilterReader; |
56 | |
import org.codehaus.plexus.util.ReaderFactory; |
57 | |
import org.codehaus.plexus.util.StringUtils; |
58 | |
import org.codehaus.plexus.util.WriterFactory; |
59 | |
import org.codehaus.plexus.util.xml.XmlStreamReader; |
60 | |
import org.codehaus.plexus.util.xml.pull.XmlPullParserException; |
61 | |
|
62 | |
import java.io.BufferedReader; |
63 | |
import java.io.File; |
64 | |
import java.io.FileInputStream; |
65 | |
import java.io.FileOutputStream; |
66 | |
import java.io.FileWriter; |
67 | |
import java.io.IOException; |
68 | |
import java.io.InputStream; |
69 | |
import java.io.OutputStreamWriter; |
70 | |
import java.io.Reader; |
71 | |
import java.io.Writer; |
72 | |
import java.text.DecimalFormat; |
73 | |
import java.text.DecimalFormatSymbols; |
74 | |
import java.util.ArrayList; |
75 | |
import java.util.Arrays; |
76 | |
import java.util.Collection; |
77 | |
import java.util.Collections; |
78 | |
import java.util.HashMap; |
79 | |
import java.util.LinkedHashMap; |
80 | |
import java.util.LinkedHashSet; |
81 | |
import java.util.List; |
82 | |
import java.util.Locale; |
83 | |
import java.util.Map; |
84 | |
import java.util.Properties; |
85 | |
import java.util.Set; |
86 | |
import java.util.StringTokenizer; |
87 | |
import java.util.TreeSet; |
88 | |
import java.util.concurrent.ExecutorService; |
89 | |
import java.util.concurrent.Executors; |
90 | |
import java.util.concurrent.TimeUnit; |
91 | |
|
92 | |
|
93 | |
|
94 | |
|
95 | |
|
96 | |
|
97 | |
|
98 | 9 | public abstract class AbstractInvokerMojo |
99 | |
extends AbstractMojo |
100 | |
{ |
101 | |
|
102 | |
|
103 | |
|
104 | |
|
105 | |
|
106 | |
|
107 | |
@Parameter( property = "invoker.skip", defaultValue = "false" ) |
108 | |
private boolean skipInvocation; |
109 | |
|
110 | |
|
111 | |
|
112 | |
|
113 | |
|
114 | |
|
115 | |
|
116 | |
@Parameter( defaultValue = "false" ) |
117 | |
protected boolean suppressSummaries; |
118 | |
|
119 | |
|
120 | |
|
121 | |
|
122 | |
@Parameter( property = "invoker.streamLogs", defaultValue = "false" ) |
123 | |
private boolean streamLogs; |
124 | |
|
125 | |
|
126 | |
|
127 | |
|
128 | |
|
129 | |
|
130 | |
@Parameter( property = "invoker.localRepositoryPath", defaultValue = "${settings.localRepository}" ) |
131 | |
private File localRepositoryPath; |
132 | |
|
133 | |
|
134 | |
|
135 | |
|
136 | |
@Parameter( property = "invoker.projectsDirectory", defaultValue = "${basedir}/src/it/" ) |
137 | |
private File projectsDirectory; |
138 | |
|
139 | |
|
140 | |
|
141 | |
|
142 | |
|
143 | |
|
144 | |
|
145 | |
|
146 | |
|
147 | |
@Parameter( property = "invoker.reportsDirectory", defaultValue = "${project.build.directory}/invoker-reports" ) |
148 | |
private File reportsDirectory; |
149 | |
|
150 | |
|
151 | |
|
152 | |
|
153 | |
|
154 | |
|
155 | |
@Parameter( property = "invoker.disableReports", defaultValue = "false" ) |
156 | |
private boolean disableReports; |
157 | |
|
158 | |
|
159 | |
|
160 | |
|
161 | |
|
162 | |
|
163 | |
|
164 | |
|
165 | |
@Parameter |
166 | |
private File cloneProjectsTo; |
167 | |
|
168 | |
|
169 | |
|
170 | |
|
171 | |
|
172 | |
|
173 | |
|
174 | |
|
175 | |
|
176 | |
@Parameter( defaultValue = "false" ) |
177 | |
private boolean cloneAllFiles; |
178 | |
|
179 | |
|
180 | |
|
181 | |
|
182 | |
|
183 | |
|
184 | |
@Parameter( defaultValue = "false" ) |
185 | |
private boolean cloneClean; |
186 | |
|
187 | |
|
188 | |
|
189 | |
|
190 | |
@Parameter( property = "invoker.pom" ) |
191 | |
private File pom; |
192 | |
|
193 | |
|
194 | |
|
195 | |
|
196 | |
|
197 | |
|
198 | |
|
199 | |
|
200 | |
|
201 | |
|
202 | |
|
203 | 9 | @Parameter |
204 | |
private List<String> pomIncludes = Collections.singletonList( "*/pom.xml" ); |
205 | |
|
206 | |
|
207 | |
|
208 | |
|
209 | |
|
210 | |
|
211 | 9 | @Parameter |
212 | |
private List<String> pomExcludes = Collections.emptyList(); |
213 | |
|
214 | |
|
215 | |
|
216 | |
|
217 | |
|
218 | |
|
219 | |
|
220 | |
|
221 | |
|
222 | |
|
223 | 9 | @Parameter |
224 | |
private List<String> setupIncludes = Collections.singletonList( "setup*/pom.xml" ); |
225 | |
|
226 | |
|
227 | |
|
228 | |
|
229 | 9 | @Parameter |
230 | |
private List<String> goals = Collections.singletonList( "package" ); |
231 | |
|
232 | |
|
233 | |
|
234 | |
|
235 | |
|
236 | |
|
237 | |
|
238 | |
@Parameter( property = "invoker.goalsFile", defaultValue = "goals.txt" ) |
239 | |
private String goalsFile; |
240 | |
|
241 | |
|
242 | |
|
243 | |
@Component |
244 | |
private Invoker invoker; |
245 | |
|
246 | |
|
247 | |
|
248 | |
|
249 | |
|
250 | |
|
251 | |
|
252 | |
|
253 | |
|
254 | |
|
255 | |
|
256 | |
|
257 | |
|
258 | |
@Parameter( property = "invoker.selectorScript", defaultValue = "selector" ) |
259 | |
private String selectorScript; |
260 | |
|
261 | |
|
262 | |
|
263 | |
|
264 | |
|
265 | |
|
266 | |
|
267 | |
|
268 | |
|
269 | |
@Parameter( property = "invoker.preBuildHookScript", defaultValue = "prebuild" ) |
270 | |
private String preBuildHookScript; |
271 | |
|
272 | |
|
273 | |
|
274 | |
|
275 | |
|
276 | |
|
277 | |
|
278 | |
|
279 | |
@Parameter( property = "invoker.postBuildHookScript", defaultValue = "postbuild" ) |
280 | |
private String postBuildHookScript; |
281 | |
|
282 | |
|
283 | |
|
284 | |
|
285 | |
@Parameter( property = "invoker.testPropertiesFile", defaultValue = "test.properties" ) |
286 | |
private String testPropertiesFile; |
287 | |
|
288 | |
|
289 | |
|
290 | |
|
291 | |
|
292 | |
|
293 | |
@Parameter |
294 | |
private Properties testProperties; |
295 | |
|
296 | |
|
297 | |
|
298 | |
|
299 | |
|
300 | |
|
301 | |
@Parameter |
302 | |
private Map<String, String> properties; |
303 | |
|
304 | |
|
305 | |
|
306 | |
|
307 | |
@Parameter( property = "invoker.showErrors", defaultValue = "false" ) |
308 | |
private boolean showErrors; |
309 | |
|
310 | |
|
311 | |
|
312 | |
|
313 | |
@Parameter( property = "invoker.debug", defaultValue = "false" ) |
314 | |
private boolean debug; |
315 | |
|
316 | |
|
317 | |
|
318 | |
|
319 | |
@Parameter( property = "invoker.noLog", defaultValue = "false" ) |
320 | |
private boolean noLog; |
321 | |
|
322 | |
|
323 | |
|
324 | |
|
325 | |
|
326 | |
|
327 | |
@Parameter |
328 | |
private List<String> profiles; |
329 | |
|
330 | |
|
331 | |
|
332 | |
|
333 | |
|
334 | |
|
335 | |
|
336 | |
@Parameter |
337 | |
private Properties interpolationsProperties; |
338 | |
|
339 | |
|
340 | |
|
341 | |
|
342 | |
|
343 | |
|
344 | |
@Parameter |
345 | |
private Map<String, String> filterProperties; |
346 | |
|
347 | |
|
348 | |
|
349 | |
|
350 | |
|
351 | |
|
352 | |
@Component |
353 | |
private MavenProject project; |
354 | |
|
355 | |
|
356 | |
|
357 | |
|
358 | |
|
359 | |
|
360 | |
|
361 | |
|
362 | |
|
363 | |
|
364 | |
|
365 | |
@Parameter( property = "invoker.test" ) |
366 | |
private String invokerTest; |
367 | |
|
368 | |
|
369 | |
|
370 | |
|
371 | |
|
372 | |
|
373 | |
|
374 | |
|
375 | |
|
376 | |
@Parameter( property = "invoker.profilesFile", defaultValue = "profiles.txt" ) |
377 | |
private String profilesFile; |
378 | |
|
379 | |
|
380 | |
|
381 | |
|
382 | |
|
383 | |
|
384 | |
|
385 | |
|
386 | |
@Parameter( property = "invoker.settingsFile" ) |
387 | |
private File settingsFile; |
388 | |
|
389 | |
|
390 | |
|
391 | |
|
392 | |
|
393 | |
|
394 | |
|
395 | |
@Parameter( property = "invoker.mavenOpts" ) |
396 | |
private String mavenOpts; |
397 | |
|
398 | |
|
399 | |
|
400 | |
|
401 | |
|
402 | |
|
403 | |
|
404 | |
@Parameter( property = "invoker.mavenHome" ) |
405 | |
private File mavenHome; |
406 | |
|
407 | |
|
408 | |
|
409 | |
|
410 | |
|
411 | |
|
412 | |
|
413 | |
@Parameter( property = "invoker.javaHome" ) |
414 | |
private File javaHome; |
415 | |
|
416 | |
|
417 | |
|
418 | |
|
419 | |
|
420 | |
|
421 | |
@Parameter( property = "encoding", defaultValue = "${project.build.sourceEncoding}" ) |
422 | |
private String encoding; |
423 | |
|
424 | |
|
425 | |
|
426 | |
|
427 | |
|
428 | |
|
429 | |
@Component |
430 | |
private Settings settings; |
431 | |
|
432 | |
|
433 | |
|
434 | |
|
435 | |
|
436 | |
|
437 | |
|
438 | |
|
439 | |
|
440 | |
|
441 | |
@Parameter( property = "invoker.addTestClassPath", defaultValue = "false" ) |
442 | |
private boolean addTestClassPath; |
443 | |
|
444 | |
|
445 | |
|
446 | |
|
447 | |
@Parameter( defaultValue = "${project.testClasspathElements}", readonly = true ) |
448 | |
private List<String> testClassPath; |
449 | |
|
450 | |
|
451 | |
|
452 | |
|
453 | |
|
454 | |
|
455 | |
|
456 | |
|
457 | |
|
458 | |
|
459 | |
|
460 | |
|
461 | |
|
462 | |
|
463 | |
|
464 | |
|
465 | |
|
466 | |
|
467 | |
|
468 | |
|
469 | |
|
470 | |
|
471 | |
|
472 | |
|
473 | |
|
474 | |
|
475 | |
|
476 | |
|
477 | |
|
478 | |
|
479 | |
|
480 | |
|
481 | |
|
482 | |
|
483 | |
|
484 | |
|
485 | |
|
486 | |
|
487 | |
|
488 | |
|
489 | |
|
490 | |
|
491 | |
|
492 | |
|
493 | |
|
494 | |
|
495 | |
|
496 | |
|
497 | |
|
498 | |
|
499 | |
|
500 | |
|
501 | |
|
502 | |
|
503 | |
|
504 | |
|
505 | |
|
506 | |
|
507 | |
|
508 | |
|
509 | |
|
510 | |
|
511 | |
|
512 | |
|
513 | |
|
514 | |
|
515 | |
|
516 | |
|
517 | |
@Parameter( property = "invoker.invokerPropertiesFile", defaultValue = "invoker.properties" ) |
518 | |
private String invokerPropertiesFile; |
519 | |
|
520 | |
|
521 | |
|
522 | |
|
523 | |
|
524 | |
|
525 | |
@Parameter( property = "invoker.showVersion", defaultValue = "false" ) |
526 | |
private boolean showVersion; |
527 | |
|
528 | |
|
529 | |
|
530 | |
|
531 | |
|
532 | |
|
533 | |
|
534 | |
@Parameter( property = "invoker.parallelThreads", defaultValue = "1" ) |
535 | |
private int parallelThreads; |
536 | |
|
537 | |
|
538 | |
|
539 | |
|
540 | |
@Parameter( property = "plugin.artifacts", required = true, readonly = true ) |
541 | |
private List<Artifact> pluginArtifacts; |
542 | |
|
543 | |
|
544 | |
|
545 | |
|
546 | |
|
547 | |
|
548 | |
|
549 | |
@Parameter( property = "invoker.mergeUserSettings", defaultValue = "false" ) |
550 | |
private boolean mergeUserSettings; |
551 | |
|
552 | |
|
553 | |
|
554 | |
|
555 | |
private ScriptRunner scriptRunner; |
556 | |
|
557 | |
|
558 | |
|
559 | |
|
560 | |
|
561 | |
|
562 | 9 | private String filteredPomPrefix = "interpolated-"; |
563 | |
|
564 | |
|
565 | |
|
566 | |
|
567 | 9 | private final DecimalFormat secFormat = new DecimalFormat( "(0.0 s)", new DecimalFormatSymbols( Locale.ENGLISH ) ); |
568 | |
|
569 | |
|
570 | |
|
571 | |
|
572 | |
|
573 | |
|
574 | |
|
575 | |
|
576 | |
|
577 | |
public void execute() |
578 | |
throws MojoExecutionException, MojoFailureException |
579 | |
{ |
580 | 0 | if ( skipInvocation ) |
581 | |
{ |
582 | 0 | getLog().info( "Skipping invocation per configuration." |
583 | |
+ " If this is incorrect, ensure the skipInvocation parameter is not set to true." ); |
584 | 0 | return; |
585 | |
} |
586 | |
|
587 | |
|
588 | 0 | if ( !disableReports && !reportsDirectory.exists() ) |
589 | |
{ |
590 | 0 | reportsDirectory.mkdirs(); |
591 | |
} |
592 | |
|
593 | |
BuildJob[] buildJobs; |
594 | 0 | if ( pom != null ) |
595 | |
{ |
596 | |
try |
597 | |
{ |
598 | 0 | projectsDirectory = pom.getCanonicalFile().getParentFile(); |
599 | |
} |
600 | 0 | catch ( IOException e ) |
601 | |
{ |
602 | 0 | throw new MojoExecutionException( |
603 | |
"Failed to discover projectsDirectory from pom File parameter." + " Reason: " + e.getMessage(), e ); |
604 | 0 | } |
605 | |
|
606 | 0 | buildJobs = new BuildJob[]{ new BuildJob( pom.getName(), BuildJob.Type.NORMAL ) }; |
607 | |
} |
608 | |
else |
609 | |
{ |
610 | |
try |
611 | |
{ |
612 | 0 | buildJobs = getBuildJobs(); |
613 | |
} |
614 | 0 | catch ( final IOException e ) |
615 | |
{ |
616 | 0 | throw new MojoExecutionException( |
617 | |
"Error retrieving POM list from includes, excludes, " + "and projects directory. Reason: " |
618 | |
+ e.getMessage(), e ); |
619 | 0 | } |
620 | |
} |
621 | |
|
622 | 0 | if ( ( buildJobs == null ) || ( buildJobs.length < 1 ) ) |
623 | |
{ |
624 | 0 | getLog().info( "No projects were selected for execution." ); |
625 | 0 | return; |
626 | |
} |
627 | |
|
628 | 0 | if ( StringUtils.isEmpty( encoding ) ) |
629 | |
{ |
630 | 0 | getLog().warn( "File encoding has not been set, using platform encoding " + ReaderFactory.FILE_ENCODING |
631 | |
+ ", i.e. build is platform dependent!" ); |
632 | |
} |
633 | |
|
634 | |
final List<String> scriptClassPath; |
635 | 0 | if ( addTestClassPath ) |
636 | |
{ |
637 | 0 | scriptClassPath = new ArrayList<String>( testClassPath ); |
638 | 0 | for ( Artifact pluginArtifact : pluginArtifacts ) |
639 | |
{ |
640 | 0 | scriptClassPath.remove( pluginArtifact.getFile().getAbsolutePath() ); |
641 | |
} |
642 | |
} |
643 | |
else |
644 | |
{ |
645 | 0 | scriptClassPath = null; |
646 | |
} |
647 | 0 | scriptRunner = new ScriptRunner( getLog() ); |
648 | 0 | scriptRunner.setScriptEncoding( encoding ); |
649 | 0 | scriptRunner.setGlobalVariable( "localRepositoryPath", localRepositoryPath ); |
650 | 0 | scriptRunner.setClassPath( scriptClassPath ); |
651 | |
|
652 | 0 | Collection<String> collectedProjects = new LinkedHashSet<String>(); |
653 | 0 | for ( int i = 0; i < buildJobs.length; i++ ) |
654 | |
{ |
655 | 0 | collectProjects( projectsDirectory, buildJobs[i].getProject(), collectedProjects, true ); |
656 | |
} |
657 | |
|
658 | 0 | File projectsDir = projectsDirectory; |
659 | |
|
660 | 0 | if ( cloneProjectsTo != null ) |
661 | |
{ |
662 | 0 | cloneProjects( collectedProjects ); |
663 | 0 | projectsDir = cloneProjectsTo; |
664 | |
} |
665 | |
else |
666 | |
{ |
667 | 0 | getLog().warn( "Filtering of parent/child POMs is not supported without cloning the projects" ); |
668 | |
} |
669 | |
|
670 | 0 | runBuilds( projectsDir, buildJobs ); |
671 | |
|
672 | 0 | processResults( new InvokerSession( buildJobs ) ); |
673 | 0 | } |
674 | |
|
675 | |
|
676 | |
|
677 | |
|
678 | |
|
679 | |
|
680 | |
|
681 | |
|
682 | |
abstract void processResults( InvokerSession invokerSession ) |
683 | |
throws MojoFailureException; |
684 | |
|
685 | |
|
686 | |
|
687 | |
|
688 | |
|
689 | |
|
690 | |
|
691 | |
|
692 | |
private Reader newReader( File file ) |
693 | |
throws IOException |
694 | |
{ |
695 | 4 | if ( StringUtils.isNotEmpty( encoding ) ) |
696 | |
{ |
697 | 0 | return ReaderFactory.newReader( file, encoding ); |
698 | |
} |
699 | |
else |
700 | |
{ |
701 | 4 | return ReaderFactory.newPlatformReader( file ); |
702 | |
} |
703 | |
} |
704 | |
|
705 | |
|
706 | |
|
707 | |
|
708 | |
|
709 | |
|
710 | |
|
711 | |
|
712 | |
|
713 | |
|
714 | |
|
715 | |
|
716 | |
|
717 | |
|
718 | |
|
719 | |
|
720 | |
private void collectProjects( File projectsDir, String projectPath, Collection<String> projectPaths, |
721 | |
boolean included ) |
722 | |
throws MojoExecutionException |
723 | |
{ |
724 | 0 | projectPath = projectPath.replace( '\\', '/' ); |
725 | 0 | File pomFile = new File( projectsDir, projectPath ); |
726 | 0 | if ( pomFile.isDirectory() ) |
727 | |
{ |
728 | 0 | pomFile = new File( pomFile, "pom.xml" ); |
729 | 0 | if ( !pomFile.exists() ) |
730 | |
{ |
731 | 0 | if ( included ) |
732 | |
{ |
733 | 0 | projectPaths.add( projectPath ); |
734 | |
} |
735 | 0 | return; |
736 | |
} |
737 | 0 | if ( !projectPath.endsWith( "/" ) ) |
738 | |
{ |
739 | 0 | projectPath += '/'; |
740 | |
} |
741 | 0 | projectPath += "pom.xml"; |
742 | |
} |
743 | 0 | else if ( !pomFile.isFile() ) |
744 | |
{ |
745 | 0 | return; |
746 | |
} |
747 | 0 | if ( !projectPaths.add( projectPath ) ) |
748 | |
{ |
749 | 0 | return; |
750 | |
} |
751 | 0 | getLog().debug( "Collecting parent/child projects of " + projectPath ); |
752 | |
|
753 | 0 | Model model = PomUtils.loadPom( pomFile ); |
754 | |
|
755 | |
try |
756 | |
{ |
757 | 0 | String projectsRoot = projectsDir.getCanonicalPath(); |
758 | 0 | String projectDir = pomFile.getParent(); |
759 | |
|
760 | 0 | String parentPath = "../pom.xml"; |
761 | 0 | if ( model.getParent() != null && StringUtils.isNotEmpty( model.getParent().getRelativePath() ) ) |
762 | |
{ |
763 | 0 | parentPath = model.getParent().getRelativePath(); |
764 | |
} |
765 | 0 | String parent = relativizePath( new File( projectDir, parentPath ), projectsRoot ); |
766 | 0 | if ( parent != null ) |
767 | |
{ |
768 | 0 | collectProjects( projectsDir, parent, projectPaths, false ); |
769 | |
} |
770 | |
|
771 | 0 | Collection<String> modulePaths = new LinkedHashSet<String>(); |
772 | |
|
773 | 0 | modulePaths.addAll( (List<String>) model.getModules() ); |
774 | |
|
775 | 0 | for ( Profile profile : (List<Profile>) model.getProfiles() ) |
776 | |
{ |
777 | 0 | modulePaths.addAll( (List<String>) profile.getModules() ); |
778 | |
} |
779 | |
|
780 | 0 | for ( String modulePath : modulePaths ) |
781 | |
{ |
782 | 0 | String module = relativizePath( new File( projectDir, modulePath ), projectsRoot ); |
783 | 0 | if ( module != null ) |
784 | |
{ |
785 | 0 | collectProjects( projectsDir, module, projectPaths, false ); |
786 | |
} |
787 | 0 | } |
788 | |
} |
789 | 0 | catch ( IOException e ) |
790 | |
{ |
791 | 0 | throw new MojoExecutionException( "Failed to analyze POM: " + pomFile, e ); |
792 | 0 | } |
793 | 0 | } |
794 | |
|
795 | |
|
796 | |
|
797 | |
|
798 | |
|
799 | |
|
800 | |
|
801 | |
|
802 | |
|
803 | |
|
804 | |
private void cloneProjects( Collection<String> projectPaths ) |
805 | |
throws MojoExecutionException |
806 | |
{ |
807 | 0 | if ( !cloneProjectsTo.mkdirs() && cloneClean ) |
808 | |
{ |
809 | |
try |
810 | |
{ |
811 | 0 | FileUtils.cleanDirectory( cloneProjectsTo ); |
812 | |
} |
813 | 0 | catch ( IOException e ) |
814 | |
{ |
815 | 0 | throw new MojoExecutionException( |
816 | |
"Could not clean the cloneProjectsTo directory. Reason: " + e.getMessage(), e ); |
817 | 0 | } |
818 | |
} |
819 | |
|
820 | |
|
821 | 0 | Collection<String> dirs = new LinkedHashSet<String>(); |
822 | 0 | for ( String projectPath : projectPaths ) |
823 | |
{ |
824 | 0 | if ( !new File( projectsDirectory, projectPath ).isDirectory() ) |
825 | |
{ |
826 | 0 | projectPath = getParentPath( projectPath ); |
827 | |
} |
828 | 0 | dirs.add( projectPath ); |
829 | |
} |
830 | |
|
831 | 0 | boolean filter = false; |
832 | |
|
833 | |
|
834 | |
try |
835 | |
{ |
836 | 0 | filter = !cloneProjectsTo.getCanonicalFile().equals( projectsDirectory.getCanonicalFile() ); |
837 | |
|
838 | 0 | List<String> clonedSubpaths = new ArrayList<String>(); |
839 | |
|
840 | 0 | for ( String subpath : dirs ) |
841 | |
{ |
842 | |
|
843 | 0 | if ( !".".equals( subpath ) && dirs.contains( getParentPath( subpath ) ) ) |
844 | |
{ |
845 | 0 | continue; |
846 | |
} |
847 | |
|
848 | |
|
849 | 0 | if ( !alreadyCloned( subpath, clonedSubpaths ) ) |
850 | |
{ |
851 | |
|
852 | 0 | if ( ".".equals( subpath ) ) |
853 | |
{ |
854 | 0 | String cloneSubdir = relativizePath( cloneProjectsTo, projectsDirectory.getCanonicalPath() ); |
855 | |
|
856 | |
|
857 | 0 | if ( cloneSubdir != null ) |
858 | |
{ |
859 | 0 | File temp = File.createTempFile( "pre-invocation-clone.", "" ); |
860 | 0 | temp.delete(); |
861 | 0 | temp.mkdirs(); |
862 | |
|
863 | 0 | copyDirectoryStructure( projectsDirectory, temp ); |
864 | |
|
865 | 0 | FileUtils.deleteDirectory( new File( temp, cloneSubdir ) ); |
866 | |
|
867 | 0 | copyDirectoryStructure( temp, cloneProjectsTo ); |
868 | 0 | } |
869 | |
else |
870 | |
{ |
871 | 0 | copyDirectoryStructure( projectsDirectory, cloneProjectsTo ); |
872 | |
} |
873 | 0 | } |
874 | |
else |
875 | |
{ |
876 | 0 | File srcDir = new File( projectsDirectory, subpath ); |
877 | 0 | File dstDir = new File( cloneProjectsTo, subpath ); |
878 | 0 | copyDirectoryStructure( srcDir, dstDir ); |
879 | |
} |
880 | |
|
881 | 0 | clonedSubpaths.add( subpath ); |
882 | |
} |
883 | |
} |
884 | |
} |
885 | 0 | catch ( IOException e ) |
886 | |
{ |
887 | 0 | throw new MojoExecutionException( |
888 | |
"Failed to clone projects from: " + projectsDirectory + " to: " + cloneProjectsTo + ". Reason: " |
889 | |
+ e.getMessage(), e ); |
890 | 0 | } |
891 | |
|
892 | |
|
893 | 0 | if ( filter ) |
894 | |
{ |
895 | 0 | for ( String projectPath : projectPaths ) |
896 | |
{ |
897 | 0 | File pomFile = new File( cloneProjectsTo, projectPath ); |
898 | 0 | if ( pomFile.isFile() ) |
899 | |
{ |
900 | 0 | buildInterpolatedFile( pomFile, pomFile ); |
901 | |
} |
902 | 0 | } |
903 | 0 | filteredPomPrefix = null; |
904 | |
} |
905 | 0 | } |
906 | |
|
907 | |
|
908 | |
|
909 | |
|
910 | |
|
911 | |
|
912 | |
|
913 | |
private String getParentPath( String path ) |
914 | |
{ |
915 | 0 | int lastSep = Math.max( path.lastIndexOf( '/' ), path.lastIndexOf( '\\' ) ); |
916 | 0 | return ( lastSep < 0 ) ? "." : path.substring( 0, lastSep ); |
917 | |
} |
918 | |
|
919 | |
|
920 | |
|
921 | |
|
922 | |
|
923 | |
|
924 | |
|
925 | |
|
926 | |
private void copyDirectoryStructure( File sourceDir, File destDir ) |
927 | |
throws IOException |
928 | |
{ |
929 | 0 | DirectoryScanner scanner = new DirectoryScanner(); |
930 | 0 | scanner.setBasedir( sourceDir ); |
931 | 0 | if ( !cloneAllFiles ) |
932 | |
{ |
933 | 0 | scanner.addDefaultExcludes(); |
934 | |
} |
935 | 0 | scanner.scan(); |
936 | |
|
937 | |
|
938 | |
|
939 | |
|
940 | 0 | destDir.mkdirs(); |
941 | 0 | String[] includedDirs = scanner.getIncludedDirectories(); |
942 | 0 | for ( int i = 0; i < includedDirs.length; ++i ) |
943 | |
{ |
944 | 0 | File clonedDir = new File( destDir, includedDirs[i] ); |
945 | 0 | clonedDir.mkdirs(); |
946 | |
} |
947 | |
|
948 | 0 | String[] includedFiles = scanner.getIncludedFiles(); |
949 | 0 | for ( int i = 0; i < includedFiles.length; ++i ) |
950 | |
{ |
951 | 0 | File sourceFile = new File( sourceDir, includedFiles[i] ); |
952 | 0 | File destFile = new File( destDir, includedFiles[i] ); |
953 | 0 | FileUtils.copyFile( sourceFile, destFile ); |
954 | |
} |
955 | 0 | } |
956 | |
|
957 | |
|
958 | |
|
959 | |
|
960 | |
|
961 | |
|
962 | |
|
963 | |
|
964 | |
|
965 | |
|
966 | |
static boolean alreadyCloned( String subpath, List<String> clonedSubpaths ) |
967 | |
{ |
968 | 4 | for ( String path : clonedSubpaths ) |
969 | |
{ |
970 | 3 | if ( ".".equals( path ) || subpath.equals( path ) || subpath.startsWith( path + File.separator ) ) |
971 | |
{ |
972 | 2 | return true; |
973 | |
} |
974 | |
} |
975 | |
|
976 | 2 | return false; |
977 | |
} |
978 | |
|
979 | |
|
980 | |
|
981 | |
|
982 | |
|
983 | |
|
984 | |
|
985 | |
|
986 | |
|
987 | |
private void runBuilds( final File projectsDir, BuildJob[] buildJobs ) |
988 | |
throws MojoExecutionException |
989 | |
{ |
990 | 0 | if ( !localRepositoryPath.exists() ) |
991 | |
{ |
992 | 0 | localRepositoryPath.mkdirs(); |
993 | |
} |
994 | |
|
995 | |
|
996 | |
|
997 | |
|
998 | |
|
999 | 0 | File interpolatedSettingsFile = null; |
1000 | 0 | if ( settingsFile != null ) |
1001 | |
{ |
1002 | 0 | if ( cloneProjectsTo != null ) |
1003 | |
{ |
1004 | 0 | interpolatedSettingsFile = new File( cloneProjectsTo, "interpolated-" + settingsFile.getName() ); |
1005 | |
} |
1006 | |
else |
1007 | |
{ |
1008 | 0 | interpolatedSettingsFile = |
1009 | |
new File( settingsFile.getParentFile(), "interpolated-" + settingsFile.getName() ); |
1010 | |
} |
1011 | 0 | buildInterpolatedFile( settingsFile, interpolatedSettingsFile ); |
1012 | |
} |
1013 | |
|
1014 | |
|
1015 | |
|
1016 | |
|
1017 | |
|
1018 | 0 | SettingsXpp3Writer settingsWriter = new SettingsXpp3Writer(); |
1019 | |
|
1020 | |
File mergedSettingsFile; |
1021 | 0 | Settings mergedSettings = this.settings; |
1022 | 0 | if ( mergeUserSettings ) |
1023 | |
{ |
1024 | 0 | if ( interpolatedSettingsFile != null ) |
1025 | |
{ |
1026 | |
|
1027 | 0 | Reader reader = null; |
1028 | |
try |
1029 | |
{ |
1030 | 0 | reader = new XmlStreamReader( interpolatedSettingsFile ); |
1031 | 0 | SettingsXpp3Reader settingsReader = new SettingsXpp3Reader(); |
1032 | 0 | Settings dominantSettings = settingsReader.read( reader ); |
1033 | 0 | Settings recessiveSettings = this.settings; |
1034 | |
|
1035 | 0 | SettingsUtils.merge( dominantSettings, recessiveSettings, TrackableBase.USER_LEVEL ); |
1036 | |
|
1037 | 0 | mergedSettings = dominantSettings; |
1038 | 0 | getLog().debug( "Merged specified settings file with settings of invoking process" ); |
1039 | |
} |
1040 | 0 | catch ( XmlPullParserException e ) |
1041 | |
{ |
1042 | 0 | throw new MojoExecutionException( "Could not read specified settings file", e ); |
1043 | |
} |
1044 | 0 | catch ( IOException e ) |
1045 | |
{ |
1046 | 0 | throw new MojoExecutionException( "Could not read specified settings file", e ); |
1047 | |
} |
1048 | |
finally |
1049 | |
{ |
1050 | 0 | IOUtil.close( reader ); |
1051 | 0 | } |
1052 | |
} |
1053 | |
} |
1054 | 0 | if ( this.settingsFile != null && !mergeUserSettings ) |
1055 | |
{ |
1056 | 0 | mergedSettingsFile = interpolatedSettingsFile; |
1057 | |
} |
1058 | |
else |
1059 | |
{ |
1060 | |
try |
1061 | |
{ |
1062 | 0 | mergedSettingsFile = File.createTempFile( "invoker-settings", ".xml" ); |
1063 | |
|
1064 | 0 | FileWriter fileWriter = null; |
1065 | |
try |
1066 | |
{ |
1067 | 0 | fileWriter = new FileWriter( mergedSettingsFile ); |
1068 | 0 | settingsWriter.write( fileWriter, mergedSettings ); |
1069 | |
} |
1070 | |
finally |
1071 | |
{ |
1072 | 0 | IOUtil.close( fileWriter ); |
1073 | 0 | } |
1074 | |
|
1075 | 0 | if ( getLog().isDebugEnabled() ) |
1076 | |
{ |
1077 | 0 | getLog().debug( |
1078 | |
"Created temporary file for invoker settings.xml: " + mergedSettingsFile.getAbsolutePath() ); |
1079 | |
} |
1080 | |
|
1081 | |
} |
1082 | 0 | catch ( IOException e ) |
1083 | |
{ |
1084 | 0 | throw new MojoExecutionException( "Could not create temporary file for invoker settings.xml", e ); |
1085 | 0 | } |
1086 | |
} |
1087 | 0 | final File finalSettingsFile = mergedSettingsFile; |
1088 | |
|
1089 | |
try |
1090 | |
{ |
1091 | 0 | if ( isParallelRun() ) |
1092 | |
{ |
1093 | 0 | getLog().info( "use parallelThreads " + parallelThreads ); |
1094 | |
|
1095 | 0 | ExecutorService executorService = Executors.newFixedThreadPool( parallelThreads ); |
1096 | 0 | for ( int i = 0; i < buildJobs.length; i++ ) |
1097 | |
{ |
1098 | 0 | final BuildJob project = buildJobs[i]; |
1099 | 0 | executorService.execute( new Runnable() |
1100 | 0 | { |
1101 | |
|
1102 | |
public void run() |
1103 | |
{ |
1104 | |
try |
1105 | |
{ |
1106 | 0 | runBuild( projectsDir, project, finalSettingsFile ); |
1107 | |
} |
1108 | 0 | catch ( MojoExecutionException e ) |
1109 | |
{ |
1110 | 0 | throw new RuntimeException( e.getMessage(), e ); |
1111 | 0 | } |
1112 | 0 | } |
1113 | |
} ); |
1114 | |
} |
1115 | |
|
1116 | |
try |
1117 | |
{ |
1118 | 0 | executorService.shutdown(); |
1119 | |
|
1120 | 0 | executorService.awaitTermination( Long.MAX_VALUE, TimeUnit.MILLISECONDS ); |
1121 | |
} |
1122 | 0 | catch ( InterruptedException e ) |
1123 | |
{ |
1124 | 0 | throw new MojoExecutionException( e.getMessage(), e ); |
1125 | 0 | } |
1126 | |
|
1127 | 0 | } |
1128 | |
else |
1129 | |
{ |
1130 | 0 | for ( int i = 0; i < buildJobs.length; i++ ) |
1131 | |
{ |
1132 | 0 | BuildJob project = buildJobs[i]; |
1133 | 0 | runBuild( projectsDir, project, finalSettingsFile ); |
1134 | |
} |
1135 | |
} |
1136 | |
} |
1137 | |
finally |
1138 | |
{ |
1139 | 0 | if ( interpolatedSettingsFile != null && cloneProjectsTo == null ) |
1140 | |
{ |
1141 | 0 | interpolatedSettingsFile.delete(); |
1142 | |
} |
1143 | 0 | if ( mergedSettingsFile != null && mergedSettingsFile.exists() ) |
1144 | |
{ |
1145 | 0 | mergedSettingsFile.delete(); |
1146 | |
} |
1147 | |
|
1148 | |
} |
1149 | 0 | } |
1150 | |
|
1151 | |
|
1152 | |
|
1153 | |
|
1154 | |
|
1155 | |
|
1156 | |
|
1157 | |
|
1158 | |
|
1159 | |
|
1160 | |
|
1161 | |
private void runBuild( File projectsDir, BuildJob buildJob, File settingsFile ) |
1162 | |
throws MojoExecutionException |
1163 | |
{ |
1164 | 0 | File pomFile = new File( projectsDir, buildJob.getProject() ); |
1165 | |
File basedir; |
1166 | 0 | if ( pomFile.isDirectory() ) |
1167 | |
{ |
1168 | 0 | basedir = pomFile; |
1169 | 0 | pomFile = new File( basedir, "pom.xml" ); |
1170 | 0 | if ( !pomFile.exists() ) |
1171 | |
{ |
1172 | 0 | pomFile = null; |
1173 | |
} |
1174 | |
else |
1175 | |
{ |
1176 | 0 | buildJob.setProject( buildJob.getProject() + File.separator + "pom.xml" ); |
1177 | |
} |
1178 | |
} |
1179 | |
else |
1180 | |
{ |
1181 | 0 | basedir = pomFile.getParentFile(); |
1182 | |
} |
1183 | |
|
1184 | 0 | getLog().info( "Building: " + buildJob.getProject() ); |
1185 | |
|
1186 | 0 | File interpolatedPomFile = null; |
1187 | 0 | if ( pomFile != null ) |
1188 | |
{ |
1189 | 0 | if ( filteredPomPrefix != null ) |
1190 | |
{ |
1191 | 0 | interpolatedPomFile = new File( basedir, filteredPomPrefix + pomFile.getName() ); |
1192 | 0 | buildInterpolatedFile( pomFile, interpolatedPomFile ); |
1193 | |
} |
1194 | |
else |
1195 | |
{ |
1196 | 0 | interpolatedPomFile = pomFile; |
1197 | |
} |
1198 | |
} |
1199 | |
|
1200 | 0 | InvokerProperties invokerProperties = getInvokerProperties( basedir ); |
1201 | |
|
1202 | |
|
1203 | 0 | buildJob.setName( invokerProperties.getJobName() ); |
1204 | 0 | buildJob.setDescription( invokerProperties.getJobDescription() ); |
1205 | |
|
1206 | |
try |
1207 | |
{ |
1208 | 0 | if ( isSelected( invokerProperties ) ) |
1209 | |
{ |
1210 | 0 | long milliseconds = System.currentTimeMillis(); |
1211 | |
boolean executed; |
1212 | |
try |
1213 | |
{ |
1214 | 0 | executed = runBuild( basedir, interpolatedPomFile, settingsFile, invokerProperties ); |
1215 | |
} |
1216 | |
finally |
1217 | |
{ |
1218 | 0 | milliseconds = System.currentTimeMillis() - milliseconds; |
1219 | 0 | buildJob.setTime( milliseconds / 1000.0 ); |
1220 | 0 | } |
1221 | |
|
1222 | 0 | if ( executed ) |
1223 | |
{ |
1224 | |
|
1225 | 0 | buildJob.setResult( BuildJob.Result.SUCCESS ); |
1226 | |
|
1227 | 0 | if ( !suppressSummaries ) |
1228 | |
{ |
1229 | 0 | getLog().info( "..SUCCESS " + formatTime( buildJob.getTime() ) ); |
1230 | |
} |
1231 | |
} |
1232 | |
else |
1233 | |
{ |
1234 | 0 | buildJob.setResult( BuildJob.Result.SKIPPED ); |
1235 | |
|
1236 | 0 | if ( !suppressSummaries ) |
1237 | |
{ |
1238 | 0 | getLog().info( "..SKIPPED " + formatTime( buildJob.getTime() ) ); |
1239 | |
} |
1240 | |
} |
1241 | 0 | } |
1242 | |
else |
1243 | |
{ |
1244 | 0 | buildJob.setResult( BuildJob.Result.SKIPPED ); |
1245 | |
|
1246 | 0 | if ( !suppressSummaries ) |
1247 | |
{ |
1248 | 0 | getLog().info( "..SKIPPED " ); |
1249 | |
} |
1250 | |
} |
1251 | |
} |
1252 | 0 | catch ( RunErrorException e ) |
1253 | |
{ |
1254 | 0 | buildJob.setResult( BuildJob.Result.ERROR ); |
1255 | 0 | buildJob.setFailureMessage( e.getMessage() ); |
1256 | |
|
1257 | 0 | if ( !suppressSummaries ) |
1258 | |
{ |
1259 | 0 | getLog().info( "..ERROR " + formatTime( buildJob.getTime() ) ); |
1260 | 0 | getLog().info( " " + e.getMessage() ); |
1261 | |
} |
1262 | |
} |
1263 | 0 | catch ( RunFailureException e ) |
1264 | |
{ |
1265 | 0 | buildJob.setResult( e.getType() ); |
1266 | 0 | buildJob.setFailureMessage( e.getMessage() ); |
1267 | |
|
1268 | 0 | if ( !suppressSummaries ) |
1269 | |
{ |
1270 | 0 | getLog().info( "..FAILED " + formatTime( buildJob.getTime() ) ); |
1271 | 0 | getLog().info( " " + e.getMessage() ); |
1272 | |
} |
1273 | |
} |
1274 | |
finally |
1275 | |
{ |
1276 | 0 | if ( interpolatedPomFile != null && StringUtils.isNotEmpty( filteredPomPrefix ) ) |
1277 | |
{ |
1278 | 0 | interpolatedPomFile.delete(); |
1279 | |
} |
1280 | 0 | writeBuildReport( buildJob ); |
1281 | 0 | } |
1282 | 0 | } |
1283 | |
|
1284 | |
|
1285 | |
|
1286 | |
|
1287 | |
|
1288 | |
|
1289 | |
|
1290 | |
private boolean isSelected( InvokerProperties invokerProperties ) |
1291 | |
{ |
1292 | 0 | if ( !SelectorUtils.isMavenVersion( invokerProperties.getMavenVersion() ) ) |
1293 | |
{ |
1294 | 0 | return false; |
1295 | |
} |
1296 | |
|
1297 | 0 | if ( !SelectorUtils.isJreVersion( invokerProperties.getJreVersion() ) ) |
1298 | |
{ |
1299 | 0 | return false; |
1300 | |
} |
1301 | |
|
1302 | 0 | if ( !SelectorUtils.isOsFamily( invokerProperties.getOsFamily() ) ) |
1303 | |
{ |
1304 | 0 | return false; |
1305 | |
} |
1306 | |
|
1307 | 0 | return true; |
1308 | |
} |
1309 | |
|
1310 | |
|
1311 | |
|
1312 | |
|
1313 | |
|
1314 | |
|
1315 | |
|
1316 | |
|
1317 | |
private void writeBuildReport( BuildJob buildJob ) |
1318 | |
throws MojoExecutionException |
1319 | |
{ |
1320 | 0 | if ( disableReports ) |
1321 | |
{ |
1322 | 0 | return; |
1323 | |
} |
1324 | |
|
1325 | 0 | String safeFileName = buildJob.getProject().replace( '/', '_' ).replace( '\\', '_' ).replace( ' ', '_' ); |
1326 | 0 | if ( safeFileName.endsWith( "_pom.xml" ) ) |
1327 | |
{ |
1328 | 0 | safeFileName = safeFileName.substring( 0, safeFileName.length() - "_pom.xml".length() ); |
1329 | |
} |
1330 | |
|
1331 | 0 | File reportFile = new File( reportsDirectory, "BUILD-" + safeFileName + ".xml" ); |
1332 | |
try |
1333 | |
{ |
1334 | 0 | FileOutputStream fos = new FileOutputStream( reportFile ); |
1335 | |
try |
1336 | |
{ |
1337 | 0 | Writer osw = new OutputStreamWriter( fos, buildJob.getModelEncoding() ); |
1338 | 0 | BuildJobXpp3Writer writer = new BuildJobXpp3Writer(); |
1339 | 0 | writer.write( osw, buildJob ); |
1340 | 0 | osw.close(); |
1341 | |
} |
1342 | |
finally |
1343 | |
{ |
1344 | 0 | fos.close(); |
1345 | 0 | } |
1346 | |
} |
1347 | 0 | catch ( IOException e ) |
1348 | |
{ |
1349 | 0 | throw new MojoExecutionException( "Failed to write build report " + reportFile, e ); |
1350 | 0 | } |
1351 | 0 | } |
1352 | |
|
1353 | |
|
1354 | |
|
1355 | |
|
1356 | |
|
1357 | |
|
1358 | |
|
1359 | |
private String formatTime( double seconds ) |
1360 | |
{ |
1361 | 0 | return secFormat.format( seconds ); |
1362 | |
} |
1363 | |
|
1364 | |
|
1365 | |
|
1366 | |
|
1367 | |
|
1368 | |
|
1369 | |
|
1370 | |
|
1371 | |
|
1372 | |
|
1373 | |
|
1374 | |
|
1375 | |
|
1376 | |
|
1377 | |
|
1378 | |
|
1379 | |
private boolean runBuild( File basedir, File pomFile, File settingsFile, InvokerProperties invokerProperties ) |
1380 | |
throws MojoExecutionException, RunFailureException |
1381 | |
{ |
1382 | 0 | if ( getLog().isDebugEnabled() && !invokerProperties.getProperties().isEmpty() ) |
1383 | |
{ |
1384 | 0 | Properties props = invokerProperties.getProperties(); |
1385 | 0 | getLog().debug( "Using invoker properties:" ); |
1386 | 0 | for ( String key : new TreeSet<String>( (Set) props.keySet() ) ) |
1387 | |
{ |
1388 | 0 | String value = props.getProperty( key ); |
1389 | 0 | getLog().debug( " " + key + " = " + value ); |
1390 | 0 | } |
1391 | |
} |
1392 | |
|
1393 | 0 | List<String> goals = getGoals( basedir ); |
1394 | |
|
1395 | 0 | List<String> profiles = getProfiles( basedir ); |
1396 | |
|
1397 | 0 | Map<String, Object> context = new LinkedHashMap<String, Object>(); |
1398 | |
|
1399 | 0 | FileLogger logger = setupLogger( basedir ); |
1400 | |
try |
1401 | |
{ |
1402 | |
try |
1403 | |
{ |
1404 | 0 | scriptRunner.run( "selector script", basedir, selectorScript, context, logger, BuildJob.Result.SKIPPED, |
1405 | |
false ); |
1406 | |
} |
1407 | 0 | catch ( RunErrorException e ) |
1408 | |
{ |
1409 | 0 | throw e; |
1410 | |
} |
1411 | 0 | catch ( RunFailureException e ) |
1412 | |
{ |
1413 | 0 | return false; |
1414 | 0 | } |
1415 | |
|
1416 | 0 | scriptRunner.run( "pre-build script", basedir, preBuildHookScript, context, logger, |
1417 | |
BuildJob.Result.FAILURE_PRE_HOOK, false ); |
1418 | |
|
1419 | 0 | final InvocationRequest request = new DefaultInvocationRequest(); |
1420 | |
|
1421 | 0 | request.setLocalRepositoryDirectory( localRepositoryPath ); |
1422 | |
|
1423 | 0 | request.setInteractive( false ); |
1424 | |
|
1425 | 0 | request.setShowErrors( showErrors ); |
1426 | |
|
1427 | 0 | request.setDebug( debug ); |
1428 | |
|
1429 | 0 | request.setShowVersion( showVersion ); |
1430 | |
|
1431 | 0 | if ( logger != null ) |
1432 | |
{ |
1433 | 0 | request.setErrorHandler( logger ); |
1434 | |
|
1435 | 0 | request.setOutputHandler( logger ); |
1436 | |
} |
1437 | |
|
1438 | 0 | if ( mavenHome != null ) |
1439 | |
{ |
1440 | 0 | invoker.setMavenHome( mavenHome ); |
1441 | 0 | request.addShellEnvironment( "M2_HOME", mavenHome.getAbsolutePath() ); |
1442 | |
} |
1443 | |
|
1444 | 0 | if ( javaHome != null ) |
1445 | |
{ |
1446 | 0 | request.setJavaHome( javaHome ); |
1447 | |
} |
1448 | |
|
1449 | 0 | for ( int invocationIndex = 1; ; invocationIndex++ ) |
1450 | |
{ |
1451 | 0 | if ( invocationIndex > 1 && !invokerProperties.isInvocationDefined( invocationIndex ) ) |
1452 | |
{ |
1453 | 0 | break; |
1454 | |
} |
1455 | |
|
1456 | 0 | request.setBaseDirectory( basedir ); |
1457 | |
|
1458 | 0 | request.setPomFile( pomFile ); |
1459 | |
|
1460 | 0 | request.setGoals( goals ); |
1461 | |
|
1462 | 0 | request.setProfiles( profiles ); |
1463 | |
|
1464 | 0 | request.setMavenOpts( mavenOpts ); |
1465 | |
|
1466 | 0 | request.setOffline( false ); |
1467 | |
|
1468 | 0 | request.setUserSettingsFile( settingsFile ); |
1469 | |
|
1470 | 0 | Properties systemProperties = |
1471 | |
getSystemProperties( basedir, invokerProperties.getSystemPropertiesFile( invocationIndex ) ); |
1472 | 0 | request.setProperties( systemProperties ); |
1473 | |
|
1474 | 0 | invokerProperties.configureInvocation( request, invocationIndex ); |
1475 | |
|
1476 | 0 | if ( getLog().isDebugEnabled() ) |
1477 | |
{ |
1478 | |
try |
1479 | |
{ |
1480 | 0 | getLog().debug( "Using MAVEN_OPTS: " + request.getMavenOpts() ); |
1481 | 0 | getLog().debug( "Executing: " + new MavenCommandLineBuilder().build( request ) ); |
1482 | |
} |
1483 | 0 | catch ( CommandLineConfigurationException e ) |
1484 | |
{ |
1485 | 0 | getLog().debug( "Failed to display command line: " + e.getMessage() ); |
1486 | 0 | } |
1487 | |
} |
1488 | |
|
1489 | |
InvocationResult result; |
1490 | |
|
1491 | |
try |
1492 | |
{ |
1493 | 0 | result = invoker.execute( request ); |
1494 | |
} |
1495 | 0 | catch ( final MavenInvocationException e ) |
1496 | |
{ |
1497 | 0 | getLog().debug( "Error invoking Maven: " + e.getMessage(), e ); |
1498 | 0 | throw new RunFailureException( "Maven invocation failed. " + e.getMessage(), |
1499 | |
BuildJob.Result.FAILURE_BUILD ); |
1500 | 0 | } |
1501 | |
|
1502 | 0 | verify( result, invocationIndex, invokerProperties, logger ); |
1503 | |
} |
1504 | |
|
1505 | 0 | scriptRunner.run( "post-build script", basedir, postBuildHookScript, context, logger, |
1506 | |
BuildJob.Result.FAILURE_POST_HOOK, true ); |
1507 | |
} |
1508 | 0 | catch ( IOException e ) |
1509 | |
{ |
1510 | 0 | throw new MojoExecutionException( e.getMessage(), e ); |
1511 | |
} |
1512 | |
finally |
1513 | |
{ |
1514 | 0 | if ( logger != null ) |
1515 | |
{ |
1516 | 0 | logger.close(); |
1517 | |
} |
1518 | |
} |
1519 | 0 | return true; |
1520 | |
} |
1521 | |
|
1522 | |
|
1523 | |
|
1524 | |
|
1525 | |
|
1526 | |
|
1527 | |
|
1528 | |
|
1529 | |
|
1530 | |
private FileLogger setupLogger( File basedir ) |
1531 | |
throws MojoExecutionException |
1532 | |
{ |
1533 | 0 | FileLogger logger = null; |
1534 | |
|
1535 | 0 | if ( !noLog ) |
1536 | |
{ |
1537 | 0 | File outputLog = new File( basedir, "build.log" ); |
1538 | |
try |
1539 | |
{ |
1540 | 0 | if ( streamLogs ) |
1541 | |
{ |
1542 | 0 | logger = new FileLogger( outputLog, getLog() ); |
1543 | |
} |
1544 | |
else |
1545 | |
{ |
1546 | 0 | logger = new FileLogger( outputLog ); |
1547 | |
} |
1548 | |
|
1549 | 0 | getLog().debug( "build log initialized in: " + outputLog ); |
1550 | |
} |
1551 | 0 | catch ( IOException e ) |
1552 | |
{ |
1553 | 0 | throw new MojoExecutionException( "Error initializing build logfile in: " + outputLog, e ); |
1554 | 0 | } |
1555 | |
} |
1556 | |
|
1557 | 0 | return logger; |
1558 | |
} |
1559 | |
|
1560 | |
|
1561 | |
|
1562 | |
|
1563 | |
|
1564 | |
|
1565 | |
|
1566 | |
|
1567 | |
|
1568 | |
|
1569 | |
|
1570 | |
private Properties getSystemProperties( final File basedir, final String filename ) |
1571 | |
throws MojoExecutionException |
1572 | |
{ |
1573 | 0 | Properties collectedTestProperties = new Properties(); |
1574 | |
|
1575 | 0 | if ( testProperties != null ) |
1576 | |
{ |
1577 | 0 | collectedTestProperties.putAll( testProperties ); |
1578 | |
} |
1579 | |
|
1580 | 0 | if ( properties != null ) |
1581 | |
{ |
1582 | 0 | collectedTestProperties.putAll( properties ); |
1583 | |
} |
1584 | |
|
1585 | 0 | File propertiesFile = null; |
1586 | 0 | if ( filename != null ) |
1587 | |
{ |
1588 | 0 | propertiesFile = new File( basedir, filename ); |
1589 | |
} |
1590 | 0 | else if ( testPropertiesFile != null ) |
1591 | |
{ |
1592 | 0 | propertiesFile = new File( basedir, testPropertiesFile ); |
1593 | |
} |
1594 | |
|
1595 | 0 | if ( propertiesFile != null && propertiesFile.isFile() ) |
1596 | |
{ |
1597 | 0 | InputStream fin = null; |
1598 | |
try |
1599 | |
{ |
1600 | 0 | fin = new FileInputStream( propertiesFile ); |
1601 | |
|
1602 | 0 | Properties loadedProperties = new Properties(); |
1603 | 0 | loadedProperties.load( fin ); |
1604 | 0 | collectedTestProperties.putAll( loadedProperties ); |
1605 | |
} |
1606 | 0 | catch ( IOException e ) |
1607 | |
{ |
1608 | 0 | throw new MojoExecutionException( "Error reading system properties from " + propertiesFile ); |
1609 | |
} |
1610 | |
finally |
1611 | |
{ |
1612 | 0 | IOUtil.close( fin ); |
1613 | 0 | } |
1614 | |
} |
1615 | |
|
1616 | 0 | return collectedTestProperties; |
1617 | |
} |
1618 | |
|
1619 | |
|
1620 | |
|
1621 | |
|
1622 | |
|
1623 | |
|
1624 | |
|
1625 | |
|
1626 | |
|
1627 | |
|
1628 | |
|
1629 | |
private void verify( InvocationResult result, int invocationIndex, InvokerProperties invokerProperties, |
1630 | |
FileLogger logger ) |
1631 | |
throws RunFailureException |
1632 | |
{ |
1633 | 0 | if ( result.getExecutionException() != null ) |
1634 | |
{ |
1635 | 0 | throw new RunFailureException( |
1636 | |
"The Maven invocation failed. " + result.getExecutionException().getMessage(), BuildJob.Result.ERROR ); |
1637 | |
} |
1638 | 0 | else if ( !invokerProperties.isExpectedResult( result.getExitCode(), invocationIndex ) ) |
1639 | |
{ |
1640 | 0 | StringBuffer buffer = new StringBuffer( 256 ); |
1641 | 0 | buffer.append( "The build exited with code " ).append( result.getExitCode() ).append( ". " ); |
1642 | 0 | if ( logger != null ) |
1643 | |
{ |
1644 | 0 | buffer.append( "See " ); |
1645 | 0 | buffer.append( logger.getOutputFile().getAbsolutePath() ); |
1646 | 0 | buffer.append( " for details." ); |
1647 | |
} |
1648 | |
else |
1649 | |
{ |
1650 | 0 | buffer.append( "See console output for details." ); |
1651 | |
} |
1652 | 0 | throw new RunFailureException( buffer.toString(), BuildJob.Result.FAILURE_BUILD ); |
1653 | |
} |
1654 | 0 | } |
1655 | |
|
1656 | |
|
1657 | |
|
1658 | |
|
1659 | |
|
1660 | |
|
1661 | |
|
1662 | |
|
1663 | |
|
1664 | |
List<String> getGoals( final File basedir ) |
1665 | |
throws MojoExecutionException |
1666 | |
{ |
1667 | |
try |
1668 | |
{ |
1669 | 5 | return getTokens( basedir, goalsFile, goals ); |
1670 | |
} |
1671 | 0 | catch ( IOException e ) |
1672 | |
{ |
1673 | 0 | throw new MojoExecutionException( "error reading goals", e ); |
1674 | |
} |
1675 | |
} |
1676 | |
|
1677 | |
|
1678 | |
|
1679 | |
|
1680 | |
|
1681 | |
|
1682 | |
|
1683 | |
|
1684 | |
|
1685 | |
List<String> getProfiles( File basedir ) |
1686 | |
throws MojoExecutionException |
1687 | |
{ |
1688 | |
try |
1689 | |
{ |
1690 | 3 | return getTokens( basedir, profilesFile, profiles ); |
1691 | |
} |
1692 | 0 | catch ( IOException e ) |
1693 | |
{ |
1694 | 0 | throw new MojoExecutionException( "error reading profiles", e ); |
1695 | |
} |
1696 | |
} |
1697 | |
|
1698 | |
|
1699 | |
|
1700 | |
|
1701 | |
|
1702 | |
|
1703 | |
|
1704 | |
BuildJob[] getBuildJobs() |
1705 | |
throws IOException |
1706 | |
{ |
1707 | |
BuildJob[] buildJobs; |
1708 | |
|
1709 | 3 | if ( ( pom != null ) && pom.exists() ) |
1710 | |
{ |
1711 | 0 | buildJobs = new BuildJob[]{ new BuildJob( pom.getAbsolutePath(), BuildJob.Type.NORMAL ) }; |
1712 | |
} |
1713 | 3 | else if ( invokerTest != null ) |
1714 | |
{ |
1715 | 3 | String[] testRegexes = StringUtils.split( invokerTest, "," ); |
1716 | 3 | List<String> includes = new ArrayList<String>( testRegexes.length ); |
1717 | |
|
1718 | 7 | for ( int i = 0, size = testRegexes.length; i < size; i++ ) |
1719 | |
{ |
1720 | |
|
1721 | 4 | includes.add( testRegexes[i] ); |
1722 | |
} |
1723 | |
|
1724 | |
|
1725 | |
|
1726 | 3 | buildJobs = scanProjectsDirectory( includes, null, BuildJob.Type.DIRECT ); |
1727 | 3 | } |
1728 | |
else |
1729 | |
{ |
1730 | 0 | List<String> excludes = |
1731 | |
( pomExcludes != null ) ? new ArrayList<String>( pomExcludes ) : new ArrayList<String>(); |
1732 | 0 | if ( this.settingsFile != null ) |
1733 | |
{ |
1734 | 0 | String exclude = relativizePath( this.settingsFile, projectsDirectory.getCanonicalPath() ); |
1735 | 0 | if ( exclude != null ) |
1736 | |
{ |
1737 | 0 | excludes.add( exclude.replace( '\\', '/' ) ); |
1738 | 0 | getLog().debug( "Automatically excluded " + exclude + " from project scanning" ); |
1739 | |
} |
1740 | |
} |
1741 | |
|
1742 | 0 | BuildJob[] setupPoms = scanProjectsDirectory( setupIncludes, excludes, BuildJob.Type.SETUP ); |
1743 | 0 | getLog().debug( "Setup projects: " + Arrays.asList( setupPoms ) ); |
1744 | |
|
1745 | 0 | BuildJob[] normalPoms = scanProjectsDirectory( pomIncludes, excludes, BuildJob.Type.NORMAL ); |
1746 | |
|
1747 | 0 | Map<String, BuildJob> uniquePoms = new LinkedHashMap<String, BuildJob>(); |
1748 | 0 | for ( int i = 0; i < setupPoms.length; i++ ) |
1749 | |
{ |
1750 | 0 | uniquePoms.put( setupPoms[i].getProject(), setupPoms[i] ); |
1751 | |
} |
1752 | 0 | for ( int i = 0; i < normalPoms.length; i++ ) |
1753 | |
{ |
1754 | 0 | if ( !uniquePoms.containsKey( normalPoms[i].getProject() ) ) |
1755 | |
{ |
1756 | 0 | uniquePoms.put( normalPoms[i].getProject(), normalPoms[i] ); |
1757 | |
} |
1758 | |
} |
1759 | |
|
1760 | 0 | buildJobs = uniquePoms.values().toArray( new BuildJob[uniquePoms.size()] ); |
1761 | |
} |
1762 | |
|
1763 | 3 | relativizeProjectPaths( buildJobs ); |
1764 | |
|
1765 | 3 | return buildJobs; |
1766 | |
} |
1767 | |
|
1768 | |
|
1769 | |
|
1770 | |
|
1771 | |
|
1772 | |
|
1773 | |
|
1774 | |
|
1775 | |
|
1776 | |
|
1777 | |
|
1778 | |
|
1779 | |
|
1780 | |
private BuildJob[] scanProjectsDirectory( List<String> includes, List<String> excludes, String type ) |
1781 | |
throws IOException |
1782 | |
{ |
1783 | 3 | if ( !projectsDirectory.isDirectory() ) |
1784 | |
{ |
1785 | 0 | return new BuildJob[0]; |
1786 | |
} |
1787 | |
|
1788 | 3 | DirectoryScanner scanner = new DirectoryScanner(); |
1789 | 3 | scanner.setBasedir( projectsDirectory.getCanonicalFile() ); |
1790 | 3 | scanner.setFollowSymlinks( false ); |
1791 | 3 | if ( includes != null ) |
1792 | |
{ |
1793 | 3 | scanner.setIncludes( includes.toArray( new String[includes.size()] ) ); |
1794 | |
} |
1795 | 3 | if ( excludes != null ) |
1796 | |
{ |
1797 | 0 | scanner.setExcludes( excludes.toArray( new String[excludes.size()] ) ); |
1798 | |
} |
1799 | 3 | scanner.addDefaultExcludes(); |
1800 | 3 | scanner.scan(); |
1801 | |
|
1802 | 3 | Map<String, BuildJob> matches = new LinkedHashMap<String, BuildJob>(); |
1803 | |
|
1804 | 3 | String[] includedFiles = scanner.getIncludedFiles(); |
1805 | 3 | for ( int i = 0; i < includedFiles.length; i++ ) |
1806 | |
{ |
1807 | 0 | matches.put( includedFiles[i], new BuildJob( includedFiles[i], type ) ); |
1808 | |
} |
1809 | |
|
1810 | 3 | String[] includedDirs = scanner.getIncludedDirectories(); |
1811 | 10 | for ( int i = 0; i < includedDirs.length; i++ ) |
1812 | |
{ |
1813 | 7 | String includedFile = includedDirs[i] + File.separatorChar + "pom.xml"; |
1814 | 7 | if ( new File( scanner.getBasedir(), includedFile ).isFile() ) |
1815 | |
{ |
1816 | 6 | matches.put( includedFile, new BuildJob( includedFile, type ) ); |
1817 | |
} |
1818 | |
else |
1819 | |
{ |
1820 | 1 | matches.put( includedDirs[i], new BuildJob( includedDirs[i], type ) ); |
1821 | |
} |
1822 | |
} |
1823 | |
|
1824 | 3 | return matches.values().toArray( new BuildJob[matches.size()] ); |
1825 | |
} |
1826 | |
|
1827 | |
|
1828 | |
|
1829 | |
|
1830 | |
|
1831 | |
|
1832 | |
|
1833 | |
|
1834 | |
|
1835 | |
|
1836 | |
private void relativizeProjectPaths( BuildJob[] buildJobs ) |
1837 | |
throws IOException |
1838 | |
{ |
1839 | 3 | String projectsDirPath = projectsDirectory.getCanonicalPath(); |
1840 | |
|
1841 | 10 | for ( int i = 0; i < buildJobs.length; i++ ) |
1842 | |
{ |
1843 | 7 | String projectPath = buildJobs[i].getProject(); |
1844 | |
|
1845 | 7 | File file = new File( projectPath ); |
1846 | |
|
1847 | 7 | if ( !file.isAbsolute() ) |
1848 | |
{ |
1849 | 7 | file = new File( projectsDirectory, projectPath ); |
1850 | |
} |
1851 | |
|
1852 | 7 | String relativizedPath = relativizePath( file, projectsDirPath ); |
1853 | |
|
1854 | 7 | if ( relativizedPath == null ) |
1855 | |
{ |
1856 | 0 | relativizedPath = projectPath; |
1857 | |
} |
1858 | |
|
1859 | 7 | buildJobs[i].setProject( relativizedPath ); |
1860 | |
} |
1861 | 3 | } |
1862 | |
|
1863 | |
|
1864 | |
|
1865 | |
|
1866 | |
|
1867 | |
|
1868 | |
|
1869 | |
|
1870 | |
|
1871 | |
|
1872 | |
|
1873 | |
private String relativizePath( File path, String basedir ) |
1874 | |
throws IOException |
1875 | |
{ |
1876 | 7 | String relativizedPath = path.getCanonicalPath(); |
1877 | |
|
1878 | 7 | if ( relativizedPath.startsWith( basedir ) ) |
1879 | |
{ |
1880 | 7 | relativizedPath = relativizedPath.substring( basedir.length() ); |
1881 | 7 | if ( relativizedPath.startsWith( File.separator ) ) |
1882 | |
{ |
1883 | 7 | relativizedPath = relativizedPath.substring( File.separator.length() ); |
1884 | |
} |
1885 | |
|
1886 | 7 | return relativizedPath; |
1887 | |
} |
1888 | |
else |
1889 | |
{ |
1890 | 0 | return null; |
1891 | |
} |
1892 | |
} |
1893 | |
|
1894 | |
|
1895 | |
|
1896 | |
|
1897 | |
|
1898 | |
|
1899 | |
private Map<String, Object> getInterpolationValueSource() |
1900 | |
{ |
1901 | 6 | Map<String, Object> props = new HashMap<String, Object>(); |
1902 | 6 | if ( interpolationsProperties != null ) |
1903 | |
{ |
1904 | 3 | props.putAll( (Map) interpolationsProperties ); |
1905 | |
} |
1906 | 6 | if ( filterProperties != null ) |
1907 | |
{ |
1908 | 0 | props.putAll( filterProperties ); |
1909 | |
} |
1910 | 6 | props.put( "basedir", this.project.getBasedir().getAbsolutePath() ); |
1911 | 6 | props.put( "baseurl", toUrl( this.project.getBasedir().getAbsolutePath() ) ); |
1912 | 6 | if ( settings.getLocalRepository() != null ) |
1913 | |
{ |
1914 | 0 | props.put( "localRepository", settings.getLocalRepository() ); |
1915 | 0 | props.put( "localRepositoryUrl", toUrl( settings.getLocalRepository() ) ); |
1916 | |
} |
1917 | 6 | return new CompositeMap( this.project, props ); |
1918 | |
} |
1919 | |
|
1920 | |
|
1921 | |
|
1922 | |
|
1923 | |
|
1924 | |
|
1925 | |
|
1926 | |
|
1927 | |
private static String toUrl( String filename ) |
1928 | |
{ |
1929 | |
|
1930 | |
|
1931 | |
|
1932 | |
|
1933 | 6 | String url = "file://" + new File( filename ).toURI().getPath(); |
1934 | 6 | if ( url.endsWith( "/" ) ) |
1935 | |
{ |
1936 | 6 | url = url.substring( 0, url.length() - 1 ); |
1937 | |
} |
1938 | 6 | return url; |
1939 | |
} |
1940 | |
|
1941 | |
|
1942 | |
|
1943 | |
|
1944 | |
|
1945 | |
|
1946 | |
|
1947 | |
|
1948 | |
|
1949 | |
|
1950 | |
|
1951 | |
|
1952 | |
|
1953 | |
private List<String> getTokens( File basedir, String filename, List<String> defaultTokens ) |
1954 | |
throws IOException |
1955 | |
{ |
1956 | 8 | List<String> tokens = ( defaultTokens != null ) ? defaultTokens : new ArrayList<String>(); |
1957 | |
|
1958 | 8 | if ( StringUtils.isNotEmpty( filename ) ) |
1959 | |
{ |
1960 | 8 | File tokenFile = new File( basedir, filename ); |
1961 | |
|
1962 | 8 | if ( tokenFile.exists() ) |
1963 | |
{ |
1964 | 4 | tokens = readTokens( tokenFile ); |
1965 | |
} |
1966 | |
} |
1967 | |
|
1968 | 8 | return tokens; |
1969 | |
} |
1970 | |
|
1971 | |
|
1972 | |
|
1973 | |
|
1974 | |
|
1975 | |
|
1976 | |
|
1977 | |
|
1978 | |
|
1979 | |
private List<String> readTokens( final File tokenFile ) |
1980 | |
throws IOException |
1981 | |
{ |
1982 | 4 | List<String> result = new ArrayList<String>(); |
1983 | |
|
1984 | 4 | BufferedReader reader = null; |
1985 | |
try |
1986 | |
{ |
1987 | 4 | Map<String, Object> composite = getInterpolationValueSource(); |
1988 | 4 | reader = new BufferedReader( new InterpolationFilterReader( newReader( tokenFile ), composite ) ); |
1989 | |
|
1990 | 4 | String line = null; |
1991 | 9 | while ( ( line = reader.readLine() ) != null ) |
1992 | |
{ |
1993 | 5 | result.addAll( collectListFromCSV( line ) ); |
1994 | |
} |
1995 | |
} |
1996 | |
finally |
1997 | |
{ |
1998 | 4 | IOUtil.close( reader ); |
1999 | 4 | } |
2000 | |
|
2001 | 4 | return result; |
2002 | |
} |
2003 | |
|
2004 | |
|
2005 | |
|
2006 | |
|
2007 | |
|
2008 | |
|
2009 | |
|
2010 | |
private List<String> collectListFromCSV( final String csv ) |
2011 | |
{ |
2012 | 5 | final List<String> result = new ArrayList<String>(); |
2013 | |
|
2014 | 5 | if ( ( csv != null ) && ( csv.trim().length() > 0 ) ) |
2015 | |
{ |
2016 | 5 | final StringTokenizer st = new StringTokenizer( csv, "," ); |
2017 | |
|
2018 | 12 | while ( st.hasMoreTokens() ) |
2019 | |
{ |
2020 | 7 | result.add( st.nextToken().trim() ); |
2021 | |
} |
2022 | |
} |
2023 | |
|
2024 | 5 | return result; |
2025 | |
} |
2026 | |
|
2027 | |
|
2028 | |
|
2029 | |
|
2030 | |
|
2031 | |
|
2032 | |
|
2033 | |
|
2034 | |
|
2035 | |
|
2036 | |
|
2037 | |
void buildInterpolatedFile( File originalFile, File interpolatedFile ) |
2038 | |
throws MojoExecutionException |
2039 | |
{ |
2040 | 2 | getLog().debug( "Interpolate " + originalFile.getPath() + " to " + interpolatedFile.getPath() ); |
2041 | |
|
2042 | |
try |
2043 | |
{ |
2044 | |
String xml; |
2045 | |
|
2046 | 2 | Reader reader = null; |
2047 | |
try |
2048 | |
{ |
2049 | |
|
2050 | 2 | Map<String, Object> composite = getInterpolationValueSource(); |
2051 | 2 | reader = ReaderFactory.newXmlReader( originalFile ); |
2052 | 2 | reader = new InterpolationFilterReader( reader, composite, "@", "@" ); |
2053 | 2 | xml = IOUtil.toString( reader ); |
2054 | |
} |
2055 | |
finally |
2056 | |
{ |
2057 | 2 | IOUtil.close( reader ); |
2058 | 2 | } |
2059 | |
|
2060 | 2 | Writer writer = null; |
2061 | |
try |
2062 | |
{ |
2063 | 2 | interpolatedFile.getParentFile().mkdirs(); |
2064 | 2 | writer = WriterFactory.newXmlWriter( interpolatedFile ); |
2065 | 2 | writer.write( xml ); |
2066 | 2 | writer.flush(); |
2067 | |
} |
2068 | |
finally |
2069 | |
{ |
2070 | 2 | IOUtil.close( writer ); |
2071 | 2 | } |
2072 | |
} |
2073 | 0 | catch ( IOException e ) |
2074 | |
{ |
2075 | 0 | throw new MojoExecutionException( "Failed to interpolate file " + originalFile.getPath(), e ); |
2076 | 2 | } |
2077 | 2 | } |
2078 | |
|
2079 | |
|
2080 | |
|
2081 | |
|
2082 | |
|
2083 | |
|
2084 | |
|
2085 | |
|
2086 | |
|
2087 | |
private InvokerProperties getInvokerProperties( final File projectDirectory ) |
2088 | |
throws MojoExecutionException |
2089 | |
{ |
2090 | 0 | Properties props = new Properties(); |
2091 | 0 | if ( invokerPropertiesFile != null ) |
2092 | |
{ |
2093 | 0 | File propertiesFile = new File( projectDirectory, invokerPropertiesFile ); |
2094 | 0 | if ( propertiesFile.isFile() ) |
2095 | |
{ |
2096 | 0 | InputStream in = null; |
2097 | |
try |
2098 | |
{ |
2099 | 0 | in = new FileInputStream( propertiesFile ); |
2100 | 0 | props.load( in ); |
2101 | |
} |
2102 | 0 | catch ( IOException e ) |
2103 | |
{ |
2104 | 0 | throw new MojoExecutionException( "Failed to read invoker properties: " + propertiesFile, e ); |
2105 | |
} |
2106 | |
finally |
2107 | |
{ |
2108 | 0 | IOUtil.close( in ); |
2109 | 0 | } |
2110 | |
} |
2111 | |
|
2112 | 0 | Interpolator interpolator = new RegexBasedInterpolator(); |
2113 | 0 | interpolator.addValueSource( new MapBasedValueSource( getInterpolationValueSource() ) ); |
2114 | 0 | for ( String key : (Set<String>) ( (Map) props ).keySet() ) |
2115 | |
{ |
2116 | 0 | String value = props.getProperty( key ); |
2117 | |
try |
2118 | |
{ |
2119 | 0 | value = interpolator.interpolate( value, "" ); |
2120 | |
} |
2121 | 0 | catch ( InterpolationException e ) |
2122 | |
{ |
2123 | 0 | throw new MojoExecutionException( "Failed to interpolate invoker properties: " + propertiesFile, |
2124 | |
e ); |
2125 | 0 | } |
2126 | 0 | props.setProperty( key, value ); |
2127 | 0 | } |
2128 | |
} |
2129 | 0 | return new InvokerProperties( props ); |
2130 | |
} |
2131 | |
|
2132 | |
protected boolean isParallelRun() |
2133 | |
{ |
2134 | 0 | return parallelThreads > 1; |
2135 | |
} |
2136 | |
|
2137 | |
} |