KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > maven > cli > MavenCli


1 package org.apache.maven.cli;
2
3 /*
4  * Copyright 2001-2005 The Apache Software Foundation.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */

18
19 import org.apache.commons.cli.CommandLine;
20 import org.apache.commons.cli.CommandLineParser;
21 import org.apache.commons.cli.GnuParser;
22 import org.apache.commons.cli.HelpFormatter;
23 import org.apache.commons.cli.OptionBuilder;
24 import org.apache.commons.cli.Options;
25 import org.apache.commons.cli.ParseException;
26 import org.apache.maven.Maven;
27 import org.apache.maven.SettingsConfigurationException;
28 import org.apache.maven.artifact.manager.WagonManager;
29 import org.apache.maven.artifact.repository.ArtifactRepository;
30 import org.apache.maven.artifact.repository.ArtifactRepositoryFactory;
31 import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
32 import org.apache.maven.artifact.repository.DefaultArtifactRepository;
33 import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
34 import org.apache.maven.execution.DefaultMavenExecutionRequest;
35 import org.apache.maven.execution.MavenExecutionRequest;
36 import org.apache.maven.execution.ReactorManager;
37 import org.apache.maven.monitor.event.DefaultEventDispatcher;
38 import org.apache.maven.monitor.event.DefaultEventMonitor;
39 import org.apache.maven.monitor.event.EventDispatcher;
40 import org.apache.maven.plugin.Mojo;
41 import org.apache.maven.profiles.DefaultProfileManager;
42 import org.apache.maven.profiles.ProfileManager;
43 import org.apache.maven.reactor.MavenExecutionException;
44 import org.apache.maven.settings.MavenSettingsBuilder;
45 import org.apache.maven.settings.RuntimeInfo;
46 import org.apache.maven.settings.Settings;
47 import org.codehaus.classworlds.ClassWorld;
48 import org.codehaus.plexus.PlexusContainerException;
49 import org.codehaus.plexus.component.repository.exception.ComponentLifecycleException;
50 import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
51 import org.codehaus.plexus.embed.Embedder;
52 import org.codehaus.plexus.logging.Logger;
53 import org.codehaus.plexus.logging.LoggerManager;
54 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
55
56 import java.io.File JavaDoc;
57 import java.io.IOException JavaDoc;
58 import java.io.InputStream JavaDoc;
59 import java.util.ArrayList JavaDoc;
60 import java.util.List JavaDoc;
61 import java.util.Properties JavaDoc;
62 import java.util.StringTokenizer JavaDoc;
63
64 /**
65  * @author <a HREF="mailto:jason@maven.org">Jason van Zyl</a>
66  * @version $Id: MavenCli.java 382460 2006-03-02 18:13:01Z jdcasey $
67  * @noinspection UseOfSystemOutOrSystemErr,ACCESS_STATIC_VIA_INSTANCE
68  */

69 public class MavenCli
70 {
71     private static Embedder embedder;
72
73     /**
74      * @noinspection ConfusingMainMethod
75      */

76     public static int main( String JavaDoc[] args, ClassWorld classWorld )
77     {
78         // ----------------------------------------------------------------------
79
// Setup the command line parser
80
// ----------------------------------------------------------------------
81

82         CLIManager cliManager = new CLIManager();
83
84         CommandLine commandLine;
85         try
86         {
87             commandLine = cliManager.parse( args );
88         }
89         catch ( ParseException e )
90         {
91             System.err.println( "Unable to parse command line options: " + e.getMessage() );
92             cliManager.displayHelp();
93             return 1;
94         }
95
96         // TODO: maybe classworlds could handle this requirement...
97
if ( System.getProperty( "java.class.version", "44.0" ).compareTo( "48.0" ) < 0 )
98         {
99             System.err.println( "Sorry, but JDK 1.4 or above is required to execute Maven" );
100             System.err.println(
101                 "You appear to be using Java version: " + System.getProperty( "java.version", "<unknown>" ) );
102
103             return 1;
104         }
105
106         boolean debug = commandLine.hasOption( CLIManager.DEBUG );
107
108         boolean showErrors = debug || commandLine.hasOption( CLIManager.ERRORS );
109
110         if ( showErrors )
111         {
112             System.out.println( "+ Error stacktraces are turned on." );
113         }
114
115         // ----------------------------------------------------------------------
116
// Process particular command line options
117
// ----------------------------------------------------------------------
118

119         if ( commandLine.hasOption( CLIManager.HELP ) )
120         {
121             cliManager.displayHelp();
122             return 0;
123         }
124         
125         if ( commandLine.hasOption( CLIManager.VERSION ) )
126         {
127             showVersion();
128
129             return 0;
130         }
131         else if ( debug )
132         {
133             showVersion();
134         }
135
136         EventDispatcher eventDispatcher = new DefaultEventDispatcher();
137
138         // ----------------------------------------------------------------------
139
// Now that we have everything that we need we will fire up plexus and
140
// bring the maven component to life for use.
141
// ----------------------------------------------------------------------
142

143         embedder = new Embedder();
144
145         try
146         {
147             embedder.start( classWorld );
148         }
149         catch ( PlexusContainerException e )
150         {
151             showFatalError( "Unable to start the embedded plexus container", e, showErrors );
152
153             return 1;
154         }
155
156         // ----------------------------------------------------------------------
157
// The execution properties need to be created before the settings
158
// are constructed.
159
// ----------------------------------------------------------------------
160

161         Properties JavaDoc executionProperties = getExecutionProperties( commandLine );
162
163         Settings settings;
164
165         try
166         {
167             settings = buildSettings( commandLine );
168         }
169         catch ( SettingsConfigurationException e )
170         {
171             showError( "Error reading settings.xml: " + e.getMessage(), e, showErrors );
172
173             return 1;
174         }
175         catch ( ComponentLookupException e )
176         {
177             showFatalError( "Unable to read settings.xml", e, showErrors );
178
179             return 1;
180         }
181
182         Maven maven = null;
183
184         MavenExecutionRequest request = null;
185
186         LoggerManager loggerManager = null;
187
188         try
189         {
190             // logger must be created first
191
loggerManager = (LoggerManager) embedder.lookup( LoggerManager.ROLE );
192
193             if ( debug )
194             {
195                 loggerManager.setThreshold( Logger.LEVEL_DEBUG );
196             }
197
198             ProfileManager profileManager = new DefaultProfileManager( embedder.getContainer() );
199
200             if ( commandLine.hasOption( CLIManager.ACTIVATE_PROFILES ) )
201             {
202                 String JavaDoc profilesLine = commandLine.getOptionValue( CLIManager.ACTIVATE_PROFILES );
203
204                 StringTokenizer JavaDoc profileTokens = new StringTokenizer JavaDoc( profilesLine, "," );
205
206                 while ( profileTokens.hasMoreTokens() )
207                 {
208                     String JavaDoc profileAction = profileTokens.nextToken().trim();
209
210                     if ( profileAction.startsWith( "-" ) )
211                     {
212                         profileManager.explicitlyDeactivate( profileAction.substring( 1 ) );
213                     }
214                     else if ( profileAction.startsWith( "+" ) )
215                     {
216                         profileManager.explicitlyActivate( profileAction.substring( 1 ) );
217                     }
218                     else
219                     {
220                         // TODO: deprecate this eventually!
221
profileManager.explicitlyActivate( profileAction );
222                     }
223                 }
224             }
225
226             request = createRequest( commandLine, settings, eventDispatcher, loggerManager, profileManager,
227                                      executionProperties, showErrors );
228
229             setProjectFileOptions( commandLine, request );
230
231             maven = createMavenInstance( settings.isInteractiveMode() );
232         }
233         catch ( ComponentLookupException e )
234         {
235             showFatalError( "Unable to configure the Maven application", e, showErrors );
236
237             return 1;
238         }
239         finally
240         {
241             if ( loggerManager != null )
242             {
243                 try
244                 {
245                     embedder.release( loggerManager );
246                 }
247                 catch ( ComponentLifecycleException e )
248                 {
249                     showFatalError( "Error releasing logging manager", e, showErrors );
250                 }
251             }
252         }
253
254         try
255         {
256             maven.execute( request );
257         }
258         catch ( MavenExecutionException e )
259         {
260             return 1;
261         }
262
263         return 0;
264     }
265
266     private static Settings buildSettings( CommandLine commandLine )
267         throws ComponentLookupException, SettingsConfigurationException
268     {
269         String JavaDoc userSettingsPath = null;
270
271         if ( commandLine.hasOption( CLIManager.ALTERNATE_USER_SETTINGS ) )
272         {
273             userSettingsPath = commandLine.getOptionValue( CLIManager.ALTERNATE_USER_SETTINGS );
274         }
275
276         Settings settings = null;
277
278         MavenSettingsBuilder settingsBuilder = (MavenSettingsBuilder) embedder.lookup( MavenSettingsBuilder.ROLE );
279
280         try
281         {
282             if ( userSettingsPath != null )
283             {
284                 File JavaDoc userSettingsFile = new File JavaDoc( userSettingsPath );
285
286                 if ( userSettingsFile.exists() && !userSettingsFile.isDirectory() )
287                 {
288                     settings = settingsBuilder.buildSettings( userSettingsFile );
289                 }
290                 else
291                 {
292                     System.out.println( "WARNING: Alternate user settings file: " + userSettingsPath +
293                         " is invalid. Using default path." );
294                 }
295             }
296
297             if ( settings == null )
298             {
299                 settings = settingsBuilder.buildSettings();
300             }
301         }
302         catch ( IOException JavaDoc e )
303         {
304             throw new SettingsConfigurationException( "Error reading settings file", e );
305         }
306         catch ( XmlPullParserException e )
307         {
308             throw new SettingsConfigurationException( e.getMessage(), e.getDetail(), e.getLineNumber(),
309                                                       e.getColumnNumber() );
310         }
311
312         // why aren't these part of the runtime info? jvz.
313

314         if ( commandLine.hasOption( CLIManager.BATCH_MODE ) )
315         {
316             settings.setInteractiveMode( false );
317         }
318
319         if ( commandLine.hasOption( CLIManager.SUPPRESS_PLUGIN_REGISTRY ) )
320         {
321             settings.setUsePluginRegistry( false );
322         }
323
324         // Create settings runtime info
325

326         settings.setRuntimeInfo( createRuntimeInfo( commandLine, settings ) );
327
328         return settings;
329     }
330
331     private static RuntimeInfo createRuntimeInfo( CommandLine commandLine, Settings settings )
332     {
333         RuntimeInfo runtimeInfo = new RuntimeInfo( settings );
334
335         if ( commandLine.hasOption( CLIManager.FORCE_PLUGIN_UPDATES ) ||
336             commandLine.hasOption( CLIManager.FORCE_PLUGIN_UPDATES2 ) )
337         {
338             runtimeInfo.setPluginUpdateOverride( Boolean.TRUE );
339         }
340         else if ( commandLine.hasOption( CLIManager.SUPPRESS_PLUGIN_UPDATES ) )
341         {
342             runtimeInfo.setPluginUpdateOverride( Boolean.FALSE );
343         }
344
345         return runtimeInfo;
346     }
347
348
349     private static void showFatalError( String JavaDoc message, Exception JavaDoc e, boolean show )
350     {
351         System.err.println( "FATAL ERROR: " + message );
352         if ( show )
353         {
354             System.err.println( "Error stacktrace:" );
355
356             e.printStackTrace();
357         }
358         else
359         {
360             System.err.println( "For more information, run with the -e flag" );
361         }
362     }
363
364     private static void showError( String JavaDoc message, Exception JavaDoc e, boolean show )
365     {
366         System.err.println( message );
367         if ( show )
368         {
369             System.err.println( "Error stacktrace:" );
370
371             e.printStackTrace();
372         }
373     }
374
375     private static MavenExecutionRequest createRequest( CommandLine commandLine, Settings settings,
376                                                         EventDispatcher eventDispatcher, LoggerManager loggerManager,
377                                                         ProfileManager profileManager, Properties JavaDoc executionProperties,
378                                                         boolean showErrors )
379         throws ComponentLookupException
380     {
381         MavenExecutionRequest request;
382
383         ArtifactRepository localRepository = createLocalRepository( embedder, settings, commandLine );
384
385         File JavaDoc userDir = new File JavaDoc( System.getProperty( "user.dir" ) );
386
387         request = new DefaultMavenExecutionRequest( localRepository, settings, eventDispatcher,
388                                                     commandLine.getArgList(), userDir.getPath(), profileManager,
389                                                     executionProperties, showErrors );
390
391         // TODO [BP]: do we set one per mojo? where to do it?
392
Logger logger = loggerManager.getLoggerForComponent( Mojo.ROLE );
393
394         if ( logger != null )
395         {
396             request.addEventMonitor( new DefaultEventMonitor( logger ) );
397         }
398
399         if ( commandLine.hasOption( CLIManager.NON_RECURSIVE ) )
400         {
401             request.setRecursive( false );
402         }
403
404         if ( commandLine.hasOption( CLIManager.FAIL_FAST ) )
405         {
406             request.setFailureBehavior( ReactorManager.FAIL_FAST );
407         }
408         else if ( commandLine.hasOption( CLIManager.FAIL_AT_END ) )
409         {
410             request.setFailureBehavior( ReactorManager.FAIL_AT_END );
411         }
412         else if ( commandLine.hasOption( CLIManager.FAIL_NEVER ) )
413         {
414             request.setFailureBehavior( ReactorManager.FAIL_NEVER );
415         }
416
417         return request;
418     }
419
420     private static void setProjectFileOptions( CommandLine commandLine, MavenExecutionRequest request )
421     {
422         if ( commandLine.hasOption( CLIManager.REACTOR ) )
423         {
424             request.setReactorActive( true );
425         }
426         else if ( commandLine.hasOption( CLIManager.ALTERNATE_POM_FILE ) )
427         {
428             request.setPomFile( commandLine.getOptionValue( CLIManager.ALTERNATE_POM_FILE ) );
429         }
430     }
431
432     private static Maven createMavenInstance( boolean interactive )
433         throws ComponentLookupException
434     {
435         // TODO [BP]: doing this here as it is CLI specific, though it doesn't feel like the right place (likewise logger).
436
WagonManager wagonManager = (WagonManager) embedder.lookup( WagonManager.ROLE );
437         if ( interactive )
438         {
439             wagonManager.setDownloadMonitor( new ConsoleDownloadMonitor() );
440         }
441         else
442         {
443             wagonManager.setDownloadMonitor( new BatchModeDownloadMonitor() );
444         }
445
446         wagonManager.setInteractive( interactive );
447
448         return (Maven) embedder.lookup( Maven.ROLE );
449     }
450
451     private static ArtifactRepository createLocalRepository( Embedder embedder, Settings settings,
452                                                              CommandLine commandLine )
453         throws ComponentLookupException
454     {
455         // TODO: release
456
// TODO: something in plexus to show all active hooks?
457
ArtifactRepositoryLayout repositoryLayout =
458             (ArtifactRepositoryLayout) embedder.lookup( ArtifactRepositoryLayout.ROLE, "default" );
459
460         ArtifactRepositoryFactory artifactRepositoryFactory =
461             (ArtifactRepositoryFactory) embedder.lookup( ArtifactRepositoryFactory.ROLE );
462
463         String JavaDoc url = settings.getLocalRepository();
464
465         if ( !url.startsWith( "file:" ) )
466         {
467             url = "file://" + url;
468         }
469
470         ArtifactRepository localRepository = new DefaultArtifactRepository( "local", url, repositoryLayout );
471
472         boolean snapshotPolicySet = false;
473
474         if ( commandLine.hasOption( CLIManager.OFFLINE ) )
475         {
476             settings.setOffline( true );
477
478             snapshotPolicySet = true;
479         }
480
481         if ( !snapshotPolicySet && commandLine.hasOption( CLIManager.UPDATE_SNAPSHOTS ) )
482         {
483             artifactRepositoryFactory.setGlobalUpdatePolicy( ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS );
484         }
485
486         if ( commandLine.hasOption( CLIManager.CHECKSUM_FAILURE_POLICY ) )
487         {
488             System.out.println( "+ Enabling strict checksum verification on all artifact downloads." );
489
490             artifactRepositoryFactory.setGlobalChecksumPolicy( ArtifactRepositoryPolicy.CHECKSUM_POLICY_FAIL );
491         }
492         else if ( commandLine.hasOption( CLIManager.CHECKSUM_WARNING_POLICY ) )
493         {
494             System.out.println( "+ Disabling strict checksum verification on all artifact downloads." );
495
496             artifactRepositoryFactory.setGlobalChecksumPolicy( ArtifactRepositoryPolicy.CHECKSUM_POLICY_WARN );
497         }
498
499         return localRepository;
500     }
501
502     private static void showVersion()
503     {
504         InputStream JavaDoc resourceAsStream;
505         try
506         {
507             Properties JavaDoc properties = new Properties JavaDoc();
508             resourceAsStream = MavenCli.class.getClassLoader().getResourceAsStream(
509                 "META-INF/maven/org.apache.maven/maven-core/pom.properties" );
510             properties.load( resourceAsStream );
511             
512             if( properties.getProperty( "builtOn" ) != null )
513             {
514                 System.out.println( "Maven version: " + properties.getProperty( "version", "unknown" )
515                     + " built on " + properties.getProperty( "builtOn" ) );
516             }
517             else
518             {
519                 System.out.println( "Maven version: " + properties.getProperty( "version", "unknown" ) );
520             }
521         }
522         catch ( IOException JavaDoc e )
523         {
524             System.err.println( "Unable determine version from JAR file: " + e.getMessage() );
525         }
526     }
527
528     // ----------------------------------------------------------------------
529
// System properties handling
530
// ----------------------------------------------------------------------
531

532     private static Properties JavaDoc getExecutionProperties( CommandLine commandLine )
533     {
534         Properties JavaDoc executionProperties = new Properties JavaDoc();
535
536         // ----------------------------------------------------------------------
537
// Options that are set on the command line become system properties
538
// and therefore are set in the session properties. System properties
539
// are most dominant.
540
// ----------------------------------------------------------------------
541

542         if ( commandLine.hasOption( CLIManager.SET_SYSTEM_PROPERTY ) )
543         {
544             String JavaDoc[] defStrs = commandLine.getOptionValues( CLIManager.SET_SYSTEM_PROPERTY );
545
546             for ( int i = 0; i < defStrs.length; ++i )
547             {
548                 setCliProperty( defStrs[i], executionProperties );
549             }
550         }
551
552         executionProperties.putAll( System.getProperties() );
553
554         return executionProperties;
555     }
556
557     private static void setCliProperty( String JavaDoc property, Properties JavaDoc executionProperties )
558     {
559         String JavaDoc name;
560
561         String JavaDoc value;
562
563         int i = property.indexOf( "=" );
564
565         if ( i <= 0 )
566         {
567             name = property.trim();
568
569             value = "true";
570         }
571         else
572         {
573             name = property.substring( 0, i ).trim();
574
575             value = property.substring( i + 1 ).trim();
576         }
577
578         executionProperties.setProperty( name, value );
579
580         // ----------------------------------------------------------------------
581
// I'm leaving the setting of system properties here as not to break
582
// the SystemPropertyProfileActivator. This won't harm embedding. jvz.
583
// ----------------------------------------------------------------------
584

585         System.setProperty( name, value );
586     }
587
588     // ----------------------------------------------------------------------
589
// Command line manager
590
// ----------------------------------------------------------------------
591

592     static class CLIManager
593     {
594         public static final char ALTERNATE_POM_FILE = 'f';
595
596         public static final char BATCH_MODE = 'B';
597
598         public static final char SET_SYSTEM_PROPERTY = 'D';
599
600         public static final char OFFLINE = 'o';
601
602         public static final char REACTOR = 'r';
603
604         public static final char DEBUG = 'X';
605
606         public static final char ERRORS = 'e';
607
608         public static final char HELP = 'h';
609
610         public static final char VERSION = 'v';
611
612         private Options options;
613
614         public static final char NON_RECURSIVE = 'N';
615
616         public static final char UPDATE_SNAPSHOTS = 'U';
617
618         public static final char ACTIVATE_PROFILES = 'P';
619
620         public static final String JavaDoc FORCE_PLUGIN_UPDATES = "cpu";
621
622         public static final String JavaDoc FORCE_PLUGIN_UPDATES2 = "up";
623
624         public static final String JavaDoc SUPPRESS_PLUGIN_UPDATES = "npu";
625
626         public static final String JavaDoc SUPPRESS_PLUGIN_REGISTRY = "npr";
627
628         public static final char CHECKSUM_FAILURE_POLICY = 'C';
629
630         public static final char CHECKSUM_WARNING_POLICY = 'c';
631
632         private static final char ALTERNATE_USER_SETTINGS = 's';
633
634         private static final String JavaDoc FAIL_FAST = "ff";
635
636         private static final String JavaDoc FAIL_AT_END = "fae";
637
638         private static final String JavaDoc FAIL_NEVER = "fn";
639
640         public CLIManager()
641         {
642             options = new Options();
643
644             options.addOption( OptionBuilder.withLongOpt( "file" ).hasArg().withDescription(
645                 "Force the use of an alternate POM file." ).create( ALTERNATE_POM_FILE ) );
646
647             options.addOption(
648                 OptionBuilder.withLongOpt( "define" ).hasArg().withDescription( "Define a system property" ).create(
649                     SET_SYSTEM_PROPERTY ) );
650             options.addOption(
651                 OptionBuilder.withLongOpt( "offline" ).withDescription( "Work offline" ).create( OFFLINE ) );
652             options.addOption(
653                 OptionBuilder.withLongOpt( "help" ).withDescription( "Display help information" ).create( HELP ) );
654             options.addOption(
655                 OptionBuilder.withLongOpt( "version" ).withDescription( "Display version information" ).create(
656                     VERSION ) );
657             options.addOption(
658                 OptionBuilder.withLongOpt( "debug" ).withDescription( "Produce execution debug output" ).create(
659                     DEBUG ) );
660             options.addOption(
661                 OptionBuilder.withLongOpt( "errors" ).withDescription( "Produce execution error messages" ).create(
662                     ERRORS ) );
663             options.addOption( OptionBuilder.withLongOpt( "reactor" ).withDescription(
664                 "Execute goals for project found in the reactor" ).create( REACTOR ) );
665             options.addOption( OptionBuilder.withLongOpt( "non-recursive" ).withDescription(
666                 "Do not recurse into sub-projects" ).create( NON_RECURSIVE ) );
667             options.addOption( OptionBuilder.withLongOpt( "update-snapshots" ).withDescription(
668                 "Update all snapshots regardless of repository policies" ).create( UPDATE_SNAPSHOTS ) );
669             options.addOption( OptionBuilder.withLongOpt( "activate-profiles" ).withDescription(
670                 "Comma-delimited list of profiles to activate" ).hasArg().create( ACTIVATE_PROFILES ) );
671
672             options.addOption( OptionBuilder.withLongOpt( "batch-mode" ).withDescription(
673                 "Run in non-interactive (batch) mode" ).create( BATCH_MODE ) );
674
675             options.addOption( OptionBuilder.withLongOpt( "check-plugin-updates" ).withDescription(
676                 "Force upToDate check for any relevant registered plugins" ).create( FORCE_PLUGIN_UPDATES ) );
677             options.addOption( OptionBuilder.withLongOpt( "update-plugins" ).withDescription(
678                 "Synonym for " + FORCE_PLUGIN_UPDATES ).create( FORCE_PLUGIN_UPDATES2 ) );
679             options.addOption( OptionBuilder.withLongOpt( "no-plugin-updates" ).withDescription(
680                 "Suppress upToDate check for any relevant registered plugins" ).create( SUPPRESS_PLUGIN_UPDATES ) );
681
682             options.addOption( OptionBuilder.withLongOpt( "no-plugin-registry" ).withDescription(
683                 "Don't use ~/.m2/plugin-registry.xml for plugin versions" ).create( SUPPRESS_PLUGIN_REGISTRY ) );
684
685             options.addOption( OptionBuilder.withLongOpt( "strict-checksums" ).withDescription(
686                 "Fail the build if checksums don't match" ).create( CHECKSUM_FAILURE_POLICY ) );
687             options.addOption(
688                 OptionBuilder.withLongOpt( "lax-checksums" ).withDescription( "Warn if checksums don't match" ).create(
689                     CHECKSUM_WARNING_POLICY ) );
690
691             options.addOption( OptionBuilder.withLongOpt( "settings" )
692                 .withDescription( "Alternate path for the user settings file" ).hasArg()
693                 .create( ALTERNATE_USER_SETTINGS ) );
694
695             options.addOption( OptionBuilder.withLongOpt( "fail-fast" ).withDescription(
696                 "Stop at first failure in reactorized builds" ).create( FAIL_FAST ) );
697
698             options.addOption( OptionBuilder.withLongOpt( "fail-at-end" ).withDescription(
699                 "Only fail the build afterwards; allow all non-impacted builds to continue" ).create( FAIL_AT_END ) );
700
701             options.addOption( OptionBuilder.withLongOpt( "fail-never" ).withDescription(
702                 "NEVER fail the build, regardless of project result" ).create( FAIL_NEVER ) );
703         }
704
705         public CommandLine parse( String JavaDoc[] args )
706             throws ParseException
707         {
708             // We need to eat any quotes surrounding arguments...
709
String JavaDoc[] cleanArgs = cleanArgs( args );
710             
711             CommandLineParser parser = new GnuParser();
712             return parser.parse( options, cleanArgs );
713         }
714         
715         private String JavaDoc[] cleanArgs( String JavaDoc[] args )
716         {
717             List JavaDoc cleaned = new ArrayList JavaDoc();
718             
719             StringBuffer JavaDoc currentArg = null;
720             
721             for ( int i = 0; i < args.length; i++ )
722             {
723                 String JavaDoc arg = args[i];
724                 
725 // System.out.println( "Processing raw arg: " + arg );
726

727                 boolean addedToBuffer = false;
728                 
729                 if ( arg.startsWith( "\"" ) )
730                 {
731                     // if we're in the process of building up another arg, push it and start over.
732
// this is for the case: "-Dfoo=bar "-Dfoo2=bar two" (note the first unterminated quote)
733
if ( currentArg != null )
734                     {
735 // System.out.println( "Flushing last arg buffer: \'" + currentArg + "\' to cleaned list." );
736
cleaned.add( currentArg.toString() );
737                     }
738                     
739                     // start building an argument here.
740
currentArg = new StringBuffer JavaDoc( arg.substring( 1 ) );
741                     addedToBuffer = true;
742                 }
743                 
744                 // this has to be a separate "if" statement, to capture the case of: "-Dfoo=bar"
745
if ( arg.endsWith( "\"" ) )
746                 {
747                     String JavaDoc cleanArgPart = arg.substring( 0, arg.length() - 1 );
748                     
749                     // if we're building an argument, keep doing so.
750
if ( currentArg != null )
751                     {
752                         // if this is the case of "-Dfoo=bar", then we need to adjust the buffer.
753
if ( addedToBuffer )
754                         {
755 // System.out.println( "Adjusting argument already appended to the arg buffer." );
756
currentArg.setLength( currentArg.length() - 1 );
757                         }
758                         // otherwise, we trim the trailing " and append to the buffer.
759
else
760                         {
761 // System.out.println( "Appending arg part: \'" + cleanArgPart + "\' with preceding space to arg buffer." );
762
// TODO: introducing a space here...not sure what else to do but collapse whitespace
763
currentArg.append( ' ' ).append( cleanArgPart );
764                         }
765                         
766 // System.out.println( "Flushing completed arg buffer: \'" + currentArg + "\' to cleaned list." );
767

768                         // we're done with this argument, so add it.
769
cleaned.add( currentArg.toString() );
770                     }
771                     else
772                     {
773 // System.out.println( "appending cleaned arg: \'" + cleanArgPart + "\' directly to cleaned list." );
774
// this is a simple argument...just add it.
775
cleaned.add( cleanArgPart );
776                     }
777                     
778 // System.out.println( "Clearing arg buffer." );
779
// the currentArg MUST be finished when this completes.
780
currentArg = null;
781                     continue;
782                 }
783                 
784                 // if we haven't added this arg to the buffer, and we ARE building an argument
785
// buffer, then append it with a preceding space...again, not sure what else to
786
// do other than collapse whitespace.
787
// NOTE: The case of a trailing quote is handled by nullifying the arg buffer.
788
if ( !addedToBuffer )
789                 {
790                     // append to the argument we're building, collapsing whitespace to a single space.
791
if ( currentArg != null )
792                     {
793 // System.out.println( "Append unquoted arg part: \'" + arg + "\' to arg buffer." );
794
currentArg.append( ' ' ).append( arg );
795                     }
796                     // this is a loner, just add it directly.
797
else
798                     {
799 // System.out.println( "Append unquoted arg part: \'" + arg + "\' directly to cleaned list." );
800
cleaned.add( arg );
801                     }
802                 }
803             }
804             
805             // clean up.
806
if ( currentArg != null )
807             {
808 // System.out.println( "Adding unterminated arg buffer: \'" + currentArg + "\' to cleaned list." );
809
cleaned.add( currentArg.toString() );
810             }
811             
812             int cleanedSz = cleaned.size();
813             String JavaDoc[] cleanArgs = null;
814             
815             if ( cleanedSz == 0 )
816             {
817                 // if we didn't have any arguments to clean, simply pass the original array through
818
cleanArgs = args;
819             }
820             else
821             {
822 // System.out.println( "Cleaned argument list:\n" + cleaned );
823
cleanArgs = (String JavaDoc[]) cleaned.toArray( new String JavaDoc[cleanedSz] );
824             }
825             
826             return cleanArgs;
827         }
828
829         public void displayHelp()
830         {
831             System.out.println();
832
833             HelpFormatter formatter = new HelpFormatter();
834             formatter.printHelp( "mvn [options] [<goal(s)>] [<phase(s)>]", "\nOptions:", options, "\n" );
835         }
836     }
837 }
838
Popular Tags