1 package org.apache.maven.shared.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.List;
25 import java.util.Map;
26 import java.util.Map.Entry;
27 import java.util.Properties;
28
29 import org.apache.maven.shared.invoker.InvocationRequest.CheckSumPolicy;
30 import org.apache.maven.shared.invoker.InvocationRequest.ReactorFailureBehavior;
31 import org.apache.maven.shared.utils.Os;
32 import org.apache.maven.shared.utils.StringUtils;
33 import org.apache.maven.shared.utils.cli.CommandLineException;
34 import org.apache.maven.shared.utils.cli.Commandline;
35
36
37
38
39 public class MavenCommandLineBuilder
40 {
41
42 private static final InvokerLogger DEFAULT_LOGGER = new SystemOutLogger();
43
44 private InvokerLogger logger = DEFAULT_LOGGER;
45
46 private File baseDirectory;
47
48 private File localRepositoryDirectory;
49
50 private File mavenHome;
51
52 private File mavenExecutable;
53
54
55
56
57
58
59
60
61 public Commandline build( InvocationRequest request )
62 throws CommandLineConfigurationException
63 {
64
65 Commandline cli = new Commandline();
66
67 setupMavenHome( request );
68
69
70 setupBaseDirectory( request );
71 cli.setWorkingDirectory( baseDirectory );
72
73 checkRequiredState();
74
75 setupMavenExecutable( request );
76 cli.setExecutable( mavenExecutable.getAbsolutePath() );
77
78
79 setShellEnvironment( request, cli );
80
81
82
83 setFlags( request, cli );
84
85
86
87 setReactorBehavior( request, cli );
88
89
90 setLocalRepository( request, cli );
91
92
93 setPomLocation( request, cli );
94
95 setSettingsLocation( request, cli );
96
97 setToolchainsLocation( request, cli );
98
99 setProperties( request, cli );
100
101 setProfiles( request, cli );
102
103 setGoals( request, cli );
104
105 setThreads( request, cli );
106
107 setArgs( request, cli );
108
109 return cli;
110 }
111
112
113
114
115 protected void checkRequiredState()
116 {
117 if ( logger == null )
118 {
119 throw new IllegalStateException( "A logger instance is required." );
120 }
121 }
122
123
124
125
126
127
128
129 protected void setSettingsLocation( InvocationRequest request, Commandline cli )
130 {
131 File userSettingsFile = request.getUserSettingsFile();
132
133 if ( userSettingsFile != null )
134 {
135 try
136 {
137 userSettingsFile = userSettingsFile.getCanonicalFile();
138 }
139 catch ( IOException e )
140 {
141 logger.debug( "Failed to canonicalize user settings path: " + userSettingsFile.getAbsolutePath()
142 + ". Using as-is.", e );
143 }
144
145 cli.createArg().setValue( "-s" );
146 cli.createArg().setValue( userSettingsFile.getPath() );
147 }
148
149 File globalSettingsFile = request.getGlobalSettingsFile();
150
151 if ( globalSettingsFile != null )
152 {
153 try
154 {
155 globalSettingsFile = globalSettingsFile.getCanonicalFile();
156 }
157 catch ( IOException e )
158 {
159 logger.debug( "Failed to canonicalize global settings path: " + globalSettingsFile.getAbsolutePath()
160 + ". Using as-is.", e );
161 }
162
163 cli.createArg().setValue( "-gs" );
164 cli.createArg().setValue( globalSettingsFile.getPath() );
165 }
166
167 }
168
169
170
171
172
173
174
175 protected void setToolchainsLocation( InvocationRequest request, Commandline cli )
176 {
177 File toolchainsFile = request.getToolchainsFile();
178
179 if ( toolchainsFile != null )
180 {
181 try
182 {
183 toolchainsFile = toolchainsFile.getCanonicalFile();
184 }
185 catch ( IOException e )
186 {
187 logger.debug( "Failed to canonicalize toolchains path: " + toolchainsFile.getAbsolutePath()
188 + ". Using as-is.", e );
189 }
190
191 cli.createArg().setValue( "-t" );
192 cli.createArg().setValue( toolchainsFile.getPath() );
193 }
194 }
195
196
197
198
199
200
201
202 protected void setShellEnvironment( InvocationRequest request, Commandline cli )
203 {
204 if ( request.isShellEnvironmentInherited() )
205 {
206 cli.addSystemEnvironment();
207 }
208
209 if ( request.getJavaHome() != null )
210 {
211 cli.addEnvironment( "JAVA_HOME", request.getJavaHome().getAbsolutePath() );
212 }
213
214 if ( request.getMavenOpts() != null )
215 {
216 cli.addEnvironment( "MAVEN_OPTS", request.getMavenOpts() );
217 }
218
219 for ( Map.Entry<String, String> entry : request.getShellEnvironments().entrySet() )
220 {
221 cli.addEnvironment( entry.getKey(), entry.getValue() );
222 }
223 }
224
225
226
227
228
229
230
231 protected void setProfiles( InvocationRequest request, Commandline cli )
232 {
233 List<String> profiles = request.getProfiles();
234
235 if ( ( profiles != null ) && !profiles.isEmpty() )
236 {
237 cli.createArg().setValue( "-P" );
238 cli.createArg().setValue( StringUtils.join( profiles.iterator(), "," ) );
239 }
240
241 }
242
243
244
245
246
247
248
249
250 protected void setGoals( InvocationRequest request, Commandline cli ) throws CommandLineConfigurationException
251 {
252 List<String> goals = request.getGoals();
253
254 if ( ( goals != null ) && !goals.isEmpty() )
255 {
256 try
257 {
258 cli.createArg().setLine( StringUtils.join( goals.iterator(), " " ) );
259 }
260 catch ( CommandLineException e )
261 {
262 throw new CommandLineConfigurationException( "Problem to set goals: " + e.getMessage(), e );
263 }
264 }
265 }
266
267
268
269
270
271
272
273 protected void setProperties( InvocationRequest request, Commandline cli )
274 {
275 Properties properties = request.getProperties();
276
277 if ( properties != null )
278 {
279 for ( Entry<Object, Object> entry : properties.entrySet() )
280 {
281 String key = (String) entry.getKey();
282 String value = (String) entry.getValue();
283
284 cli.createArg().setValue( "-D" );
285 cli.createArg().setValue( key + '=' + value );
286 }
287 }
288 }
289
290
291
292
293
294
295
296 protected void setPomLocation( InvocationRequest request, Commandline cli )
297 {
298 File pom = request.getPomFile();
299 String pomFilename = request.getPomFileName();
300
301 if ( pom == null )
302 {
303 if ( pomFilename != null )
304 {
305 pom = new File( baseDirectory, pomFilename );
306 }
307 else
308 {
309 pom = new File( baseDirectory, "pom.xml" );
310 }
311 }
312
313 try
314 {
315 pom = pom.getCanonicalFile();
316 }
317 catch ( IOException e )
318 {
319 logger.debug( "Failed to canonicalize the POM path: " + pom + ". Using as-is.", e );
320 }
321
322 if ( pom.getParentFile().equals( baseDirectory ) )
323 {
324
325 if ( !"pom.xml".equals( pom.getName() ) )
326 {
327 logger.debug( "Specified POM file is not named 'pom.xml'. "
328 + "Using the '-f' command-line option to accommodate non-standard filename..." );
329
330 cli.createArg().setValue( "-f" );
331 cli.createArg().setValue( pom.getName() );
332 }
333 }
334 else
335 {
336 cli.createArg().setValue( "-f" );
337 cli.createArg().setValue( pom.getPath() );
338 }
339 }
340
341 void setupBaseDirectory( InvocationRequest request )
342 {
343 File baseDirectoryFromRequest = null;
344 if ( request.getBaseDirectory() != null )
345 {
346 baseDirectoryFromRequest = request.getBaseDirectory();
347 }
348 else
349 {
350 File pomFile = request.getPomFile();
351 if ( pomFile != null )
352 {
353 baseDirectoryFromRequest = pomFile.getParentFile();
354 }
355 }
356
357 if ( baseDirectoryFromRequest != null )
358 {
359 baseDirectory = baseDirectoryFromRequest;
360 }
361
362 if ( baseDirectory == null )
363 {
364 baseDirectory = new File( System.getProperty( "user.dir" ) );
365 }
366 else if ( baseDirectory.isFile() )
367 {
368 logger.warn( "Specified base directory (" + baseDirectory + ") is a file."
369 + " Using its parent directory..." );
370
371 baseDirectory = baseDirectory.getParentFile();
372 }
373
374 try
375 {
376 baseDirectory = baseDirectory.getCanonicalFile();
377 }
378 catch ( IOException e )
379 {
380 logger.debug( "Failed to canonicalize base directory: " + baseDirectory + ". Using as-is.", e );
381 }
382 }
383
384
385
386
387
388
389
390 protected void setLocalRepository( InvocationRequest request, Commandline cli )
391 {
392 File localRepositoryDirectory = request.getLocalRepositoryDirectory( this.localRepositoryDirectory );
393
394 if ( localRepositoryDirectory != null )
395 {
396 try
397 {
398 localRepositoryDirectory = localRepositoryDirectory.getCanonicalFile();
399 }
400 catch ( IOException e )
401 {
402 logger.debug( "Failed to canonicalize local repository directory: " + localRepositoryDirectory
403 + ". Using as-is.", e );
404 }
405
406 if ( !localRepositoryDirectory.isDirectory() )
407 {
408 throw new IllegalArgumentException( "Local repository location: '" + localRepositoryDirectory
409 + "' is NOT a directory." );
410 }
411
412 cli.createArg().setValue( "-D" );
413 cli.createArg().setValue( "maven.repo.local=" + localRepositoryDirectory.getPath() );
414 }
415 }
416
417
418
419
420
421
422
423 protected void setReactorBehavior( InvocationRequest request, Commandline cli )
424 {
425
426 ReactorFailureBehavior failureBehavior = request.getReactorFailureBehavior();
427
428 if ( failureBehavior != null )
429 {
430 if ( ReactorFailureBehavior.FailAtEnd.equals( failureBehavior ) )
431 {
432 cli.createArg().setValue( "-" + ReactorFailureBehavior.FailAtEnd.getShortOption() );
433 }
434 else if ( ReactorFailureBehavior.FailNever.equals( failureBehavior ) )
435 {
436 cli.createArg().setValue( "-" + ReactorFailureBehavior.FailNever.getShortOption() );
437 }
438
439 }
440
441 if ( StringUtils.isNotEmpty( request.getResumeFrom() ) )
442 {
443 cli.createArg().setValue( "-rf" );
444 cli.createArg().setValue( request.getResumeFrom() );
445 }
446
447 List<String> projectList = request.getProjects();
448 if ( projectList != null )
449 {
450 cli.createArg().setValue( "-pl" );
451 cli.createArg().setValue( StringUtils.join( projectList.iterator(), "," ) );
452
453 if ( request.isAlsoMake() )
454 {
455 cli.createArg().setValue( "-am" );
456 }
457
458 if ( request.isAlsoMakeDependents() )
459 {
460 cli.createArg().setValue( "-amd" );
461 }
462 }
463 }
464
465
466
467
468
469
470
471 protected void setFlags( InvocationRequest request, Commandline cli )
472 {
473 if ( request.isBatchMode() )
474 {
475 cli.createArg().setValue( "-B" );
476 }
477
478 if ( request.isOffline() )
479 {
480 cli.createArg().setValue( "-o" );
481 }
482
483 if ( request.isUpdateSnapshots() )
484 {
485 cli.createArg().setValue( "-U" );
486 }
487
488 if ( !request.isRecursive() )
489 {
490 cli.createArg().setValue( "-N" );
491 }
492
493 if ( request.isDebug() )
494 {
495 cli.createArg().setValue( "-X" );
496 }
497
498 else if ( request.isShowErrors() )
499 {
500 cli.createArg().setValue( "-e" );
501 }
502
503 CheckSumPolicy checksumPolicy = request.getGlobalChecksumPolicy();
504 if ( CheckSumPolicy.Fail.equals( checksumPolicy ) )
505 {
506 cli.createArg().setValue( "-C" );
507 }
508 else if ( CheckSumPolicy.Warn.equals( checksumPolicy ) )
509 {
510 cli.createArg().setValue( "-c" );
511 }
512
513 if ( request.isNonPluginUpdates() )
514 {
515 cli.createArg().setValue( "-npu" );
516 }
517
518 if ( request.isShowVersion() )
519 {
520 cli.createArg().setValue( "-V" );
521 }
522
523 if ( request.getBuilder() != null )
524 {
525 cli.createArg().setValue( "-b" );
526 cli.createArg().setValue( request.getBuilder() );
527 }
528
529 if ( request.isQuiet() )
530 {
531 cli.createArg().setValue( "-q" );
532 }
533
534 if ( request.isNoTransferProgress() )
535 {
536 cli.createArg().setValue( "-ntp" );
537 }
538 }
539
540
541
542
543
544
545
546 protected void setThreads( InvocationRequest request, Commandline cli )
547 {
548 String threads = request.getThreads();
549 if ( StringUtils.isNotEmpty( threads ) )
550 {
551 cli.createArg().setValue( "-T" );
552 cli.createArg().setValue( threads );
553 }
554
555 }
556
557 private void setArgs( InvocationRequest request, Commandline cli )
558 {
559 for ( String arg : request.getArgs() )
560 {
561 cli.createArg().setValue( arg );
562 }
563 }
564
565 private void setupMavenHome( InvocationRequest request )
566 {
567 if ( request.getMavenHome() != null )
568 {
569 mavenHome = request.getMavenHome();
570 }
571 else if ( System.getProperty( "maven.home" ) != null )
572 {
573 mavenHome = new File( System.getProperty( "maven.home" ) );
574 }
575
576 if ( mavenHome != null && !mavenHome.isDirectory() )
577 {
578 File binDir = mavenHome.getParentFile();
579 if ( binDir != null && "bin".equals( binDir.getName() ) )
580 {
581
582
583 mavenHome = binDir.getParentFile();
584 }
585 }
586
587 if ( mavenHome != null && !mavenHome.isDirectory() )
588 {
589 throw new IllegalStateException( "Maven home is set to: '" + mavenHome + "' which is not a directory" );
590 }
591
592 logger.debug( "Using maven.home of: '" + mavenHome + "'." );
593 }
594
595
596
597
598
599
600
601
602 protected void setupMavenExecutable( InvocationRequest request )
603 throws CommandLineConfigurationException
604 {
605 if ( request.getMavenExecutable() != null )
606 {
607 mavenExecutable = request.getMavenExecutable();
608 }
609
610 if ( mavenExecutable == null || !mavenExecutable.isAbsolute() )
611 {
612 String executable;
613 if ( mavenExecutable != null )
614 {
615 executable = mavenExecutable.getPath();
616 }
617 else
618 {
619 executable = "mvn";
620 }
621
622
623 mavenExecutable = detectMavenExecutablePerOs( baseDirectory, executable );
624 if ( mavenExecutable == null )
625 {
626
627 mavenExecutable = detectMavenExecutablePerOs( mavenHome, "/bin/" + executable );
628 }
629
630 if ( mavenExecutable != null )
631 {
632 try
633 {
634 mavenExecutable = mavenExecutable.getCanonicalFile();
635 }
636 catch ( IOException e )
637 {
638 logger.debug( "Failed to canonicalize maven executable: '" + mavenExecutable
639 + "'. Using as-is.", e );
640 }
641 }
642 else
643 {
644 throw new CommandLineConfigurationException(
645 "Maven executable: '" + executable + "'"
646 + " not found at project dir: '" + baseDirectory + "' nor maven home: '" + mavenHome + "'" );
647 }
648 }
649 }
650
651 private File detectMavenExecutablePerOs( File baseDirectory, String executable )
652 {
653 if ( Os.isFamily( Os.FAMILY_WINDOWS ) )
654 {
655 File executableFile = new File( baseDirectory, executable + ".cmd" );
656 if ( executableFile.isFile() )
657 {
658 return executableFile;
659 }
660
661 executableFile = new File( baseDirectory, executable + ".bat" );
662 if ( executableFile.isFile() )
663 {
664 return executableFile;
665 }
666 }
667
668 File executableFile = new File( baseDirectory, executable );
669 if ( executableFile.isFile() )
670 {
671 return executableFile;
672 }
673 return null;
674 }
675
676
677
678
679
680
681 public File getLocalRepositoryDirectory()
682 {
683 return localRepositoryDirectory;
684 }
685
686
687
688
689
690
691 public void setLocalRepositoryDirectory( File localRepositoryDirectory )
692 {
693 this.localRepositoryDirectory = localRepositoryDirectory;
694 }
695
696
697
698
699
700
701 public InvokerLogger getLogger()
702 {
703 return logger;
704 }
705
706
707
708
709
710
711 public void setLogger( InvokerLogger logger )
712 {
713 this.logger = logger;
714 }
715
716
717
718
719
720
721 public File getMavenHome()
722 {
723 return mavenHome;
724 }
725
726
727
728
729
730
731 public void setMavenHome( File mavenHome )
732 {
733 this.mavenHome = mavenHome;
734 }
735
736
737
738
739
740
741 public File getBaseDirectory()
742 {
743 return baseDirectory;
744 }
745
746
747
748
749
750
751 public void setBaseDirectory( File baseDirectory )
752 {
753 this.baseDirectory = baseDirectory;
754 }
755
756
757
758
759
760
761 public void setMavenExecutable( File mavenExecutable )
762 {
763 this.mavenExecutable = mavenExecutable;
764 }
765
766
767
768
769
770
771 public File getMavenExecutable()
772 {
773 return mavenExecutable;
774 }
775
776 }