Save This Page
Home » maven-2.0.9-src » org.apache » maven » cli » [javadoc | source]
    1   package org.apache.maven.cli;
    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 org.apache.commons.cli.CommandLine;
   23   import org.apache.commons.cli.CommandLineParser;
   24   import org.apache.commons.cli.GnuParser;
   25   import org.apache.commons.cli.HelpFormatter;
   26   import org.apache.commons.cli.OptionBuilder;
   27   import org.apache.commons.cli.Options;
   28   import org.apache.commons.cli.ParseException;
   29   import org.apache.maven.Maven;
   30   import org.apache.maven.SettingsConfigurationException;
   31   import org.apache.maven.artifact.manager.WagonManager;
   32   import org.apache.maven.artifact.repository.ArtifactRepository;
   33   import org.apache.maven.artifact.repository.ArtifactRepositoryFactory;
   34   import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
   35   import org.apache.maven.artifact.repository.DefaultArtifactRepository;
   36   import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
   37   import org.apache.maven.execution.DefaultMavenExecutionRequest;
   38   import org.apache.maven.execution.MavenExecutionRequest;
   39   import org.apache.maven.execution.ReactorManager;
   40   import org.apache.maven.monitor.event.DefaultEventDispatcher;
   41   import org.apache.maven.monitor.event.DefaultEventMonitor;
   42   import org.apache.maven.monitor.event.EventDispatcher;
   43   import org.apache.maven.plugin.Mojo;
   44   import org.apache.maven.profiles.DefaultProfileManager;
   45   import org.apache.maven.profiles.ProfileManager;
   46   import org.apache.maven.reactor.MavenExecutionException;
   47   import org.apache.maven.settings.MavenSettingsBuilder;
   48   import org.apache.maven.settings.RuntimeInfo;
   49   import org.apache.maven.settings.Settings;
   50   import org.codehaus.classworlds.ClassWorld;
   51   import org.codehaus.plexus.PlexusContainerException;
   52   import org.codehaus.plexus.component.repository.exception.ComponentLifecycleException;
   53   import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
   54   import org.codehaus.plexus.embed.Embedder;
   55   import org.codehaus.plexus.logging.Logger;
   56   import org.codehaus.plexus.logging.LoggerManager;
   57   import org.codehaus.plexus.util.Os;
   58   import org.codehaus.plexus.util.cli.CommandLineUtils;
   59   import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
   60   
   61   import java.io.File;
   62   import java.io.IOException;
   63   import java.io.InputStream;
   64   import java.util.ArrayList;
   65   import java.util.Iterator;
   66   import java.util.List;
   67   import java.util.Properties;
   68   import java.util.StringTokenizer;
   69   import java.util.Map.Entry;
   70   
   71   /**
   72    * @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
   73    * @version $Id: MavenCli.java 642024 2008-03-27 23:30:59Z jdcasey $
   74    * @noinspection UseOfSystemOutOrSystemErr,ACCESS_STATIC_VIA_INSTANCE
   75    */
   76   public class MavenCli
   77   {
   78       /** @deprecated use {@link Os#OS_NAME} */
   79       public static final String OS_NAME = Os.OS_NAME;
   80   
   81       /** @deprecated use {@link Os#OS_ARCH} */
   82       public static final String OS_ARCH = Os.OS_ARCH;
   83   
   84       /** @deprecated use {@link Os#OS_VERSION} */
   85       public static final String OS_VERSION = Os.OS_VERSION;
   86   
   87       private static Embedder embedder;
   88   
   89       /**
   90        * @noinspection ConfusingMainMethod
   91        */
   92       public static int main( String[] args, ClassWorld classWorld )
   93       {
   94           // ----------------------------------------------------------------------
   95           // Setup the command line parser
   96           // ----------------------------------------------------------------------
   97   
   98           CLIManager cliManager = new CLIManager();
   99   
  100           CommandLine commandLine;
  101           try
  102           {
  103               commandLine = cliManager.parse( args );
  104           }
  105           catch ( ParseException e )
  106           {
  107               System.err.println( "Unable to parse command line options: " + e.getMessage() );
  108               cliManager.displayHelp();
  109               return 1;
  110           }
  111   
  112           // TODO: maybe classworlds could handle this requirement...
  113           if ( "1.4".compareTo( System.getProperty( "java.specification.version" ) ) > 0 )
  114           {
  115               System.err.println( "Sorry, but JDK 1.4 or above is required to execute Maven. You appear to be using "
  116                   + "Java:" );
  117               System.err.println( "java version \"" + System.getProperty( "java.version", "<unknown java version>" )
  118                   + "\"" );
  119               System.err.println( System.getProperty( "java.runtime.name", "<unknown runtime name>" ) + " (build "
  120                   + System.getProperty( "java.runtime.version", "<unknown runtime version>" ) + ")" );
  121               System.err.println( System.getProperty( "java.vm.name", "<unknown vm name>" ) + " (build "
  122                   + System.getProperty( "java.vm.version", "<unknown vm version>" ) + ", "
  123                   + System.getProperty( "java.vm.info", "<unknown vm info>" ) + ")" );
  124   
  125               return 1;
  126           }
  127   
  128           boolean debug = commandLine.hasOption( CLIManager.DEBUG );
  129   
  130           boolean showErrors = debug || commandLine.hasOption( CLIManager.ERRORS );
  131   
  132           if ( showErrors )
  133           {
  134               System.out.println( "+ Error stacktraces are turned on." );
  135           }
  136   
  137           // ----------------------------------------------------------------------
  138           // Process particular command line options
  139           // ----------------------------------------------------------------------
  140   
  141           if ( commandLine.hasOption( CLIManager.HELP ) )
  142           {
  143               cliManager.displayHelp();
  144               return 0;
  145           }
  146   
  147           if ( commandLine.hasOption( CLIManager.VERSION ) )
  148           {
  149               showVersion();
  150   
  151               return 0;
  152           }
  153           else if ( debug )
  154           {
  155               showVersion();
  156           }
  157   
  158           EventDispatcher eventDispatcher = new DefaultEventDispatcher();
  159   
  160           // ----------------------------------------------------------------------
  161           // Now that we have everything that we need we will fire up plexus and
  162           // bring the maven component to life for use.
  163           // ----------------------------------------------------------------------
  164   
  165           embedder = new Embedder();
  166   
  167           try
  168           {
  169               embedder.start( classWorld );
  170           }
  171           catch ( PlexusContainerException e )
  172           {
  173               showFatalError( "Unable to start the embedded plexus container", e, showErrors );
  174   
  175               return 1;
  176           }
  177   
  178           // ----------------------------------------------------------------------
  179           // The execution properties need to be created before the settings
  180           // are constructed.
  181           // ----------------------------------------------------------------------
  182   
  183           Properties executionProperties = new Properties();
  184           Properties userProperties = new Properties();
  185           populateProperties( commandLine, executionProperties, userProperties );
  186   
  187           Settings settings;
  188   
  189           try
  190           {
  191               settings = buildSettings( commandLine );
  192           }
  193           catch ( SettingsConfigurationException e )
  194           {
  195               showError( "Error reading settings.xml: " + e.getMessage(), e, showErrors );
  196   
  197               return 1;
  198           }
  199           catch ( ComponentLookupException e )
  200           {
  201               showFatalError( "Unable to read settings.xml", e, showErrors );
  202   
  203               return 1;
  204           }
  205   
  206           Maven maven = null;
  207   
  208           MavenExecutionRequest request = null;
  209   
  210           LoggerManager loggerManager = null;
  211   
  212           try
  213           {
  214               // logger must be created first
  215               loggerManager = (LoggerManager) embedder.lookup( LoggerManager.ROLE );
  216   
  217               if ( debug )
  218               {
  219                   loggerManager.setThreshold( Logger.LEVEL_DEBUG );
  220               }
  221               else if ( commandLine.hasOption( CLIManager.QUIET ) )
  222               {
  223                   // TODO: we need to do some more work here. Some plugins use sys out or log errors at info level.
  224                   // Ideally, we could use Warn across the board
  225                   loggerManager.setThreshold( Logger.LEVEL_ERROR );
  226                   // TODO:Additionally, we can't change the mojo level because the component key includes the version and it isn't known ahead of time. This seems worth changing.
  227               }
  228   
  229               ProfileManager profileManager = new DefaultProfileManager( embedder.getContainer(), executionProperties );
  230   
  231               if ( commandLine.hasOption( CLIManager.ACTIVATE_PROFILES ) )
  232               {
  233                   String profilesLine = commandLine.getOptionValue( CLIManager.ACTIVATE_PROFILES );
  234   
  235                   StringTokenizer profileTokens = new StringTokenizer( profilesLine, "," );
  236   
  237                   while ( profileTokens.hasMoreTokens() )
  238                   {
  239                       String profileAction = profileTokens.nextToken().trim();
  240   
  241                       if ( profileAction.startsWith( "-" ) )
  242                       {
  243                           profileManager.explicitlyDeactivate( profileAction.substring( 1 ) );
  244                       }
  245                       else if ( profileAction.startsWith( "+" ) )
  246                       {
  247                           profileManager.explicitlyActivate( profileAction.substring( 1 ) );
  248                       }
  249                       else
  250                       {
  251                           // TODO: deprecate this eventually!
  252                           profileManager.explicitlyActivate( profileAction );
  253                       }
  254                   }
  255               }
  256   
  257               request = createRequest( commandLine, settings, eventDispatcher, loggerManager, profileManager,
  258                                        executionProperties, userProperties, showErrors );
  259   
  260               setProjectFileOptions( commandLine, request );
  261   
  262               maven = createMavenInstance( settings.isInteractiveMode() );
  263           }
  264           catch ( ComponentLookupException e )
  265           {
  266               showFatalError( "Unable to configure the Maven application", e, showErrors );
  267   
  268               return 1;
  269           }
  270           finally
  271           {
  272               if ( loggerManager != null )
  273               {
  274                   try
  275                   {
  276                       embedder.release( loggerManager );
  277                   }
  278                   catch ( ComponentLifecycleException e )
  279                   {
  280                       showFatalError( "Error releasing logging manager", e, showErrors );
  281                   }
  282               }
  283           }
  284   
  285           try
  286           {
  287               maven.execute( request );
  288           }
  289           catch ( MavenExecutionException e )
  290           {
  291               return 1;
  292           }
  293   
  294           return 0;
  295       }
  296   
  297       private static Settings buildSettings( CommandLine commandLine )
  298           throws ComponentLookupException, SettingsConfigurationException
  299       {
  300           String userSettingsPath = null;
  301   
  302           if ( commandLine.hasOption( CLIManager.ALTERNATE_USER_SETTINGS ) )
  303           {
  304               userSettingsPath = commandLine.getOptionValue( CLIManager.ALTERNATE_USER_SETTINGS );
  305           }
  306   
  307           Settings settings = null;
  308   
  309           MavenSettingsBuilder settingsBuilder = (MavenSettingsBuilder) embedder.lookup( MavenSettingsBuilder.ROLE );
  310   
  311           try
  312           {
  313               if ( userSettingsPath != null )
  314               {
  315                   File userSettingsFile = new File( userSettingsPath );
  316   
  317                   if ( userSettingsFile.exists() && !userSettingsFile.isDirectory() )
  318                   {
  319                       settings = settingsBuilder.buildSettings( userSettingsFile );
  320                   }
  321                   else
  322                   {
  323                       System.out.println( "WARNING: Alternate user settings file: " + userSettingsPath +
  324                           " is invalid. Using default path." );
  325                   }
  326               }
  327   
  328               if ( settings == null )
  329               {
  330                   settings = settingsBuilder.buildSettings();
  331               }
  332           }
  333           catch ( IOException e )
  334           {
  335               throw new SettingsConfigurationException( "Error reading settings file", e );
  336           }
  337           catch ( XmlPullParserException e )
  338           {
  339               throw new SettingsConfigurationException( e.getMessage(), e.getDetail(), e.getLineNumber(),
  340                                                         e.getColumnNumber() );
  341           }
  342   
  343           // why aren't these part of the runtime info? jvz.
  344   
  345           if ( commandLine.hasOption( CLIManager.BATCH_MODE ) )
  346           {
  347               settings.setInteractiveMode( false );
  348           }
  349   
  350           if ( commandLine.hasOption( CLIManager.SUPPRESS_PLUGIN_REGISTRY ) )
  351           {
  352               settings.setUsePluginRegistry( false );
  353           }
  354   
  355           // Create settings runtime info
  356   
  357           settings.setRuntimeInfo( createRuntimeInfo( commandLine, settings ) );
  358   
  359           return settings;
  360       }
  361   
  362       private static RuntimeInfo createRuntimeInfo( CommandLine commandLine, Settings settings )
  363       {
  364           RuntimeInfo runtimeInfo = new RuntimeInfo( settings );
  365   
  366           if ( commandLine.hasOption( CLIManager.FORCE_PLUGIN_UPDATES ) ||
  367               commandLine.hasOption( CLIManager.FORCE_PLUGIN_UPDATES2 ) )
  368           {
  369               runtimeInfo.setPluginUpdateOverride( Boolean.TRUE );
  370           }
  371           else if ( commandLine.hasOption( CLIManager.SUPPRESS_PLUGIN_UPDATES ) )
  372           {
  373               runtimeInfo.setPluginUpdateOverride( Boolean.FALSE );
  374           }
  375   
  376           return runtimeInfo;
  377       }
  378   
  379   
  380       private static void showFatalError( String message, Exception e, boolean show )
  381       {
  382           System.err.println( "FATAL ERROR: " + message );
  383           if ( show )
  384           {
  385               System.err.println( "Error stacktrace:" );
  386   
  387               e.printStackTrace();
  388           }
  389           else
  390           {
  391               System.err.println( "For more information, run with the -e flag" );
  392           }
  393       }
  394   
  395       private static void showError( String message, Exception e, boolean show )
  396       {
  397           System.err.println( message );
  398           if ( show )
  399           {
  400               System.err.println( "Error stacktrace:" );
  401   
  402               e.printStackTrace();
  403           }
  404       }
  405   
  406       private static MavenExecutionRequest createRequest( CommandLine commandLine, Settings settings,
  407                                                           EventDispatcher eventDispatcher, LoggerManager loggerManager,
  408                                                           ProfileManager profileManager, Properties executionProperties,
  409                                                           Properties userProperties, boolean showErrors )
  410           throws ComponentLookupException
  411       {
  412           MavenExecutionRequest request;
  413   
  414           ArtifactRepository localRepository = createLocalRepository( embedder, settings, commandLine );
  415   
  416           File userDir = new File( System.getProperty( "user.dir" ) );
  417   
  418           request = new DefaultMavenExecutionRequest( localRepository, settings, eventDispatcher,
  419                                                       commandLine.getArgList(), userDir.getPath(), profileManager,
  420                                                       executionProperties, userProperties, showErrors );
  421   
  422           // TODO [BP]: do we set one per mojo? where to do it?
  423           Logger logger = loggerManager.getLoggerForComponent( Mojo.ROLE );
  424   
  425           if ( logger != null )
  426           {
  427               request.addEventMonitor( new DefaultEventMonitor( logger ) );
  428           }
  429   
  430           if ( commandLine.hasOption( CLIManager.NON_RECURSIVE ) )
  431           {
  432               request.setRecursive( false );
  433           }
  434   
  435           if ( commandLine.hasOption( CLIManager.FAIL_FAST ) )
  436           {
  437               request.setFailureBehavior( ReactorManager.FAIL_FAST );
  438           }
  439           else if ( commandLine.hasOption( CLIManager.FAIL_AT_END ) )
  440           {
  441               request.setFailureBehavior( ReactorManager.FAIL_AT_END );
  442           }
  443           else if ( commandLine.hasOption( CLIManager.FAIL_NEVER ) )
  444           {
  445               request.setFailureBehavior( ReactorManager.FAIL_NEVER );
  446           }
  447   
  448           return request;
  449       }
  450   
  451       private static void setProjectFileOptions( CommandLine commandLine, MavenExecutionRequest request )
  452       {
  453           if ( commandLine.hasOption( CLIManager.REACTOR ) )
  454           {
  455               request.setReactorActive( true );
  456           }
  457           else if ( commandLine.hasOption( CLIManager.ALTERNATE_POM_FILE ) )
  458           {
  459               request.setPomFile( commandLine.getOptionValue( CLIManager.ALTERNATE_POM_FILE ) );
  460           }
  461       }
  462   
  463       private static Maven createMavenInstance( boolean interactive )
  464           throws ComponentLookupException
  465       {
  466           // TODO [BP]: doing this here as it is CLI specific, though it doesn't feel like the right place (likewise logger).
  467           WagonManager wagonManager = (WagonManager) embedder.lookup( WagonManager.ROLE );
  468           if ( interactive )
  469           {
  470               wagonManager.setDownloadMonitor( new ConsoleDownloadMonitor() );
  471           }
  472           else
  473           {
  474               wagonManager.setDownloadMonitor( new BatchModeDownloadMonitor() );
  475           }
  476   
  477           wagonManager.setInteractive( interactive );
  478   
  479           return (Maven) embedder.lookup( Maven.ROLE );
  480       }
  481   
  482       private static ArtifactRepository createLocalRepository( Embedder embedder, Settings settings,
  483                                                                CommandLine commandLine )
  484           throws ComponentLookupException
  485       {
  486           // TODO: release
  487           // TODO: something in plexus to show all active hooks?
  488           ArtifactRepositoryLayout repositoryLayout =
  489               (ArtifactRepositoryLayout) embedder.lookup( ArtifactRepositoryLayout.ROLE, "default" );
  490   
  491           ArtifactRepositoryFactory artifactRepositoryFactory =
  492               (ArtifactRepositoryFactory) embedder.lookup( ArtifactRepositoryFactory.ROLE );
  493   
  494           String url = settings.getLocalRepository();
  495   
  496           if ( !url.startsWith( "file:" ) )
  497           {
  498               url = "file://" + url;
  499           }
  500   
  501           ArtifactRepository localRepository = new DefaultArtifactRepository( "local", url, repositoryLayout );
  502   
  503           boolean snapshotPolicySet = false;
  504   
  505           if ( commandLine.hasOption( CLIManager.OFFLINE ) )
  506           {
  507               settings.setOffline( true );
  508   
  509               snapshotPolicySet = true;
  510           }
  511   
  512           if ( !snapshotPolicySet && commandLine.hasOption( CLIManager.UPDATE_SNAPSHOTS ) )
  513           {
  514               artifactRepositoryFactory.setGlobalUpdatePolicy( ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS );
  515           }
  516   
  517           if ( commandLine.hasOption( CLIManager.CHECKSUM_FAILURE_POLICY ) )
  518           {
  519               System.out.println( "+ Enabling strict checksum verification on all artifact downloads." );
  520   
  521               artifactRepositoryFactory.setGlobalChecksumPolicy( ArtifactRepositoryPolicy.CHECKSUM_POLICY_FAIL );
  522           }
  523           else if ( commandLine.hasOption( CLIManager.CHECKSUM_WARNING_POLICY ) )
  524           {
  525               System.out.println( "+ Disabling strict checksum verification on all artifact downloads." );
  526   
  527               artifactRepositoryFactory.setGlobalChecksumPolicy( ArtifactRepositoryPolicy.CHECKSUM_POLICY_WARN );
  528           }
  529   
  530           return localRepository;
  531       }
  532   
  533       private static void showVersion()
  534       {
  535           InputStream resourceAsStream;
  536           try
  537           {
  538               Properties properties = new Properties();
  539               resourceAsStream = MavenCli.class.getClassLoader().getResourceAsStream(
  540                   "META-INF/maven/org.apache.maven/maven-core/pom.properties" );
  541   
  542               if ( resourceAsStream != null )
  543               {
  544                   properties.load( resourceAsStream );
  545   
  546                   if( properties.getProperty( "builtOn" ) != null )
  547                   {
  548                       System.out.println( "Maven version: " + properties.getProperty( "version", "unknown" )
  549                           + " built on " + properties.getProperty( "builtOn" ) );
  550                   }
  551                   else
  552                   {
  553                       System.out.println( "Maven version: " + properties.getProperty( "version", "unknown" ) );
  554                   }
  555               }
  556               else
  557               {
  558                   System.out.println( "Maven version: unknown" );
  559               }
  560   
  561               System.out.println( "Java version: " + System.getProperty( "java.version", "<unknown java version>" ) );
  562   
  563               System.out.println( "OS name: \"" + Os.OS_NAME + "\" version: \"" + Os.OS_VERSION +
  564                                   "\" arch: \"" + Os.OS_ARCH + "\" Family: \"" + Os.OS_FAMILY + "\"" );
  565   
  566           }
  567           catch ( IOException e )
  568           {
  569               System.err.println( "Unable determine version from JAR file: " + e.getMessage() );
  570           }
  571       }
  572   
  573       // ----------------------------------------------------------------------
  574       // System properties handling
  575       // ----------------------------------------------------------------------
  576   
  577       static void populateProperties( CommandLine commandLine, Properties executionProperties, Properties userProperties )
  578       {
  579           // add the env vars to the property set, with the "env." prefix
  580           // XXX support for env vars should probably be removed from the ModelInterpolator
  581           try
  582           {
  583               Properties envVars = CommandLineUtils.getSystemEnvVars();
  584               Iterator i = envVars.entrySet().iterator();
  585               while ( i.hasNext() )
  586               {
  587                   Entry e = (Entry) i.next();
  588                   executionProperties.setProperty( "env." + e.getKey().toString(), e.getValue().toString() );
  589               }
  590           }
  591           catch ( IOException e )
  592           {
  593               System.err.println( "Error getting environment vars for profile activation: " + e );
  594           }
  595   
  596           // ----------------------------------------------------------------------
  597           // Options that are set on the command line become system properties
  598           // and therefore are set in the session properties. System properties
  599           // are most dominant.
  600           // ----------------------------------------------------------------------
  601   
  602           if ( commandLine.hasOption( CLIManager.SET_SYSTEM_PROPERTY ) )
  603           {
  604               String[] defStrs = commandLine.getOptionValues( CLIManager.SET_SYSTEM_PROPERTY );
  605   
  606               if ( defStrs != null )
  607               {
  608                   for ( int i = 0; i < defStrs.length; ++i )
  609                   {
  610                       setCliProperty( defStrs[i], userProperties );
  611                   }
  612               }
  613   
  614               executionProperties.putAll( userProperties );
  615           }
  616   
  617           executionProperties.putAll( System.getProperties() );
  618       }
  619   
  620       private static void setCliProperty( String property, Properties requestProperties )
  621       {
  622           String name;
  623   
  624           String value;
  625   
  626           int i = property.indexOf( "=" );
  627   
  628           if ( i <= 0 )
  629           {
  630               name = property.trim();
  631   
  632               value = "true";
  633           }
  634           else
  635           {
  636               name = property.substring( 0, i ).trim();
  637   
  638               value = property.substring( i + 1 ).trim();
  639           }
  640   
  641           requestProperties.setProperty( name, value );
  642   
  643           // ----------------------------------------------------------------------
  644           // I'm leaving the setting of system properties here as not to break
  645           // the SystemPropertyProfileActivator. This won't harm embedding. jvz.
  646           // ----------------------------------------------------------------------
  647   
  648           System.setProperty( name, value );
  649       }
  650   
  651       // ----------------------------------------------------------------------
  652       // Command line manager
  653       // ----------------------------------------------------------------------
  654   
  655       static class CLIManager
  656       {
  657           public static final char ALTERNATE_POM_FILE = 'f';
  658   
  659           public static final char BATCH_MODE = 'B';
  660   
  661           public static final char SET_SYSTEM_PROPERTY = 'D';
  662   
  663           public static final char OFFLINE = 'o';
  664   
  665           public static final char REACTOR = 'r';
  666   
  667           public static final char QUIET = 'q';
  668   
  669           public static final char DEBUG = 'X';
  670   
  671           public static final char ERRORS = 'e';
  672   
  673           public static final char HELP = 'h';
  674   
  675           public static final char VERSION = 'v';
  676   
  677           private Options options;
  678   
  679           public static final char NON_RECURSIVE = 'N';
  680   
  681           public static final char UPDATE_SNAPSHOTS = 'U';
  682   
  683           public static final char ACTIVATE_PROFILES = 'P';
  684   
  685           public static final String FORCE_PLUGIN_UPDATES = "cpu";
  686   
  687           public static final String FORCE_PLUGIN_UPDATES2 = "up";
  688   
  689           public static final String SUPPRESS_PLUGIN_UPDATES = "npu";
  690   
  691           public static final String SUPPRESS_PLUGIN_REGISTRY = "npr";
  692   
  693           public static final char CHECKSUM_FAILURE_POLICY = 'C';
  694   
  695           public static final char CHECKSUM_WARNING_POLICY = 'c';
  696   
  697           private static final char ALTERNATE_USER_SETTINGS = 's';
  698   
  699           private static final String FAIL_FAST = "ff";
  700   
  701           private static final String FAIL_AT_END = "fae";
  702   
  703           private static final String FAIL_NEVER = "fn";
  704   
  705           public CLIManager()
  706           {
  707               options = new Options();
  708   
  709               options.addOption( OptionBuilder.withLongOpt( "file" ).hasArg().withDescription(
  710                   "Force the use of an alternate POM file." ).create( ALTERNATE_POM_FILE ) );
  711   
  712               options.addOption(
  713                   OptionBuilder.withLongOpt( "define" ).hasArg().withDescription( "Define a system property" ).create(
  714                       SET_SYSTEM_PROPERTY ) );
  715               options.addOption(
  716                   OptionBuilder.withLongOpt( "offline" ).withDescription( "Work offline" ).create( OFFLINE ) );
  717               options.addOption(
  718                   OptionBuilder.withLongOpt( "help" ).withDescription( "Display help information" ).create( HELP ) );
  719               options.addOption(
  720                   OptionBuilder.withLongOpt( "version" ).withDescription( "Display version information" ).create(
  721                       VERSION ) );
  722               options.addOption(
  723                   OptionBuilder.withLongOpt( "quiet" ).withDescription( "Quiet output - only show errors" ).create(
  724                       QUIET ) );
  725               options.addOption(
  726                   OptionBuilder.withLongOpt( "debug" ).withDescription( "Produce execution debug output" ).create(
  727                       DEBUG ) );
  728               options.addOption(
  729                   OptionBuilder.withLongOpt( "errors" ).withDescription( "Produce execution error messages" ).create(
  730                       ERRORS ) );
  731               options.addOption( OptionBuilder.withLongOpt( "reactor" ).withDescription(
  732                   "Execute goals for project found in the reactor" ).create( REACTOR ) );
  733               options.addOption( OptionBuilder.withLongOpt( "non-recursive" ).withDescription(
  734                   "Do not recurse into sub-projects" ).create( NON_RECURSIVE ) );
  735               options.addOption( OptionBuilder.withLongOpt( "update-snapshots" ).withDescription(
  736                   "Forces a check for updated releases and snapshots on remote repositories" ).create( UPDATE_SNAPSHOTS ) );
  737               options.addOption( OptionBuilder.withLongOpt( "activate-profiles" ).withDescription(
  738                   "Comma-delimited list of profiles to activate" ).hasArg().create( ACTIVATE_PROFILES ) );
  739   
  740               options.addOption( OptionBuilder.withLongOpt( "batch-mode" ).withDescription(
  741                   "Run in non-interactive (batch) mode" ).create( BATCH_MODE ) );
  742   
  743               options.addOption( OptionBuilder.withLongOpt( "check-plugin-updates" ).withDescription(
  744                   "Force upToDate check for any relevant registered plugins" ).create( FORCE_PLUGIN_UPDATES ) );
  745               options.addOption( OptionBuilder.withLongOpt( "update-plugins" ).withDescription(
  746                   "Synonym for " + FORCE_PLUGIN_UPDATES ).create( FORCE_PLUGIN_UPDATES2 ) );
  747               options.addOption( OptionBuilder.withLongOpt( "no-plugin-updates" ).withDescription(
  748                   "Suppress upToDate check for any relevant registered plugins" ).create( SUPPRESS_PLUGIN_UPDATES ) );
  749   
  750               options.addOption( OptionBuilder.withLongOpt( "no-plugin-registry" ).withDescription(
  751                   "Don't use ~/.m2/plugin-registry.xml for plugin versions" ).create( SUPPRESS_PLUGIN_REGISTRY ) );
  752   
  753               options.addOption( OptionBuilder.withLongOpt( "strict-checksums" ).withDescription(
  754                   "Fail the build if checksums don't match" ).create( CHECKSUM_FAILURE_POLICY ) );
  755               options.addOption(
  756                   OptionBuilder.withLongOpt( "lax-checksums" ).withDescription( "Warn if checksums don't match" ).create(
  757                       CHECKSUM_WARNING_POLICY ) );
  758   
  759               options.addOption( OptionBuilder.withLongOpt( "settings" )
  760                   .withDescription( "Alternate path for the user settings file" ).hasArg()
  761                   .create( ALTERNATE_USER_SETTINGS ) );
  762   
  763               options.addOption( OptionBuilder.withLongOpt( "fail-fast" ).withDescription(
  764                   "Stop at first failure in reactorized builds" ).create( FAIL_FAST ) );
  765   
  766               options.addOption( OptionBuilder.withLongOpt( "fail-at-end" ).withDescription(
  767                   "Only fail the build afterwards; allow all non-impacted builds to continue" ).create( FAIL_AT_END ) );
  768   
  769               options.addOption( OptionBuilder.withLongOpt( "fail-never" ).withDescription(
  770                   "NEVER fail the build, regardless of project result" ).create( FAIL_NEVER ) );
  771           }
  772   
  773           public CommandLine parse( String[] args )
  774               throws ParseException
  775           {
  776               // We need to eat any quotes surrounding arguments...
  777               String[] cleanArgs = cleanArgs( args );
  778   
  779               CommandLineParser parser = new GnuParser();
  780               return parser.parse( options, cleanArgs );
  781           }
  782   
  783           private String[] cleanArgs( String[] args )
  784           {
  785               List cleaned = new ArrayList();
  786   
  787               StringBuffer currentArg = null;
  788   
  789               for ( int i = 0; i < args.length; i++ )
  790               {
  791                   String arg = args[i];
  792   
  793   //                System.out.println( "Processing raw arg: " + arg );
  794   
  795                   boolean addedToBuffer = false;
  796   
  797                   if ( arg.startsWith( "\"" ) )
  798                   {
  799                       // if we're in the process of building up another arg, push it and start over.
  800                       // this is for the case: "-Dfoo=bar "-Dfoo2=bar two" (note the first unterminated quote)
  801                       if ( currentArg != null )
  802                       {
  803   //                        System.out.println( "Flushing last arg buffer: \'" + currentArg + "\' to cleaned list." );
  804                           cleaned.add( currentArg.toString() );
  805                       }
  806   
  807                       // start building an argument here.
  808                       currentArg = new StringBuffer( arg.substring( 1 ) );
  809                       addedToBuffer = true;
  810                   }
  811   
  812                   // this has to be a separate "if" statement, to capture the case of: "-Dfoo=bar"
  813                   if ( arg.endsWith( "\"" ) )
  814                   {
  815                       String cleanArgPart = arg.substring( 0, arg.length() - 1 );
  816   
  817                       // if we're building an argument, keep doing so.
  818                       if ( currentArg != null )
  819                       {
  820                           // if this is the case of "-Dfoo=bar", then we need to adjust the buffer.
  821                           if ( addedToBuffer )
  822                           {
  823   //                            System.out.println( "Adjusting argument already appended to the arg buffer." );
  824                               currentArg.setLength( currentArg.length() - 1 );
  825                           }
  826                           // otherwise, we trim the trailing " and append to the buffer.
  827                           else
  828                           {
  829   //                            System.out.println( "Appending arg part: \'" + cleanArgPart + "\' with preceding space to arg buffer." );
  830                               // TODO: introducing a space here...not sure what else to do but collapse whitespace
  831                               currentArg.append( ' ' ).append( cleanArgPart );
  832                           }
  833   
  834   //                        System.out.println( "Flushing completed arg buffer: \'" + currentArg + "\' to cleaned list." );
  835   
  836                           // we're done with this argument, so add it.
  837                           cleaned.add( currentArg.toString() );
  838                       }
  839                       else
  840                       {
  841   //                        System.out.println( "appending cleaned arg: \'" + cleanArgPart + "\' directly to cleaned list." );
  842                           // this is a simple argument...just add it.
  843                           cleaned.add( cleanArgPart );
  844                       }
  845   
  846   //                    System.out.println( "Clearing arg buffer." );
  847                       // the currentArg MUST be finished when this completes.
  848                       currentArg = null;
  849                       continue;
  850                   }
  851   
  852                   // if we haven't added this arg to the buffer, and we ARE building an argument
  853                   // buffer, then append it with a preceding space...again, not sure what else to
  854                   // do other than collapse whitespace.
  855                   // NOTE: The case of a trailing quote is handled by nullifying the arg buffer.
  856                   if ( !addedToBuffer )
  857                   {
  858                       // append to the argument we're building, collapsing whitespace to a single space.
  859                       if ( currentArg != null )
  860                       {
  861   //                        System.out.println( "Append unquoted arg part: \'" + arg + "\' to arg buffer." );
  862                           currentArg.append( ' ' ).append( arg );
  863                       }
  864                       // this is a loner, just add it directly.
  865                       else
  866                       {
  867   //                        System.out.println( "Append unquoted arg part: \'" + arg + "\' directly to cleaned list." );
  868                           cleaned.add( arg );
  869                       }
  870                   }
  871               }
  872   
  873               // clean up.
  874               if ( currentArg != null )
  875               {
  876   //                System.out.println( "Adding unterminated arg buffer: \'" + currentArg + "\' to cleaned list." );
  877                   cleaned.add( currentArg.toString() );
  878               }
  879   
  880               int cleanedSz = cleaned.size();
  881               String[] cleanArgs = null;
  882   
  883               if ( cleanedSz == 0 )
  884               {
  885                   // if we didn't have any arguments to clean, simply pass the original array through
  886                   cleanArgs = args;
  887               }
  888               else
  889               {
  890   //                System.out.println( "Cleaned argument list:\n" + cleaned );
  891                   cleanArgs = (String[]) cleaned.toArray( new String[cleanedSz] );
  892               }
  893   
  894               return cleanArgs;
  895           }
  896   
  897           public void displayHelp()
  898           {
  899               System.out.println();
  900   
  901               HelpFormatter formatter = new HelpFormatter();
  902               formatter.printHelp( "mvn [options] [<goal(s)>] [<phase(s)>]", "\nOptions:", options, "\n" );
  903           }
  904       }
  905   }

Save This Page
Home » maven-2.0.9-src » org.apache » maven » cli » [javadoc | source]