Coverage Report - org.apache.maven.shared.invoker.MavenCommandLineBuilder
 
Classes in this File Line Coverage Branch Coverage Complexity
MavenCommandLineBuilder
78%
168/215
75%
84/112
4,273
 
 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 java.io.File;
 23  
 import java.io.IOException;
 24  
 import java.util.Iterator;
 25  
 import java.util.List;
 26  
 import java.util.Map;
 27  
 import java.util.Properties;
 28  
 
 29  
 import org.codehaus.plexus.util.Os;
 30  
 import org.codehaus.plexus.util.StringUtils;
 31  
 import org.codehaus.plexus.util.cli.CommandLineUtils;
 32  
 import org.codehaus.plexus.util.cli.Commandline;
 33  
 
 34  
 /**
 35  
  * @version $Id: MavenCommandLineBuilder.java 807829 2009-08-25 22:06:10Z olamy $
 36  
  */
 37  92
 public class MavenCommandLineBuilder
 38  
 {
 39  
 
 40  2
     private static final InvokerLogger DEFAULT_LOGGER = new SystemOutLogger();
 41  
 
 42  92
     private InvokerLogger logger = DEFAULT_LOGGER;
 43  
 
 44  
     private File workingDirectory;
 45  
 
 46  
     private File localRepositoryDirectory;
 47  
 
 48  
     private File mavenHome;
 49  
 
 50  
     private File mvnCommand;
 51  
 
 52  
     private Properties systemEnvVars;
 53  
 
 54  
     public Commandline build( InvocationRequest request )
 55  
         throws CommandLineConfigurationException
 56  
     {
 57  
         try
 58  
         {
 59  18
             checkRequiredState();
 60  
         }
 61  0
         catch ( IOException e )
 62  
         {
 63  0
             throw new CommandLineConfigurationException( e.getMessage(), e );
 64  18
         }
 65  18
         File mvn = null;
 66  
         try
 67  
         {
 68  18
             mvn = findMavenExecutable();
 69  
         }
 70  0
         catch ( IOException e )
 71  
         {
 72  0
             throw new CommandLineConfigurationException( e.getMessage(), e );
 73  18
         }
 74  18
         Commandline cli = new Commandline();
 75  
 
 76  18
         cli.setExecutable( mvn.getAbsolutePath() );
 77  
 
 78  
         // handling for OS-level envars
 79  18
         setShellEnvironment( request, cli );
 80  
 
 81  
         // interactive, offline, update-snapshots,
 82  
         // debug/show-errors, checksum policy
 83  18
         setFlags( request, cli );
 84  
 
 85  
         // failure behavior and [eventually] forced-reactor
 86  
         // includes/excludes, etc.
 87  18
         setReactorBehavior( request, cli );
 88  
 
 89  
         // working directory and local repository location
 90  18
         setEnvironmentPaths( request, cli );
 91  
 
 92  
         // pom-file and basedir handling
 93  18
         setPomLocation( request, cli );
 94  
 
 95  18
         setSettingsLocation( request, cli );
 96  
 
 97  18
         setProperties( request, cli );
 98  
 
 99  18
         setProfiles( request, cli );
 100  
 
 101  18
         setGoals( request, cli );
 102  
 
 103  18
         return cli;
 104  
     }
 105  
 
 106  
     protected void checkRequiredState()
 107  
         throws IOException
 108  
     {
 109  22
         if ( logger == null )
 110  
         {
 111  2
             throw new IllegalStateException( "A logger instance is required." );
 112  
         }
 113  
 
 114  20
         if ( ( mavenHome == null ) && ( System.getProperty( "maven.home" ) == null ) )
 115  
         // can be restored with 1.5
 116  
         // && ( System.getenv( "M2_HOME" ) != null ) )
 117  
         {
 118  0
             if ( !getSystemEnvVars().containsKey( "M2_HOME" ) )
 119  
             {
 120  0
                 throw new IllegalStateException( "Maven application directory was not "
 121  
                     + "specified, and ${maven.home} is not provided in the system "
 122  
                     + "properties. Please specify at least on of these." );
 123  
             }
 124  
         }
 125  20
     }
 126  
 
 127  
     protected void setSettingsLocation( InvocationRequest request, Commandline cli )
 128  
     {
 129  20
         File userSettingsFile = request.getUserSettingsFile();
 130  
 
 131  20
         if ( userSettingsFile != null )
 132  
         {
 133  
             try
 134  
             {
 135  4
                 File canSet = userSettingsFile.getCanonicalFile();
 136  4
                 userSettingsFile = canSet;
 137  
             }
 138  0
             catch ( IOException e )
 139  
             {
 140  0
                 logger.debug( "Failed to canonicalize user settings path: " + userSettingsFile.getAbsolutePath()
 141  
                     + ". Using as-is.", e );
 142  4
             }
 143  
 
 144  4
             cli.createArg().setValue( "-s" );
 145  4
             cli.createArg().setValue( userSettingsFile.getPath() );
 146  
         }
 147  20
     }
 148  
 
 149  
     protected void setShellEnvironment( InvocationRequest request, Commandline cli )
 150  
         throws CommandLineConfigurationException
 151  
     {
 152  18
         if ( request.isShellEnvironmentInherited() )
 153  
         {
 154  
             try
 155  
             {
 156  18
                 cli.addSystemEnvironment();
 157  18
                 cli.addEnvironment( "MAVEN_TERMINATE_CMD", "on" );
 158  
             }
 159  0
             catch ( IOException e )
 160  
             {
 161  0
                 throw new CommandLineConfigurationException( "Error reading shell environment variables. Reason: "
 162  
                     + e.getMessage(), e );
 163  
             }
 164  0
             catch ( Exception e )
 165  
             {
 166  0
                 if ( e instanceof RuntimeException )
 167  
                 {
 168  0
                     throw (RuntimeException) e;
 169  
                 }
 170  
                 else
 171  
                 {
 172  0
                     IllegalStateException error =
 173  
                         new IllegalStateException( "Unknown error retrieving shell environment variables. Reason: "
 174  
                             + e.getMessage() );
 175  0
                     error.initCause( e );
 176  
 
 177  0
                     throw error;
 178  
                 }
 179  18
             }
 180  
         }
 181  
 
 182  18
         if ( request.getJavaHome() != null )
 183  
         {
 184  0
             cli.addEnvironment( "JAVA_HOME", request.getJavaHome().getAbsolutePath() );
 185  
         }
 186  
 
 187  18
         if ( request.getMavenOpts() != null )
 188  
         {
 189  0
             cli.addEnvironment( "MAVEN_OPTS", request.getMavenOpts() );
 190  
         }
 191  
 
 192  18
         for ( Iterator iterator = request.getShellEnvironments().keySet().iterator(); iterator.hasNext(); )
 193  
         {
 194  0
             String key = (String) iterator.next();
 195  0
             String value = (String) request.getShellEnvironments().get( key );
 196  0
             cli.addEnvironment( key, value );
 197  
         }
 198  18
     }
 199  
 
 200  
     protected void setProfiles( InvocationRequest request, Commandline cli )
 201  
     {
 202  18
         List profiles = request.getProfiles();
 203  
 
 204  18
         if ( ( profiles != null ) && !profiles.isEmpty() )
 205  
         {
 206  2
             cli.createArg().setValue( "-P" );
 207  2
             cli.createArg().setValue( StringUtils.join( profiles.iterator(), "," ) );
 208  
         }
 209  
 
 210  18
     }
 211  
 
 212  
     protected void setGoals( InvocationRequest request, Commandline cli )
 213  
     {
 214  22
         List goals = request.getGoals();
 215  
 
 216  22
         if ( ( goals != null ) && !goals.isEmpty() )
 217  
         {
 218  20
             cli.createArg().setLine( StringUtils.join( goals.iterator(), " " ) );
 219  
         }
 220  22
     }
 221  
 
 222  
     protected void setProperties( InvocationRequest request, Commandline cli )
 223  
     {
 224  24
         Properties properties = request.getProperties();
 225  
 
 226  24
         if ( properties != null )
 227  
         {
 228  10
             for ( Iterator it = properties.entrySet().iterator(); it.hasNext(); )
 229  
             {
 230  12
                 Map.Entry entry = (Map.Entry) it.next();
 231  
 
 232  12
                 String key = (String) entry.getKey();
 233  12
                 String value = (String) entry.getValue();
 234  
 
 235  12
                 cli.createArg().setValue( "-D" );
 236  12
                 cli.createArg().setValue( key + '=' + value );
 237  
             }
 238  
         }
 239  24
     }
 240  
 
 241  
     protected void setPomLocation( InvocationRequest request, Commandline cli )
 242  
     {
 243  30
         boolean pomSpecified = false;
 244  
 
 245  30
         File pom = request.getPomFile();
 246  30
         String pomFilename = request.getPomFileName();
 247  30
         File baseDirectory = request.getBaseDirectory();
 248  
 
 249  30
         if ( pom != null )
 250  
         {
 251  4
             pomSpecified = true;
 252  
         }
 253  26
         else if ( baseDirectory != null )
 254  
         {
 255  24
             if ( baseDirectory.isDirectory() )
 256  
             {
 257  20
                 if ( pomFilename != null )
 258  
                 {
 259  4
                     pom = new File( baseDirectory, pomFilename );
 260  
 
 261  4
                     pomSpecified = true;
 262  
                 }
 263  
                 else
 264  
                 {
 265  16
                     pom = new File( baseDirectory, "pom.xml" );
 266  
                 }
 267  
             }
 268  
             else
 269  
             {
 270  4
                 logger.warn( "Base directory is a file. Using base directory as POM location." );
 271  
 
 272  4
                 pom = baseDirectory;
 273  
 
 274  4
                 pomSpecified = true;
 275  
             }
 276  
         }
 277  
 
 278  30
         if ( pomSpecified )
 279  
         {
 280  
             try
 281  
             {
 282  12
                 File canPom = pom.getCanonicalFile();
 283  12
                 pom = canPom;
 284  
             }
 285  0
             catch ( IOException e )
 286  
             {
 287  0
                 logger.debug( "Failed to canonicalize the POM path: " + pom + ". Using as-is.", e );
 288  12
             }
 289  
 
 290  12
             if ( !"pom.xml".equals( pom.getName() ) )
 291  
             {
 292  8
                 logger.debug( "Specified POM file is not named \'pom.xml\'. "
 293  
                     + "Using the \'-f\' command-line option to accommodate non-standard filename..." );
 294  
 
 295  8
                 cli.createArg().setValue( "-f" );
 296  8
                 cli.createArg().setValue( pom.getName() );
 297  
             }
 298  
         }
 299  30
     }
 300  
 
 301  
     protected void setEnvironmentPaths( InvocationRequest request, Commandline cli )
 302  
     {
 303  46
         File workingDirectory = request.getBaseDirectory();
 304  
 
 305  46
         if ( workingDirectory == null )
 306  
         {
 307  18
             File pomFile = request.getPomFile();
 308  18
             if ( pomFile != null )
 309  
             {
 310  4
                 workingDirectory = pomFile.getParentFile();
 311  
             }
 312  
         }
 313  
 
 314  46
         if ( workingDirectory == null )
 315  
         {
 316  14
             workingDirectory = this.workingDirectory;
 317  
         }
 318  
 
 319  46
         if ( workingDirectory == null )
 320  
         {
 321  12
             workingDirectory = new File( System.getProperty( "user.dir" ) );
 322  
         }
 323  34
         else if ( workingDirectory.isFile() )
 324  
         {
 325  4
             logger.warn( "Specified base directory (" + workingDirectory + ") is a file."
 326  
                 + " Using its parent directory..." );
 327  
 
 328  4
             workingDirectory = workingDirectory.getParentFile();
 329  
         }
 330  
 
 331  
         try
 332  
         {
 333  46
             cli.setWorkingDirectory( workingDirectory.getCanonicalPath() );
 334  
         }
 335  0
         catch ( IOException e )
 336  
         {
 337  0
             logger.debug( "Failed to canonicalize base directory: " + workingDirectory + ". Using as-is.", e );
 338  
 
 339  0
             cli.setWorkingDirectory( workingDirectory.getAbsolutePath() );
 340  46
         }
 341  
 
 342  46
         File localRepositoryDirectory = request.getLocalRepositoryDirectory( this.localRepositoryDirectory );
 343  
 
 344  46
         if ( localRepositoryDirectory != null )
 345  
         {
 346  
             try
 347  
             {
 348  12
                 File canLRD = localRepositoryDirectory.getCanonicalFile();
 349  12
                 localRepositoryDirectory = canLRD;
 350  
             }
 351  0
             catch ( IOException e )
 352  
             {
 353  0
                 logger.debug( "Failed to canonicalize local repository directory: " + localRepositoryDirectory
 354  
                     + ". Using as-is.", e );
 355  12
             }
 356  
 
 357  12
             if ( !localRepositoryDirectory.isDirectory() )
 358  
             {
 359  4
                 throw new IllegalArgumentException( "Local repository location: \'" + localRepositoryDirectory
 360  
                     + "\' is NOT a directory." );
 361  
             }
 362  
 
 363  8
             cli.createArg().setValue( "-D" );
 364  8
             cli.createArg().setValue( "maven.repo.local=" + localRepositoryDirectory.getPath() );
 365  
         }
 366  42
     }
 367  
 
 368  
     protected void setReactorBehavior( InvocationRequest request, Commandline cli )
 369  
     {
 370  
         // NOTE: The default is "fail-fast"
 371  28
         String failureBehavior = request.getFailureBehavior();
 372  
 
 373  28
         if ( StringUtils.isNotEmpty( failureBehavior ) )
 374  
         {
 375  28
             if ( InvocationRequest.REACTOR_FAIL_AT_END.equals( failureBehavior ) )
 376  
             {
 377  2
                 cli.createArg().setValue( "-fae" );
 378  
             }
 379  26
             else if ( InvocationRequest.REACTOR_FAIL_NEVER.equals( failureBehavior ) )
 380  
             {
 381  2
                 cli.createArg().setValue( "-fn" );
 382  
             }
 383  
         }
 384  
 
 385  28
         if ( request.isActivatedReactor() )
 386  
         {
 387  4
             cli.createArg().setValue( "-r" );
 388  4
             String[] includes = request.getActivatedReactorIncludes();
 389  4
             String[] excludes = request.getActivatedReactorExcludes();
 390  4
             if ( includes != null )
 391  
             {
 392  2
                 cli.createArg().setValue( "-D" );
 393  2
                 cli.createArg().setValue( "maven.reactor.includes=" + StringUtils.join( includes, "," ) );
 394  
             }
 395  4
             if ( excludes != null )
 396  
             {
 397  2
                 cli.createArg().setValue( "-D" );
 398  2
                 cli.createArg().setValue( "maven.reactor.excludes=" + StringUtils.join( excludes, "," ) );
 399  
             }
 400  
         }
 401  28
     }
 402  
 
 403  
     protected void setFlags( InvocationRequest request, Commandline cli )
 404  
     {
 405  34
         if ( !request.isInteractive() )
 406  
         {
 407  34
             cli.createArg().setValue( "-B" );
 408  
         }
 409  
 
 410  34
         if ( request.isOffline() )
 411  
         {
 412  4
             cli.createArg().setValue( "-o" );
 413  
         }
 414  
 
 415  34
         if ( request.isUpdateSnapshots() )
 416  
         {
 417  2
             cli.createArg().setValue( "-U" );
 418  
         }
 419  
 
 420  34
         if ( !request.isRecursive() )
 421  
         {
 422  0
             cli.createArg().setValue( "-N" );
 423  
         }
 424  
 
 425  34
         if ( request.isDebug() )
 426  
         {
 427  16
             cli.createArg().setValue( "-X" );
 428  
         }
 429  
         // this is superceded by -X, if it exists.
 430  18
         else if ( request.isShowErrors() )
 431  
         {
 432  2
             cli.createArg().setValue( "-e" );
 433  
         }
 434  
 
 435  34
         String checksumPolicy = request.getGlobalChecksumPolicy();
 436  34
         if ( InvocationRequest.CHECKSUM_POLICY_FAIL.equals( checksumPolicy ) )
 437  
         {
 438  2
             cli.createArg().setValue( "-C" );
 439  
         }
 440  32
         else if ( InvocationRequest.CHECKSUM_POLICY_WARN.equals( checksumPolicy ) )
 441  
         {
 442  2
             cli.createArg().setValue( "-c" );
 443  
         }
 444  34
         if ( request.isNonPluginUpdates() )
 445  
         {
 446  0
             cli.createArg().setValue( "-npu" );
 447  
         }
 448  
         
 449  34
         if ( request.isShowVersion() )
 450  
         {
 451  0
             cli.createArg().setValue( "-V" );
 452  
         }
 453  34
     }
 454  
 
 455  
     protected File findMavenExecutable()
 456  
         throws CommandLineConfigurationException, IOException
 457  
     {
 458  20
         if ( mavenHome == null )
 459  
         {
 460  6
             String mavenHomeProperty = System.getProperty( "maven.home" );
 461  6
             if ( mavenHomeProperty != null )
 462  
             {
 463  6
                 mavenHome = new File( mavenHomeProperty );
 464  6
                 if ( !mavenHome.isDirectory() )
 465  
                 {
 466  0
                     File binDir = mavenHome.getParentFile();
 467  0
                     if ( "bin".equals( binDir.getName() ) )
 468  
                     {
 469  
                         // ah, they specified the mvn
 470  
                         // executable instead...
 471  0
                         mavenHome = binDir.getParentFile();
 472  
                     }
 473  
                     else
 474  
                     {
 475  0
                         throw new IllegalStateException( "${maven.home} is not specified as a directory: \'"
 476  
                             + mavenHomeProperty + "\'." );
 477  
                     }
 478  
                 }
 479  
             }
 480  
 
 481  6
             if ( ( mavenHome == null ) && ( getSystemEnvVars().getProperty( "M2_HOME" ) != null ) )
 482  
             {
 483  0
                 mavenHome = new File( getSystemEnvVars().getProperty( "M2_HOME" ) );
 484  
             }
 485  
         }
 486  
 
 487  20
         logger.debug( "Using ${maven.home} of: \'" + mavenHome + "\'." );
 488  
 
 489  20
         if ( mvnCommand == null )
 490  
         {
 491  20
             if ( Os.isFamily( "windows" ) )
 492  
             {
 493  20
                 mvnCommand = new File( mavenHome, "/bin/mvn.bat" );
 494  
             }
 495  
             else
 496  
             {
 497  0
                 mvnCommand = new File( mavenHome, "/bin/mvn" );
 498  
             }
 499  
 
 500  
             try
 501  
             {
 502  20
                 File canonicalMvn = mvnCommand.getCanonicalFile();
 503  20
                 mvnCommand = canonicalMvn;
 504  
             }
 505  0
             catch ( IOException e )
 506  
             {
 507  0
                 logger.debug( "Failed to canonicalize maven executable: " + mvnCommand + ". Using as-is.", e );
 508  20
             }
 509  
 
 510  20
             if ( !mvnCommand.exists() )
 511  
             {
 512  0
                 throw new CommandLineConfigurationException( "Maven executable not found at: " + mvnCommand );
 513  
             }
 514  
         }
 515  
 
 516  20
         return mvnCommand;
 517  
     }
 518  
 
 519  
     /**
 520  
      * Wraps a path with quotes to handle paths with spaces. If no spaces are found, the original string is returned.
 521  
      * 
 522  
      * @param path string to wrap if containing spaces
 523  
      * @return quote wrapped string
 524  
      * @deprecated Quoting of command line arguments should be left to the Commandline from plexus-utils.
 525  
      */
 526  
     public String wrapStringWithQuotes( String path )
 527  
     {
 528  8
         if ( path.indexOf( " " ) > -1 )
 529  
         {
 530  4
             return "\"" + path + "\"";
 531  
         }
 532  
         else
 533  
         {
 534  4
             return path;
 535  
         }
 536  
     }
 537  
 
 538  
     private Properties getSystemEnvVars()
 539  
         throws IOException
 540  
     {
 541  0
         if ( this.systemEnvVars == null )
 542  
         {
 543  
             // with 1.5 replace with System.getenv()
 544  0
             this.systemEnvVars = CommandLineUtils.getSystemEnvVars();
 545  
         }
 546  0
         return this.systemEnvVars;
 547  
     }
 548  
 
 549  
     public File getLocalRepositoryDirectory()
 550  
     {
 551  0
         return localRepositoryDirectory;
 552  
     }
 553  
 
 554  
     public void setLocalRepositoryDirectory( File localRepositoryDirectory )
 555  
     {
 556  6
         this.localRepositoryDirectory = localRepositoryDirectory;
 557  6
     }
 558  
 
 559  
     public InvokerLogger getLogger()
 560  
     {
 561  0
         return logger;
 562  
     }
 563  
 
 564  
     public void setLogger( InvokerLogger logger )
 565  
     {
 566  14
         this.logger = logger;
 567  14
     }
 568  
 
 569  
     public File getMavenHome()
 570  
     {
 571  0
         return mavenHome;
 572  
     }
 573  
 
 574  
     public void setMavenHome( File mavenHome )
 575  
     {
 576  14
         this.mavenHome = mavenHome;
 577  14
     }
 578  
 
 579  
     public File getWorkingDirectory()
 580  
     {
 581  0
         return workingDirectory;
 582  
     }
 583  
 
 584  
     public void setWorkingDirectory( File workingDirectory )
 585  
     {
 586  4
         this.workingDirectory = workingDirectory;
 587  4
     }
 588  
 
 589  
 }