1   package org.apache.maven.shared.invoker;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import junit.framework.TestCase;
23  import org.codehaus.plexus.util.FileUtils;
24  import org.codehaus.plexus.util.IOUtil;
25  import org.codehaus.plexus.util.Os;
26  import org.codehaus.plexus.util.cli.Commandline;
27  
28  import java.io.File;
29  import java.io.FileWriter;
30  import java.io.IOException;
31  import java.util.ArrayList;
32  import java.util.Arrays;
33  import java.util.Collections;
34  import java.util.HashSet;
35  import java.util.Iterator;
36  import java.util.List;
37  import java.util.Properties;
38  import java.util.Set;
39  
40  public class MavenCommandLineBuilderTest
41      extends TestCase
42  {
43  
44      private List toDelete = new ArrayList();
45  
46      private Properties sysProps;
47  
48      public void testWrapwithQuotes()
49      {
50          TestCommandLineBuilder tcb = new TestCommandLineBuilder();
51          String test = "noSpacesInHere";
52  
53          assertSame( test, tcb.wrapStringWithQuotes( test ) );
54          assertEquals( "noSpacesInHere", tcb.wrapStringWithQuotes( test ) );
55  
56          test = "bunch of spaces in here";
57          assertNotSame( test, tcb.wrapStringWithQuotes( test ) );
58          assertEquals( "\"bunch of spaces in here\"", tcb.wrapStringWithQuotes( test ) );
59  
60      }
61  
62      public void testShouldFailToSetLocalRepoLocationGloballyWhenItIsAFile()
63          throws IOException
64      {
65          logTestStart();
66  
67          File lrd = File.createTempFile( "workdir-test", "file" ).getCanonicalFile();
68  
69          toDelete.add( lrd );
70  
71          TestCommandLineBuilder tcb = new TestCommandLineBuilder();
72          tcb.setLocalRepositoryDirectory( lrd );
73  
74          Commandline cli = new Commandline();
75  
76          try
77          {
78              tcb.setEnvironmentPaths( newRequest(), cli );
79              fail( "Should not set local repo location to point to a file." );
80          }
81          catch ( IllegalArgumentException e )
82          {
83              assertTrue( true );
84          }
85      }
86  
87      public void testShouldFailToSetLocalRepoLocationFromRequestWhenItIsAFile()
88          throws IOException
89      {
90          logTestStart();
91  
92          File lrd = File.createTempFile( "workdir-test", "file" ).getCanonicalFile();
93  
94          toDelete.add( lrd );
95  
96          TestCommandLineBuilder tcb = new TestCommandLineBuilder();
97  
98          Commandline cli = new Commandline();
99  
100         try
101         {
102             tcb.setEnvironmentPaths( newRequest().setLocalRepositoryDirectory( lrd ), cli );
103             fail( "Should not set local repo location to point to a file." );
104         }
105         catch ( IllegalArgumentException e )
106         {
107             assertTrue( true );
108         }
109     }
110 
111     public void testShouldSetLocalRepoLocationGlobally()
112         throws Exception
113     {
114         logTestStart();
115 
116         File tmpDir = getTempDir();
117 
118         File lrd = new File( tmpDir, "workdir" ).getCanonicalFile();
119 
120         lrd.mkdirs();
121         toDelete.add( lrd );
122 
123         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
124         tcb.setLocalRepositoryDirectory( lrd );
125 
126         Commandline cli = new Commandline();
127 
128         tcb.setEnvironmentPaths( newRequest(), cli );
129 
130         assertArgumentsPresentInOrder( new String[] { "-D", "maven.repo.local=" + lrd.getPath() }, cli );
131     }
132 
133     public void testShouldSetLocalRepoLocationFromRequest()
134         throws Exception
135     {
136         logTestStart();
137 
138         File tmpDir = getTempDir();
139 
140         File lrd = new File( tmpDir, "workdir" ).getCanonicalFile();
141 
142         lrd.mkdirs();
143         toDelete.add( lrd );
144 
145         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
146 
147         Commandline cli = new Commandline();
148 
149         tcb.setEnvironmentPaths( newRequest().setLocalRepositoryDirectory( lrd ), cli );
150 
151         assertArgumentsPresentInOrder( new String[] { "-D", "maven.repo.local=" + lrd.getPath() }, cli );
152     }
153 
154     public void testRequestProvidedLocalRepoLocationShouldOverrideGlobal()
155         throws Exception
156     {
157         logTestStart();
158 
159         File tmpDir = getTempDir();
160 
161         File lrd = new File( tmpDir, "workdir" ).getCanonicalFile();
162         File glrd = new File( tmpDir, "global-workdir" ).getCanonicalFile();
163 
164         lrd.mkdirs();
165         glrd.mkdirs();
166 
167         toDelete.add( lrd );
168         toDelete.add( glrd );
169 
170         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
171         tcb.setLocalRepositoryDirectory( glrd );
172 
173         Commandline cli = new Commandline();
174 
175         tcb.setEnvironmentPaths( newRequest().setLocalRepositoryDirectory( lrd ), cli );
176 
177         assertArgumentsPresentInOrder( new String[] { "-D", "maven.repo.local=" + lrd.getPath() }, cli );
178     }
179 
180     public void testShouldSetWorkingDirectoryGlobally()
181         throws Exception
182     {
183         logTestStart();
184 
185         File tmpDir = getTempDir();
186 
187         File wd = new File( tmpDir, "workdir" );
188 
189         wd.mkdirs();
190 
191         toDelete.add( wd );
192 
193         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
194         tcb.setWorkingDirectory( wd );
195 
196         Commandline cli = new Commandline();
197 
198         tcb.setEnvironmentPaths( newRequest(), cli );
199 
200         assertEquals( cli.getWorkingDirectory(), wd );
201     }
202 
203     public void testShouldSetWorkingDirectoryFromRequest()
204         throws Exception
205     {
206         logTestStart();
207 
208         File tmpDir = getTempDir();
209 
210         File wd = new File( tmpDir, "workdir" );
211 
212         wd.mkdirs();
213 
214         toDelete.add( wd );
215 
216         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
217         InvocationRequest req = newRequest();
218         req.setBaseDirectory( wd );
219 
220         Commandline cli = new Commandline();
221 
222         tcb.setEnvironmentPaths( req, cli );
223 
224         assertEquals( cli.getWorkingDirectory(), wd );
225     }
226 
227     public void testRequestProvidedWorkingDirectoryShouldOverrideGlobal()
228         throws Exception
229     {
230         logTestStart();
231 
232         File tmpDir = getTempDir();
233 
234         File wd = new File( tmpDir, "workdir" );
235         File gwd = new File( tmpDir, "global-workdir" );
236 
237         wd.mkdirs();
238         gwd.mkdirs();
239 
240         toDelete.add( wd );
241         toDelete.add( gwd );
242 
243         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
244         tcb.setWorkingDirectory( gwd );
245 
246         InvocationRequest req = newRequest();
247         req.setBaseDirectory( wd );
248 
249         Commandline cli = new Commandline();
250 
251         tcb.setEnvironmentPaths( req, cli );
252 
253         assertEquals( cli.getWorkingDirectory(), wd );
254     }
255 
256     public void testShouldUseSystemOutLoggerWhenNoneSpecified()
257         throws Exception
258     {
259         logTestStart();
260         setupTempMavenHomeIfMissing();
261 
262         TestCommandLineBuilder tclb = new TestCommandLineBuilder();
263         tclb.checkRequiredState();
264     }
265 
266     private File setupTempMavenHomeIfMissing()
267         throws Exception
268     {
269         String mavenHome = System.getProperty( "maven.home" );
270 
271         File appDir = null;
272 
273         if ( ( mavenHome == null ) || !new File( mavenHome ).exists() )
274         {
275             File tmpDir = getTempDir();
276             appDir = new File( tmpDir, "invoker-tests/maven-home" );
277 
278             File binDir = new File( appDir, "bin" );
279 
280             binDir.mkdirs();
281             toDelete.add( appDir );
282 
283             if ( Os.isFamily( Os.FAMILY_WINDOWS ) )
284             {
285                 createDummyFile( binDir, "mvn.bat" );
286             }
287             else
288             {
289                 createDummyFile( binDir, "mvn" );
290             }
291 
292             Properties props = System.getProperties();
293             props.setProperty( "maven.home", appDir.getCanonicalPath() );
294 
295             System.setProperties( props );
296         }
297         else
298         {
299             appDir = new File( mavenHome );
300         }
301 
302         return appDir;
303     }
304 
305     public void testShouldFailIfLoggerSetToNull()
306     {
307         logTestStart();
308 
309         TestCommandLineBuilder tclb = new TestCommandLineBuilder();
310         tclb.setLogger( null );
311 
312         try
313         {
314             tclb.checkRequiredState();
315             fail( "Should not allow execution to proceed when logger is missing." );
316         }
317         catch ( IllegalStateException e )
318         {
319             assertTrue( true );
320         }
321         catch ( IOException e )
322         {
323             fail( e.getMessage() );
324         }
325     }
326 
327     public void testShouldFindDummyMavenExecutable()
328         throws Exception
329     {
330         logTestStart();
331 
332         File tmpDir = getTempDir();
333 
334         File base = new File( tmpDir, "invoker-tests" );
335 
336         File dummyMavenHomeBin = new File( base, "dummy-maven-home/bin" );
337 
338         dummyMavenHomeBin.mkdirs();
339 
340         toDelete.add( base );
341 
342         File check;
343         if ( Os.isFamily( Os.FAMILY_WINDOWS ) )
344         {
345             check = createDummyFile( dummyMavenHomeBin, "mvn.bat" );
346         }
347         else
348         {
349             check = createDummyFile( dummyMavenHomeBin, "mvn" );
350         }
351 
352         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
353         tcb.setMavenHome( dummyMavenHomeBin.getParentFile() );
354 
355         File mavenExe = tcb.findMavenExecutable();
356 
357         assertEquals( check.getCanonicalPath(), mavenExe.getCanonicalPath() );
358     }
359 
360     public void testShouldSetBatchModeFlagFromRequest()
361     {
362         logTestStart();
363 
364         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
365         Commandline cli = new Commandline();
366 
367         tcb.setFlags( newRequest().setInteractive( false ), cli );
368 
369         assertArgumentsPresent( Collections.singleton( "-B" ), cli );
370     }
371 
372     public void testShouldSetOfflineFlagFromRequest()
373     {
374         logTestStart();
375 
376         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
377         Commandline cli = new Commandline();
378 
379         tcb.setFlags( newRequest().setOffline( true ), cli );
380 
381         assertArgumentsPresent( Collections.singleton( "-o" ), cli );
382     }
383 
384     public void testShouldSetUpdateSnapshotsFlagFromRequest()
385     {
386         logTestStart();
387 
388         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
389         Commandline cli = new Commandline();
390 
391         tcb.setFlags( newRequest().setUpdateSnapshots( true ), cli );
392 
393         assertArgumentsPresent( Collections.singleton( "-U" ), cli );
394     }
395 
396     public void testShouldSetDebugFlagFromRequest()
397     {
398         logTestStart();
399 
400         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
401         Commandline cli = new Commandline();
402 
403         tcb.setFlags( newRequest().setDebug( true ), cli );
404 
405         assertArgumentsPresent( Collections.singleton( "-X" ), cli );
406     }
407 
408     public void testShouldSetErrorFlagFromRequest()
409     {
410         logTestStart();
411 
412         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
413         Commandline cli = new Commandline();
414 
415         tcb.setFlags( newRequest().setShowErrors( true ), cli );
416 
417         assertArgumentsPresent( Collections.singleton( "-e" ), cli );
418     }
419 
420     public void testDebugOptionShouldMaskShowErrorsOption()
421     {
422         logTestStart();
423 
424         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
425         Commandline cli = new Commandline();
426 
427         tcb.setFlags( newRequest().setDebug( true ).setShowErrors( true ), cli );
428 
429         assertArgumentsPresent( Collections.singleton( "-X" ), cli );
430         assertArgumentsNotPresent( Collections.singleton( "-e" ), cli );
431     }
432     
433     public void testActivateReactor()
434     {
435         logTestStart();
436         
437         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
438         Commandline cli = new Commandline();
439 
440         tcb.setReactorBehavior( newRequest().activateReactor( null, null ), cli );
441 
442         assertArgumentsPresent( Collections.singleton( "-r" ), cli );
443 
444         
445     }
446     
447     public void testActivateReactorIncludesExcludes()
448     {
449         logTestStart();
450         
451         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
452         Commandline cli = new Commandline();
453 
454         String[] includes = new String[] {"foo", "bar"};
455         String[] excludes = new String[] {"baz", "quz"};
456         
457         tcb.setReactorBehavior( newRequest().activateReactor( includes, excludes ), cli );
458         
459         Set args = new HashSet();
460         args.add( "-r" );
461         args.add( "-D" );
462         args.add( "maven.reactor.includes=foo,bar" );
463         args.add( "maven.reactor.excludes=baz,quz" );
464 
465         assertArgumentsPresent( args, cli );
466 
467 
468         
469     }
470 
471     public void testShouldSetStrictChecksumPolityFlagFromRequest()
472     {
473         logTestStart();
474 
475         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
476         Commandline cli = new Commandline();
477 
478         tcb.setFlags( newRequest().setGlobalChecksumPolicy( InvocationRequest.CHECKSUM_POLICY_FAIL ), cli );
479 
480         assertArgumentsPresent( Collections.singleton( "-C" ), cli );
481     }
482 
483     public void testShouldSetLaxChecksumPolicyFlagFromRequest()
484     {
485         logTestStart();
486 
487         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
488         Commandline cli = new Commandline();
489 
490         tcb.setFlags( newRequest().setGlobalChecksumPolicy( InvocationRequest.CHECKSUM_POLICY_WARN ), cli );
491 
492         assertArgumentsPresent( Collections.singleton( "-c" ), cli );
493     }
494 
495     public void testShouldSetFailAtEndFlagFromRequest()
496     {
497         logTestStart();
498 
499         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
500         Commandline cli = new Commandline();
501 
502         tcb.setReactorBehavior( newRequest().setFailureBehavior( InvocationRequest.REACTOR_FAIL_AT_END ), cli );
503 
504         assertArgumentsPresent( Collections.singleton( "-fae" ), cli );
505     }
506 
507     public void testShouldSetFailNeverFlagFromRequest()
508     {
509         logTestStart();
510 
511         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
512         Commandline cli = new Commandline();
513 
514         tcb.setReactorBehavior( newRequest().setFailureBehavior( InvocationRequest.REACTOR_FAIL_NEVER ), cli );
515 
516         assertArgumentsPresent( Collections.singleton( "-fn" ), cli );
517     }
518 
519     public void testShouldUseDefaultOfFailFastWhenSpecifiedInRequest()
520     {
521         logTestStart();
522 
523         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
524         Commandline cli = new Commandline();
525 
526         tcb.setReactorBehavior( newRequest().setFailureBehavior( InvocationRequest.REACTOR_FAIL_FAST ), cli );
527 
528         Set banned = new HashSet();
529         banned.add( "-fae" );
530         banned.add( "-fn" );
531 
532         assertArgumentsNotPresent( banned, cli );
533     }
534 
535     public void testShouldSpecifyFileOptionUsingNonStandardPomFileLocation()
536         throws Exception
537     {
538         logTestStart();
539 
540         File tmpDir = getTempDir();
541         File base = new File( tmpDir, "invoker-tests" );
542 
543         toDelete.add( base );
544 
545         File projectDir = new File( base, "file-option-nonstd-pom-file-location" ).getCanonicalFile();
546 
547         projectDir.mkdirs();
548 
549         File pomFile = createDummyFile( projectDir, "non-standard-pom.xml" ).getCanonicalFile();
550 
551         Commandline cli = new Commandline();
552 
553         InvocationRequest req = newRequest().setPomFile( pomFile );
554 
555         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
556         tcb.setEnvironmentPaths( req, cli );
557         tcb.setPomLocation( req, cli );
558 
559         assertEquals( projectDir, cli.getWorkingDirectory() );
560 
561         Set args = new HashSet();
562         args.add( "-f" );
563         args.add( "non-standard-pom.xml" );
564 
565         assertArgumentsPresent( args, cli );
566     }
567 
568     public void testShouldSpecifyFileOptionUsingNonStandardPomInBasedir()
569         throws Exception
570     {
571         logTestStart();
572 
573         File tmpDir = getTempDir();
574         File base = new File( tmpDir, "invoker-tests" );
575 
576         toDelete.add( base );
577 
578         File projectDir = new File( base, "file-option-nonstd-basedir" ).getCanonicalFile();
579 
580         projectDir.mkdirs();
581 
582         File basedir = createDummyFile( projectDir, "non-standard-pom.xml" ).getCanonicalFile();
583 
584         Commandline cli = new Commandline();
585 
586         InvocationRequest req = newRequest().setBaseDirectory( basedir );
587 
588         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
589         tcb.setEnvironmentPaths( req, cli );
590         tcb.setPomLocation( req, cli );
591 
592         assertEquals( projectDir, cli.getWorkingDirectory() );
593 
594         Set args = new HashSet();
595         args.add( "-f" );
596         args.add( "non-standard-pom.xml" );
597 
598         assertArgumentsPresent( args, cli );
599     }
600 
601     public void testShouldNotSpecifyFileOptionUsingStandardPomFileLocation()
602         throws Exception
603     {
604         logTestStart();
605 
606         File tmpDir = getTempDir();
607         File base = new File( tmpDir, "invoker-tests" );
608 
609         toDelete.add( base );
610 
611         File projectDir = new File( base, "std-pom-file-location" ).getCanonicalFile();
612 
613         projectDir.mkdirs();
614 
615         File pomFile = createDummyFile( projectDir, "pom.xml" ).getCanonicalFile();
616 
617         Commandline cli = new Commandline();
618 
619         InvocationRequest req = newRequest().setPomFile( pomFile );
620 
621         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
622         tcb.setEnvironmentPaths( req, cli );
623         tcb.setPomLocation( req, cli );
624 
625         assertEquals( projectDir, cli.getWorkingDirectory() );
626 
627         Set args = new HashSet();
628         args.add( "-f" );
629         args.add( "pom.xml" );
630 
631         assertArgumentsNotPresent( args, cli );
632     }
633 
634     public void testShouldNotSpecifyFileOptionUsingStandardPomInBasedir()
635         throws Exception
636     {
637         logTestStart();
638 
639         File tmpDir = getTempDir();
640         File base = new File( tmpDir, "invoker-tests" );
641 
642         toDelete.add( base );
643 
644         File projectDir = new File( base, "std-basedir-is-pom-file" ).getCanonicalFile();
645 
646         projectDir.mkdirs();
647 
648         File basedir = createDummyFile( projectDir, "pom.xml" ).getCanonicalFile();
649 
650         Commandline cli = new Commandline();
651 
652         InvocationRequest req = newRequest().setBaseDirectory( basedir );
653 
654         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
655         tcb.setEnvironmentPaths( req, cli );
656         tcb.setPomLocation( req, cli );
657 
658         assertEquals( projectDir, cli.getWorkingDirectory() );
659 
660         Set args = new HashSet();
661         args.add( "-f" );
662         args.add( "pom.xml" );
663 
664         assertArgumentsNotPresent( args, cli );
665     }
666 
667     public void testShouldUseDefaultPomFileWhenBasedirSpecifiedWithoutPomFileName()
668         throws Exception
669     {
670         logTestStart();
671 
672         File tmpDir = getTempDir();
673         File base = new File( tmpDir, "invoker-tests" );
674 
675         toDelete.add( base );
676 
677         File projectDir = new File( base, "std-basedir-no-pom-filename" ).getCanonicalFile();
678 
679         projectDir.mkdirs();
680 
681         Commandline cli = new Commandline();
682 
683         InvocationRequest req = newRequest().setBaseDirectory( projectDir );
684 
685         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
686         tcb.setEnvironmentPaths( req, cli );
687         tcb.setPomLocation( req, cli );
688 
689         assertEquals( projectDir, cli.getWorkingDirectory() );
690 
691         Set args = new HashSet();
692         args.add( "-f" );
693         args.add( "pom.xml" );
694 
695         assertArgumentsNotPresent( args, cli );
696     }
697 
698     public void testShouldSpecifyPomFileWhenBasedirSpecifiedWithPomFileName()
699         throws Exception
700     {
701         logTestStart();
702 
703         File tmpDir = getTempDir();
704         File base = new File( tmpDir, "invoker-tests" );
705 
706         toDelete.add( base );
707 
708         File projectDir = new File( base, "std-basedir-with-pom-filename" ).getCanonicalFile();
709 
710         projectDir.mkdirs();
711 
712         Commandline cli = new Commandline();
713 
714         InvocationRequest req = newRequest().setBaseDirectory( projectDir ).setPomFileName( "non-standard-pom.xml" );
715 
716         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
717         tcb.setEnvironmentPaths( req, cli );
718         tcb.setPomLocation( req, cli );
719 
720         assertEquals( projectDir, cli.getWorkingDirectory() );
721 
722         Set args = new HashSet();
723         args.add( "-f" );
724         args.add( "non-standard-pom.xml" );
725 
726         assertArgumentsPresent( args, cli );
727     }
728 
729     public void testShouldSpecifyCustomSettingsLocationFromRequest()
730         throws Exception
731     {
732         logTestStart();
733 
734         File tmpDir = getTempDir();
735         File base = new File( tmpDir, "invoker-tests" );
736 
737         toDelete.add( base );
738 
739         File projectDir = new File( base, "custom-settings" ).getCanonicalFile();
740 
741         projectDir.mkdirs();
742 
743         File settingsFile = createDummyFile( projectDir, "settings.xml" );
744 
745         Commandline cli = new Commandline();
746 
747         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
748         tcb.setSettingsLocation( newRequest().setUserSettingsFile( settingsFile ), cli );
749 
750         Set args = new HashSet();
751         args.add( "-s" );
752         args.add( settingsFile.getCanonicalPath() );
753 
754         assertArgumentsPresent( args, cli );
755     }
756 
757     public void testShouldSpecifyCustomPropertyFromRequest()
758         throws IOException
759     {
760         logTestStart();
761 
762         Commandline cli = new Commandline();
763 
764         Properties properties = new Properties();
765         properties.setProperty( "key", "value" );
766 
767         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
768         tcb.setProperties( newRequest().setProperties( properties ), cli );
769 
770         assertArgumentsPresentInOrder( new String[] { "-D", "key=value" }, cli );
771     }
772 
773     public void testShouldSpecifyCustomPropertyWithSpacesInValueFromRequest()
774         throws IOException
775     {
776         logTestStart();
777 
778         Commandline cli = new Commandline();
779 
780         Properties properties = new Properties();
781         properties.setProperty( "key", "value with spaces" );
782 
783         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
784         tcb.setProperties( newRequest().setProperties( properties ), cli );
785 
786         assertArgumentsPresentInOrder( new String[] { "-D", "key=value with spaces" }, cli );
787     }
788 
789     public void testShouldSpecifyCustomPropertyWithSpacesInKeyFromRequest()
790         throws IOException
791     {
792         logTestStart();
793 
794         Commandline cli = new Commandline();
795 
796         Properties properties = new Properties();
797         properties.setProperty( "key with spaces", "value with spaces" );
798 
799         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
800         tcb.setProperties( newRequest().setProperties( properties ), cli );
801 
802         assertArgumentsPresentInOrder( new String[] { "-D", "key with spaces=value with spaces" }, cli );
803     }
804 
805     public void testShouldSpecifySingleGoalFromRequest()
806         throws IOException
807     {
808         logTestStart();
809 
810         Commandline cli = new Commandline();
811 
812         List goals = new ArrayList();
813         goals.add( "test" );
814 
815         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
816         tcb.setGoals( newRequest().setGoals( goals ), cli );
817 
818         assertArgumentsPresent( Collections.singleton( "test" ), cli );
819     }
820 
821     public void testShouldSpecifyTwoGoalsFromRequest()
822         throws IOException
823     {
824         logTestStart();
825 
826         Commandline cli = new Commandline();
827 
828         List goals = new ArrayList();
829         goals.add( "test" );
830         goals.add( "clean" );
831 
832         TestCommandLineBuilder tcb = new TestCommandLineBuilder();
833         tcb.setGoals( newRequest().setGoals( goals ), cli );
834 
835         assertArgumentsPresent( new HashSet( goals ), cli );
836         assertArgumentsPresentInOrder( goals, cli );
837     }
838 
839     public void testBuildTypicalMavenInvocationEndToEnd()
840         throws Exception
841     {
842         logTestStart();
843         File mavenDir = setupTempMavenHomeIfMissing();
844 
845         InvocationRequest request = newRequest();
846 
847         File tmpDir = getTempDir();
848         File projectDir = new File( tmpDir, "invoker-tests/typical-end-to-end-cli-build" );
849 
850         projectDir.mkdirs();
851         toDelete.add( projectDir.getParentFile() );
852 
853         request.setBaseDirectory( projectDir );
854 
855         Set expectedArgs = new HashSet();
856         Set bannedArgs = new HashSet();
857 
858         createDummyFile( projectDir, "pom.xml" );
859 
860         bannedArgs.add( "-f" );
861         bannedArgs.add( "pom.xml" );
862 
863         Properties properties = new Properties();
864         // this is REALLY bad practice, but since it's just a test...
865         properties.setProperty( "maven.tests.skip", "true" );
866 
867         expectedArgs.add( "maven.tests.skip=true" );
868 
869         request.setProperties( properties );
870 
871         request.setOffline( true );
872 
873         expectedArgs.add( "-o" );
874 
875         List goals = new ArrayList();
876 
877         goals.add( "post-clean" );
878         goals.add( "deploy" );
879         goals.add( "site-deploy" );
880 
881         request.setGoals( goals );
882 
883         MavenCommandLineBuilder commandLineBuilder = new MavenCommandLineBuilder();
884 
885         Commandline commandline = commandLineBuilder.build( request );
886 
887         assertArgumentsPresent( expectedArgs, commandline );
888         assertArgumentsNotPresent( bannedArgs, commandline );
889         assertArgumentsPresentInOrder( goals, commandline );
890 
891         File mavenFile;
892         if ( Os.isFamily( Os.FAMILY_WINDOWS ) )
893         {
894             mavenFile = new File( mavenDir, "bin/mvn.bat" );
895         }
896         else
897         {
898             mavenFile = new File( mavenDir, "bin/mvn" );
899         }
900 
901         String executable = commandline.getExecutable();
902         System.out.println( "Executable is: " + executable );
903 
904         assertTrue( executable.indexOf( mavenFile.getCanonicalPath() ) > -1 );
905         assertEquals( projectDir.getCanonicalPath(), commandline.getWorkingDirectory().getCanonicalPath() );
906     }
907 
908     public void testShouldSetEnvVar_MAVEN_TERMINATE_CMD()
909         throws Exception
910     {
911         logTestStart();
912         setupTempMavenHomeIfMissing();
913 
914         InvocationRequest request = newRequest();
915 
916         File tmpDir = getTempDir();
917         File projectDir = new File( tmpDir, "invoker-tests/maven-terminate-cmd-options-set" );
918 
919         projectDir.mkdirs();
920         toDelete.add( projectDir.getParentFile() );
921 
922         request.setBaseDirectory( projectDir );
923 
924         createDummyFile( projectDir, "pom.xml" );
925 
926         List goals = new ArrayList();
927 
928         goals.add( "clean" );
929         request.setGoals( goals );
930 
931         MavenCommandLineBuilder commandLineBuilder = new MavenCommandLineBuilder();
932 
933         Commandline commandline = commandLineBuilder.build( request );
934 
935         String[] environmentVariables = commandline.getEnvironmentVariables();
936         String envVarMavenTerminateCmd = null;
937         for ( int i = 0; i < environmentVariables.length; i++ )
938         {
939             String envVar = environmentVariables[i];
940             if ( envVar.startsWith( "MAVEN_TERMINATE_CMD=" ) )
941             {
942                 envVarMavenTerminateCmd = envVar;
943                 break;
944             }
945         }
946         assertEquals( "MAVEN_TERMINATE_CMD=on", envVarMavenTerminateCmd );
947 
948     }
949 
950     public void testShouldInsertActivatedProfiles()
951         throws Exception
952     {
953         setupTempMavenHomeIfMissing();
954 
955         String profile1 = "profile-1";
956         String profile2 = "profile-2";
957 
958         InvocationRequest request = newRequest();
959 
960         List profiles = new ArrayList();
961         profiles.add( profile1 );
962         profiles.add( profile2 );
963 
964         request.setProfiles( profiles );
965 
966         MavenCommandLineBuilder commandLineBuilder = new MavenCommandLineBuilder();
967 
968         Commandline commandline = commandLineBuilder.build( request );
969 
970         assertArgumentsPresentInOrder( new String[] { "-P", profile1 + "," + profile2 }, commandline );
971     }
972 
973     public void setUp()
974     {
975         sysProps = System.getProperties();
976 
977         Properties p = new Properties( sysProps );
978 
979         System.setProperties( p );
980     }
981 
982     public void tearDown()
983         throws IOException
984     {
985         System.setProperties( sysProps );
986 
987         for ( Iterator it = toDelete.iterator(); it.hasNext(); )
988         {
989             File file = (File) it.next();
990 
991             if ( file.exists() )
992             {
993                 if ( file.isDirectory() )
994                 {
995                     FileUtils.deleteDirectory( file );
996                 }
997                 else
998                 {
999                     file.delete();
1000                 }
1001             }
1002         }
1003     }
1004 
1005     // this is just a debugging helper for separating unit test output...
1006     private void logTestStart()
1007     {
1008         NullPointerException npe = new NullPointerException();
1009         StackTraceElement element = npe.getStackTrace()[1];
1010 
1011         System.out.println( "Starting: " + element.getMethodName() );
1012     }
1013 
1014     private void assertArgumentsPresentInOrder( String[] expected, Commandline cli )
1015     {
1016         assertArgumentsPresentInOrder( Arrays.asList( expected ), cli );
1017     }
1018 
1019     private void assertArgumentsPresentInOrder( List expected, Commandline cli )
1020     {
1021         String[] arguments = cli.getArguments();
1022 
1023         int expectedCounter = 0;
1024 
1025         for ( int i = 0; i < arguments.length; i++ )
1026         {
1027             if ( arguments[i].equals( expected.get( expectedCounter ) ) )
1028             {
1029                 expectedCounter++;
1030             }
1031         }
1032 
1033         assertEquals( "Arguments: " + expected + " were not found or are in the wrong order: "
1034             + Arrays.asList( arguments ), expected.size(), expectedCounter );
1035     }
1036 
1037     private void assertArgumentsPresent( Set requiredArgs, Commandline cli )
1038     {
1039         String[] argv = cli.getArguments();
1040         List args = Arrays.asList( argv );
1041 
1042         for ( Iterator it = requiredArgs.iterator(); it.hasNext(); )
1043         {
1044             String arg = (String) it.next();
1045 
1046             assertTrue( "Command-line argument: \'" + arg + "\' is missing in " + args, args.contains( arg ) );
1047         }
1048     }
1049 
1050     private void assertArgumentsNotPresent( Set bannedArgs, Commandline cli )
1051     {
1052         String[] argv = cli.getArguments();
1053         List args = Arrays.asList( argv );
1054 
1055         for ( Iterator it = bannedArgs.iterator(); it.hasNext(); )
1056         {
1057             String arg = (String) it.next();
1058 
1059             assertFalse( "Command-line argument: \'" + arg + "\' should not be present.", args.contains( arg ) );
1060         }
1061     }
1062 
1063     private File createDummyFile( File directory, String filename )
1064         throws IOException
1065     {
1066         File dummyFile = new File( directory, filename );
1067 
1068         FileWriter writer = null;
1069         try
1070         {
1071             writer = new FileWriter( dummyFile );
1072             writer.write( "This is a dummy file." );
1073         }
1074         finally
1075         {
1076             IOUtil.close( writer );
1077         }
1078 
1079         toDelete.add( dummyFile );
1080 
1081         return dummyFile;
1082     }
1083 
1084     private static final class TestCommandLineBuilder
1085         extends MavenCommandLineBuilder
1086     {
1087         public void checkRequiredState()
1088             throws IOException
1089         {
1090             super.checkRequiredState();
1091         }
1092 
1093         public File findMavenExecutable()
1094             throws CommandLineConfigurationException, IOException
1095         {
1096             return super.findMavenExecutable();
1097         }
1098 
1099         public void setEnvironmentPaths( InvocationRequest request, Commandline cli )
1100         {
1101             super.setEnvironmentPaths( request, cli );
1102         }
1103 
1104         public void setFlags( InvocationRequest request, Commandline cli )
1105         {
1106             super.setFlags( request, cli );
1107         }
1108 
1109         public void setGoals( InvocationRequest request, Commandline cli )
1110         {
1111             super.setGoals( request, cli );
1112         }
1113 
1114         public void setPomLocation( InvocationRequest request, Commandline cli )
1115         {
1116             super.setPomLocation( request, cli );
1117         }
1118 
1119         public void setProperties( InvocationRequest request, Commandline cli )
1120         {
1121             super.setProperties( request, cli );
1122         }
1123 
1124         public void setReactorBehavior( InvocationRequest request, Commandline cli )
1125         {
1126             super.setReactorBehavior( request, cli );
1127         }
1128 
1129         public void setSettingsLocation( InvocationRequest request, Commandline cli )
1130         {
1131             super.setSettingsLocation( request, cli );
1132         }
1133 
1134         public void setShellEnvironment( InvocationRequest request, Commandline cli )
1135             throws CommandLineConfigurationException
1136         {
1137             super.setShellEnvironment( request, cli );
1138         }
1139 
1140     }
1141 
1142     private File getTempDir()
1143         throws Exception
1144     {
1145         return new File( System.getProperty( "java.io.tmpdir" ) ).getCanonicalFile();
1146     }
1147 
1148     private InvocationRequest newRequest()
1149     {
1150         return new DefaultInvocationRequest();
1151     }
1152 
1153 }