Coverage Report - org.apache.maven.shared.release.DefaultReleaseManager
 
Classes in this File Line Coverage Branch Coverage Complexity
DefaultReleaseManager
66%
173/262
55%
43/78
2,182
 
 1  
 package org.apache.maven.shared.release;
 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.util.ArrayList;
 24  
 import java.util.Collections;
 25  
 import java.util.LinkedHashSet;
 26  
 import java.util.List;
 27  
 import java.util.Map;
 28  
 import java.util.Set;
 29  
 
 30  
 import org.apache.commons.lang.BooleanUtils;
 31  
 import org.apache.maven.project.MavenProject;
 32  
 import org.apache.maven.settings.Settings;
 33  
 import org.apache.maven.shared.release.config.ReleaseDescriptor;
 34  
 import org.apache.maven.shared.release.config.ReleaseDescriptorStore;
 35  
 import org.apache.maven.shared.release.config.ReleaseDescriptorStoreException;
 36  
 import org.apache.maven.shared.release.env.DefaultReleaseEnvironment;
 37  
 import org.apache.maven.shared.release.env.ReleaseEnvironment;
 38  
 import org.apache.maven.shared.release.phase.ReleasePhase;
 39  
 import org.apache.maven.shared.release.scm.ScmRepositoryConfigurator;
 40  
 import org.codehaus.plexus.logging.AbstractLogEnabled;
 41  
 import org.codehaus.plexus.util.StringUtils;
 42  
 
 43  
 /**
 44  
  * Implementation of the release manager.
 45  
  *
 46  
  * @author <a href="mailto:brett@apache.org">Brett Porter</a>
 47  
  */
 48  60
 public class DefaultReleaseManager
 49  
     extends AbstractLogEnabled
 50  
     implements ReleaseManager
 51  
 {
 52  
     /**
 53  
      * The phases of release to run, and in what order.
 54  
      */
 55  
     private List<String> preparePhases;
 56  
 
 57  
     /**
 58  
      * The phases of release to run to perform.
 59  
      */
 60  
     private List<String> performPhases;
 61  
 
 62  
     /**
 63  
      * The phases of release to run to rollback changes
 64  
      */
 65  
     private List<String> rollbackPhases;
 66  
 
 67  
     /**
 68  
      * The phases to create a branch.
 69  
      */
 70  
     private List<String> branchPhases;
 71  
 
 72  
     /**
 73  
      * The phases to create update versions.
 74  
      */
 75  
     private List<String> updateVersionsPhases;
 76  
 
 77  
     /**
 78  
      * The available phases.
 79  
      */
 80  
     private Map<String, ReleasePhase> releasePhases;
 81  
 
 82  
     /**
 83  
      * The configuration storage.
 84  
      */
 85  
     private ReleaseDescriptorStore configStore;
 86  
 
 87  
     /**
 88  
      * Tool for configuring SCM repositories from release configuration.
 89  
      */
 90  
     private ScmRepositoryConfigurator scmRepositoryConfigurator;
 91  
 
 92  
     private static final int PHASE_SKIP = 0, PHASE_START = 1, PHASE_END = 2, GOAL_START = 11, GOAL_END = 12, ERROR = 99;
 93  
 
 94  
     /** {@inheritDoc} */
 95  
     public void prepare( ReleaseDescriptor releaseDescriptor, ReleaseEnvironment releaseEnvironment,
 96  
                          List<MavenProject> reactorProjects )
 97  
         throws ReleaseExecutionException, ReleaseFailureException
 98  
     {
 99  12
         prepare( releaseDescriptor, releaseEnvironment, reactorProjects, true, false, null );
 100  8
     }
 101  
 
 102  
     /** {@inheritDoc} */
 103  
     public void prepare( ReleaseDescriptor releaseDescriptor, ReleaseEnvironment releaseEnvironment,
 104  
                          List<MavenProject> reactorProjects, boolean resume, boolean dryRun )
 105  
         throws ReleaseExecutionException, ReleaseFailureException
 106  
     {
 107  12
         prepare( releaseDescriptor, releaseEnvironment, reactorProjects, resume, dryRun, null );
 108  10
     }
 109  
 
 110  
     public ReleaseResult prepareWithResult( ReleaseDescriptor releaseDescriptor, ReleaseEnvironment releaseEnvironment,
 111  
                                             List<MavenProject> reactorProjects, boolean resume, boolean dryRun,
 112  
                                             ReleaseManagerListener listener )
 113  
     {
 114  0
         ReleaseResult result = new ReleaseResult();
 115  
 
 116  0
         result.setStartTime( System.currentTimeMillis() );
 117  
 
 118  
         try
 119  
         {
 120  0
             prepare( releaseDescriptor, releaseEnvironment, reactorProjects, resume, dryRun, listener, result );
 121  
 
 122  0
             result.setResultCode( ReleaseResult.SUCCESS );
 123  
         }
 124  0
         catch ( ReleaseExecutionException e )
 125  
         {
 126  0
             captureException( result, listener, e );
 127  
         }
 128  0
         catch ( ReleaseFailureException e )
 129  
         {
 130  0
             captureException( result, listener, e );
 131  
         }
 132  
         finally
 133  
         {
 134  0
             result.setEndTime( System.currentTimeMillis() );
 135  0
         }
 136  
 
 137  0
         return result;
 138  
     }
 139  
 
 140  
     /** {@inheritDoc} */
 141  
     public void prepare( ReleaseDescriptor releaseDescriptor, ReleaseEnvironment releaseEnvironment,
 142  
                          List<MavenProject> reactorProjects, boolean resume, boolean dryRun,
 143  
                          ReleaseManagerListener listener )
 144  
         throws ReleaseExecutionException, ReleaseFailureException
 145  
     {
 146  24
         prepare( releaseDescriptor, releaseEnvironment, reactorProjects, resume, dryRun, listener, null );
 147  18
     }
 148  
     
 149  
     /** {@inheritDoc} */
 150  
     public void prepare( ReleasePrepareRequest prepareRequest )
 151  
         throws ReleaseExecutionException, ReleaseFailureException
 152  
     {
 153  0
         prepare( prepareRequest, new ReleaseResult() );
 154  0
     }
 155  
 
 156  
     private void prepare( ReleaseDescriptor releaseDescriptor, ReleaseEnvironment releaseEnvironment,
 157  
                           List<MavenProject> reactorProjects, boolean resume, boolean dryRun,
 158  
                           ReleaseManagerListener listener, ReleaseResult result )
 159  
         throws ReleaseExecutionException, ReleaseFailureException
 160  
     {
 161  24
         ReleasePrepareRequest prepareRequest = new ReleasePrepareRequest();
 162  24
         prepareRequest.setReleaseDescriptor( releaseDescriptor );
 163  24
         prepareRequest.setReleaseEnvironment( releaseEnvironment );
 164  24
         prepareRequest.setReactorProjects( reactorProjects );
 165  24
         prepareRequest.setResume( resume );
 166  24
         prepareRequest.setDryRun( dryRun );
 167  24
         prepareRequest.setReleaseManagerListener( listener );
 168  
 
 169  24
         prepare( prepareRequest, result );
 170  18
     }
 171  
     
 172  
     private void prepare( ReleasePrepareRequest prepareRequest, ReleaseResult result )
 173  
         throws ReleaseExecutionException, ReleaseFailureException
 174  
     {
 175  24
         updateListener( prepareRequest.getReleaseManagerListener(), "prepare", GOAL_START );
 176  
 
 177  
         ReleaseDescriptor config;
 178  24
         if ( BooleanUtils.isNotFalse( prepareRequest.getResume() ) )
 179  
         {
 180  20
             config = loadReleaseDescriptor( prepareRequest.getReleaseDescriptor(),
 181  
                                             prepareRequest.getReleaseManagerListener() );
 182  
         }
 183  
         else
 184  
         {
 185  4
             config = prepareRequest.getReleaseDescriptor();
 186  
         }
 187  
 
 188  
         // Later, it would be a good idea to introduce a proper workflow tool so that the release can be made up of a
 189  
         // more flexible set of steps.
 190  
 
 191  22
         String completedPhase = config.getCompletedPhase();
 192  22
         int index = preparePhases.indexOf( completedPhase );
 193  
 
 194  38
         for ( int idx = 0; idx <= index; idx++ )
 195  
         {
 196  16
             updateListener( prepareRequest.getReleaseManagerListener(), preparePhases.get( idx ), PHASE_SKIP );
 197  
         }
 198  
 
 199  22
         if ( index == preparePhases.size() - 1 )
 200  
         {
 201  4
             logInfo( result, "Release preparation already completed. You can now continue with release:perform, "
 202  
                 + "or start again using the -Dresume=false flag" );
 203  
         }
 204  18
         else if ( index >= 0 )
 205  
         {
 206  4
             logInfo( result, "Resuming release from phase '" + preparePhases.get( index + 1 ) + "'" );
 207  
         }
 208  
 
 209  
         // start from next phase
 210  60
         for ( int i = index + 1; i < preparePhases.size(); i++ )
 211  
         {
 212  42
             String name = preparePhases.get( i );
 213  
 
 214  42
             ReleasePhase phase = releasePhases.get( name );
 215  
 
 216  42
             if ( phase == null )
 217  
             {
 218  2
                 throw new ReleaseExecutionException( "Unable to find phase '" + name + "' to execute" );
 219  
             }
 220  
 
 221  40
             updateListener( prepareRequest.getReleaseManagerListener(), name, PHASE_START );
 222  
 
 223  40
             ReleaseResult phaseResult = null;
 224  
             try
 225  
             {
 226  40
                 if ( BooleanUtils.isTrue( prepareRequest.getDryRun() ) )
 227  
                 {
 228  16
                     phaseResult = phase.simulate( config,
 229  
                                                   prepareRequest.getReleaseEnvironment(),
 230  
                                                   prepareRequest.getReactorProjects() );
 231  
                 }
 232  
                 else
 233  
                 {
 234  24
                     phaseResult = phase.execute( config,
 235  
                                                  prepareRequest.getReleaseEnvironment(),
 236  
                                                  prepareRequest.getReactorProjects() );
 237  
                 }
 238  
             }
 239  
             finally
 240  
             {
 241  40
                 if ( result != null && phaseResult != null )
 242  
                 {
 243  0
                     result.appendOutput(  phaseResult.getOutput() );
 244  
                 }
 245  
             }
 246  
 
 247  40
             config.setCompletedPhase( name );
 248  
             try
 249  
             {
 250  40
                 configStore.write( config );
 251  
             }
 252  2
             catch ( ReleaseDescriptorStoreException e )
 253  
             {
 254  
                 // TODO: rollback?
 255  2
                 throw new ReleaseExecutionException( "Error writing release properties after completing phase", e );
 256  38
             }
 257  
 
 258  38
             updateListener( prepareRequest.getReleaseManagerListener(), name, PHASE_END );
 259  
         }
 260  
 
 261  18
         updateListener( prepareRequest.getReleaseManagerListener(), "prepare", GOAL_END );
 262  18
     }
 263  
 
 264  
     /** {@inheritDoc} */
 265  
     public void rollback( ReleaseDescriptor releaseDescriptor, ReleaseEnvironment releaseEnvironment,
 266  
                           List<MavenProject> reactorProjects )
 267  
         throws ReleaseExecutionException, ReleaseFailureException
 268  
     {
 269  2
         rollback( releaseDescriptor, releaseEnvironment, reactorProjects, null );
 270  2
     }
 271  
 
 272  
     /** {@inheritDoc} */
 273  
     public void rollback( ReleaseDescriptor releaseDescriptor, ReleaseEnvironment releaseEnvironment,
 274  
                           List<MavenProject> reactorProjects, ReleaseManagerListener listener )
 275  
         throws ReleaseExecutionException, ReleaseFailureException
 276  
     {
 277  2
         ReleaseRollbackRequest rollbackRequest = new ReleaseRollbackRequest();
 278  2
         rollbackRequest.setReleaseDescriptor( releaseDescriptor );
 279  2
         rollbackRequest.setReleaseEnvironment( releaseEnvironment );
 280  2
         rollbackRequest.setReactorProjects( reactorProjects );
 281  2
         rollbackRequest.setReleaseManagerListener( listener );
 282  
 
 283  2
         rollback( rollbackRequest );
 284  2
     }
 285  
     
 286  
     /** {@inheritDoc} */
 287  
     public void rollback( ReleaseRollbackRequest rollbackRequest )
 288  
         throws ReleaseExecutionException, ReleaseFailureException
 289  
     {
 290  2
         updateListener( rollbackRequest.getReleaseManagerListener(), "rollback", GOAL_START );
 291  
 
 292  2
         ReleaseDescriptor releaseDescriptor = loadReleaseDescriptor( rollbackRequest.getReleaseDescriptor(), null );
 293  
 
 294  2
         for ( String name : rollbackPhases )
 295  
         {
 296  2
             ReleasePhase phase = releasePhases.get( name );
 297  
 
 298  2
             if ( phase == null )
 299  
             {
 300  0
                 throw new ReleaseExecutionException( "Unable to find phase '" + name + "' to execute" );
 301  
             }
 302  
 
 303  2
             updateListener( rollbackRequest.getReleaseManagerListener(), name, PHASE_START );
 304  2
             phase.execute( releaseDescriptor,
 305  
                            rollbackRequest.getReleaseEnvironment(),
 306  
                            rollbackRequest.getReactorProjects() );
 307  2
             updateListener( rollbackRequest.getReleaseManagerListener(), name, PHASE_END );
 308  2
         }
 309  
 
 310  
         //call release:clean so that resume will not be possible anymore after a rollback
 311  2
         clean( releaseDescriptor, 
 312  
                rollbackRequest.getReleaseManagerListener(), 
 313  
                rollbackRequest.getReactorProjects() );
 314  2
         updateListener( rollbackRequest.getReleaseManagerListener(), "rollback", GOAL_END );
 315  2
     }
 316  
 
 317  
     /** {@inheritDoc} */
 318  
     public void perform( ReleaseDescriptor releaseDescriptor, ReleaseEnvironment releaseEnvironment,
 319  
                          List<MavenProject> reactorProjects )
 320  
         throws ReleaseExecutionException, ReleaseFailureException
 321  
     {
 322  24
         perform( releaseDescriptor, releaseEnvironment, reactorProjects, null, true );
 323  10
     }
 324  
 
 325  
     /** {@inheritDoc} */
 326  
     public void perform( ReleaseDescriptor releaseDescriptor, ReleaseEnvironment releaseEnvironment,
 327  
                          List<MavenProject> reactorProjects, boolean clean )
 328  
         throws ReleaseExecutionException, ReleaseFailureException
 329  
     {
 330  0
         perform( releaseDescriptor, releaseEnvironment, reactorProjects, null, clean );
 331  0
     }
 332  
 
 333  
     /** {@inheritDoc} */
 334  
     public void perform( ReleaseDescriptor releaseDescriptor, ReleaseEnvironment releaseEnvironment,
 335  
                          List<MavenProject> reactorProjects, ReleaseManagerListener listener )
 336  
         throws ReleaseExecutionException, ReleaseFailureException
 337  
     {
 338  0
         perform( releaseDescriptor, releaseEnvironment, reactorProjects, listener, true );
 339  0
     }
 340  
 
 341  
     public void perform( ReleaseDescriptor releaseDescriptor, ReleaseEnvironment releaseEnvironment,
 342  
                          List<MavenProject> reactorProjects, ReleaseManagerListener listener, boolean clean )
 343  
         throws ReleaseExecutionException, ReleaseFailureException
 344  
     {
 345  24
         perform( releaseDescriptor, releaseEnvironment, reactorProjects, listener, new ReleaseResult(), clean );
 346  10
     }
 347  
 
 348  
     public ReleaseResult performWithResult( ReleaseDescriptor releaseDescriptor, ReleaseEnvironment releaseEnvironment,
 349  
                                             List<MavenProject> reactorProjects, ReleaseManagerListener listener )
 350  
     {
 351  2
         ReleaseResult result = new ReleaseResult();
 352  
 
 353  
         try
 354  
         {
 355  2
             result.setStartTime( System.currentTimeMillis() );
 356  
 
 357  2
             perform( releaseDescriptor, releaseEnvironment, reactorProjects, listener, result, true );
 358  
 
 359  2
             result.setResultCode( ReleaseResult.SUCCESS );
 360  
         }
 361  0
         catch ( ReleaseExecutionException e )
 362  
         {
 363  0
             captureException( result, listener, e );
 364  
         }
 365  0
         catch ( ReleaseFailureException e )
 366  
         {
 367  0
             captureException( result, listener, e );
 368  
         }
 369  
         finally
 370  
         {
 371  2
             result.setEndTime( System.currentTimeMillis() );
 372  2
         }
 373  
 
 374  2
         return result;
 375  
     }
 376  
 
 377  
     /** {@inheritDoc} */
 378  
     public void perform( ReleasePerformRequest performRequest )
 379  
         throws ReleaseExecutionException, ReleaseFailureException
 380  
     {
 381  2
         perform( performRequest, new ReleaseResult() );
 382  2
     }
 383  
     
 384  
     private void perform( ReleaseDescriptor releaseDescriptor, ReleaseEnvironment releaseEnvironment,
 385  
                           List<MavenProject> reactorProjects, ReleaseManagerListener listener, ReleaseResult result,
 386  
                           boolean clean )
 387  
         throws ReleaseExecutionException, ReleaseFailureException
 388  
     {
 389  26
         ReleasePerformRequest performRequest = new ReleasePerformRequest();
 390  26
         performRequest.setReleaseDescriptor( releaseDescriptor );
 391  26
         performRequest.setReleaseEnvironment( releaseEnvironment );
 392  26
         performRequest.setReactorProjects( reactorProjects );
 393  26
         performRequest.setReleaseManagerListener( listener );
 394  26
         performRequest.setClean( clean );
 395  
 
 396  26
         perform( performRequest, result );
 397  12
     }    
 398  
     
 399  
     private void perform( ReleasePerformRequest performRequest, ReleaseResult result )
 400  
         throws ReleaseExecutionException, ReleaseFailureException
 401  
     {
 402  28
         updateListener( performRequest.getReleaseManagerListener(), "perform", GOAL_START );
 403  
 
 404  28
         ReleaseDescriptor releaseDescriptor = loadReleaseDescriptor( performRequest.getReleaseDescriptor(),
 405  
                                                                      performRequest.getReleaseManagerListener() );
 406  
 
 407  26
         for ( String name : performPhases )
 408  
         {
 409  62
             ReleasePhase phase = releasePhases.get( name );
 410  
 
 411  62
             if ( phase == null )
 412  
             {
 413  0
                 throw new ReleaseExecutionException( "Unable to find phase '" + name + "' to execute" );
 414  
             }
 415  
 
 416  62
             updateListener( performRequest.getReleaseManagerListener(), name, PHASE_START );
 417  
 
 418  62
             ReleaseResult phaseResult = null;
 419  
             try
 420  
             {
 421  62
                 if ( BooleanUtils.isTrue( performRequest.getDryRun() ) )
 422  
                 {
 423  6
                     phaseResult = phase.simulate( releaseDescriptor,
 424  
                                                  performRequest.getReleaseEnvironment(),
 425  
                                                  performRequest.getReactorProjects() );
 426  
                 }
 427  
                 else
 428  
                 {
 429  56
                     phaseResult = phase.execute( releaseDescriptor,
 430  
                                                  performRequest.getReleaseEnvironment(),
 431  
                                                  performRequest.getReactorProjects() );
 432  
                 }
 433  
             }
 434  
             finally
 435  
             {
 436  62
                 if ( result != null && phaseResult != null )
 437  
                 {
 438  50
                     result.appendOutput( phaseResult.getOutput() );
 439  
                 }
 440  
             }
 441  
 
 442  50
             updateListener( performRequest.getReleaseManagerListener(), name, PHASE_END );
 443  50
         }
 444  
 
 445  14
         if ( BooleanUtils.isNotFalse( performRequest.getClean() ) )
 446  
         {
 447  
             // call release:clean so that resume will not be possible anymore after a perform
 448  14
             clean( releaseDescriptor, performRequest.getReleaseManagerListener(), performRequest.getReactorProjects() );
 449  
         }
 450  
 
 451  14
         updateListener( performRequest.getReleaseManagerListener(), "perform", GOAL_END );
 452  14
     }
 453  
 
 454  
     /** {@inheritDoc} */
 455  
     public void branch( ReleaseDescriptor releaseDescriptor, ReleaseEnvironment releaseEnvironment,
 456  
                         List<MavenProject> reactorProjects, boolean dryRun )
 457  
         throws ReleaseExecutionException, ReleaseFailureException
 458  
     {
 459  0
         branch( releaseDescriptor, releaseEnvironment, reactorProjects, dryRun, null );
 460  0
     }
 461  
 
 462  
     /** {@inheritDoc} */
 463  
     public void branch( ReleaseDescriptor releaseDescriptor, ReleaseEnvironment releaseEnvironment,
 464  
                         List<MavenProject> reactorProjects, boolean dryRun, ReleaseManagerListener listener )
 465  
         throws ReleaseExecutionException, ReleaseFailureException
 466  
     {
 467  0
         ReleaseBranchRequest branchRequest = new ReleaseBranchRequest();
 468  0
         branchRequest.setReleaseDescriptor( releaseDescriptor );
 469  0
         branchRequest.setReleaseEnvironment( releaseEnvironment );
 470  0
         branchRequest.setReactorProjects( reactorProjects );
 471  0
         branchRequest.setDryRun( dryRun );
 472  0
         branchRequest.setReleaseManagerListener( listener );
 473  
 
 474  0
         branch( branchRequest );
 475  0
     }
 476  
     
 477  
     /** {@inheritDoc} */
 478  
     public void branch( ReleaseBranchRequest branchRequest )
 479  
         throws ReleaseExecutionException, ReleaseFailureException
 480  
     {
 481  0
         ReleaseDescriptor releaseDescriptor = loadReleaseDescriptor( branchRequest.getReleaseDescriptor(),
 482  
                                                                      branchRequest.getReleaseManagerListener() );
 483  
 
 484  0
         updateListener( branchRequest.getReleaseManagerListener(), "branch", GOAL_START );
 485  
 
 486  0
         boolean dryRun = BooleanUtils.isTrue( branchRequest.getDryRun() );
 487  
 
 488  0
         for ( String name : branchPhases )
 489  
         {
 490  0
             ReleasePhase phase = releasePhases.get( name );
 491  
 
 492  0
             if ( phase == null )
 493  
             {
 494  0
                 throw new ReleaseExecutionException( "Unable to find phase '" + name + "' to execute" );
 495  
             }
 496  
 
 497  0
             updateListener( branchRequest.getReleaseManagerListener(), name, PHASE_START );
 498  
 
 499  0
             if ( dryRun )
 500  
             {
 501  0
                 phase.simulate( releaseDescriptor,
 502  
                                 branchRequest.getReleaseEnvironment(),
 503  
                                 branchRequest.getReactorProjects() );
 504  
             }
 505  
             else // getDryRun is null or FALSE
 506  
             {
 507  0
                 phase.execute( releaseDescriptor,
 508  
                                branchRequest.getReleaseEnvironment(),
 509  
                                branchRequest.getReactorProjects() );
 510  
             }
 511  0
             updateListener( branchRequest.getReleaseManagerListener(), name, PHASE_END );
 512  0
         }
 513  
 
 514  0
         if ( !dryRun )
 515  
         {
 516  0
             clean( releaseDescriptor,
 517  
                    branchRequest.getReleaseManagerListener(),
 518  
                    branchRequest.getReactorProjects() );
 519  
         }
 520  
 
 521  0
         updateListener( branchRequest.getReleaseManagerListener(), "branch", GOAL_END );
 522  0
     }
 523  
 
 524  
     public void updateVersions( ReleaseDescriptor releaseDescriptor, ReleaseEnvironment releaseEnvironment,
 525  
                                 List<MavenProject> reactorProjects )
 526  
         throws ReleaseExecutionException, ReleaseFailureException
 527  
     {
 528  2
         ReleaseUpdateVersionsRequest updateVersionsRequest = new ReleaseUpdateVersionsRequest();
 529  2
         updateVersionsRequest.setReleaseDescriptor( releaseDescriptor );
 530  2
         updateVersionsRequest.setReleaseEnvironment( releaseEnvironment );
 531  2
         updateVersionsRequest.setReactorProjects( reactorProjects );
 532  
 
 533  2
         updateVersions( updateVersionsRequest );
 534  2
     }
 535  
     
 536  
     /** {@inheritDoc} */
 537  
     public void updateVersions( ReleaseUpdateVersionsRequest updateVersionsRequest )
 538  
         throws ReleaseExecutionException, ReleaseFailureException
 539  
     {
 540  2
         updateListener( updateVersionsRequest.getReleaseManagerListener(), "updateVersions", GOAL_START );
 541  
 
 542  2
         ReleaseDescriptor releaseDescriptor = loadReleaseDescriptor( updateVersionsRequest.getReleaseDescriptor(), 
 543  
                                                                      updateVersionsRequest.getReleaseManagerListener() );
 544  
 
 545  2
         for ( String name : updateVersionsPhases )
 546  
         {
 547  2
             ReleasePhase phase = releasePhases.get( name );
 548  
 
 549  2
             if ( phase == null )
 550  
             {
 551  0
                 throw new ReleaseExecutionException( "Unable to find phase '" + name + "' to execute" );
 552  
             }
 553  
 
 554  2
             updateListener( updateVersionsRequest.getReleaseManagerListener(), name, PHASE_START );
 555  2
             phase.execute( releaseDescriptor,
 556  
                            updateVersionsRequest.getReleaseEnvironment(),
 557  
                            updateVersionsRequest.getReactorProjects() );
 558  2
             updateListener( updateVersionsRequest.getReleaseManagerListener(), name, PHASE_END );
 559  2
         }
 560  
 
 561  2
         clean( releaseDescriptor, 
 562  
                updateVersionsRequest.getReleaseManagerListener(),
 563  
                updateVersionsRequest.getReactorProjects() );
 564  
 
 565  2
         updateListener( updateVersionsRequest.getReleaseManagerListener(), "updateVersions", GOAL_END );
 566  2
     }
 567  
 
 568  
     /**
 569  
      * Determines the path of the working directory. By default, this is the
 570  
      * checkout directory. For some SCMs, the project root directory is not the
 571  
      * checkout directory itself, but a SCM-specific subdirectory.
 572  
      *
 573  
      * @param checkoutDirectory            The checkout directory as java.io.File
 574  
      * @param relativePathProjectDirectory The relative path of the project directory within the checkout
 575  
      *                                     directory or ""
 576  
      * @return The working directory
 577  
      */
 578  
     protected File determineWorkingDirectory( File checkoutDirectory, String relativePathProjectDirectory )
 579  
     {
 580  10
         if ( StringUtils.isNotEmpty( relativePathProjectDirectory ) )
 581  
         {
 582  6
             return new File( checkoutDirectory, relativePathProjectDirectory );
 583  
         }
 584  
         else
 585  
         {
 586  4
             return checkoutDirectory;
 587  
         }
 588  
     }
 589  
 
 590  
     private ReleaseDescriptor loadReleaseDescriptor( ReleaseDescriptor releaseDescriptor,
 591  
                                                      ReleaseManagerListener listener )
 592  
         throws ReleaseExecutionException
 593  
     {
 594  
         try
 595  
         {
 596  52
             updateListener( listener, "verify-release-configuration", PHASE_START );
 597  52
             ReleaseDescriptor descriptor = configStore.read( releaseDescriptor );
 598  48
             updateListener( listener, "verify-release-configuration", PHASE_END );
 599  48
             return descriptor;
 600  
         }
 601  4
         catch ( ReleaseDescriptorStoreException e )
 602  
         {
 603  4
             updateListener( listener, e.getMessage(), ERROR );
 604  
 
 605  4
             throw new ReleaseExecutionException( "Error reading stored configuration: " + e.getMessage(), e );
 606  
         }
 607  
     }
 608  
 
 609  
     /** {@inheritDoc} */
 610  
     public void clean( ReleaseDescriptor releaseDescriptor, ReleaseManagerListener listener,
 611  
                        List<MavenProject> reactorProjects )
 612  
     {
 613  20
         ReleaseCleanRequest cleanRequest = new ReleaseCleanRequest();
 614  20
         cleanRequest.setReleaseDescriptor( releaseDescriptor );
 615  20
         cleanRequest.setReleaseManagerListener( listener );
 616  20
         cleanRequest.setReactorProjects( reactorProjects );
 617  
 
 618  20
         clean( cleanRequest );
 619  20
     }
 620  
 
 621  
     /** {@inheritDoc} */
 622  
     public void clean( ReleaseCleanRequest cleanRequest )
 623  
     {
 624  20
         updateListener( cleanRequest.getReleaseManagerListener(), "cleanup", PHASE_START );
 625  
 
 626  20
         getLogger().info( "Cleaning up after release..." );
 627  
 
 628  20
         configStore.delete( cleanRequest.getReleaseDescriptor() );
 629  20
         Set<String> phases = new LinkedHashSet<String>( preparePhases );
 630  20
         phases.addAll( branchPhases );
 631  
 
 632  20
         for ( String name : phases )
 633  
         {
 634  80
             ReleasePhase phase = releasePhases.get( name );
 635  
 
 636  80
             phase.clean( cleanRequest.getReactorProjects() );
 637  80
         }
 638  
 
 639  20
         updateListener( cleanRequest.getReleaseManagerListener(), "cleanup", PHASE_END );
 640  20
     }
 641  
 
 642  
     void setConfigStore( ReleaseDescriptorStore configStore )
 643  
     {
 644  12
         this.configStore = configStore;
 645  12
     }
 646  
 
 647  
     void updateListener( ReleaseManagerListener listener, String name, int state )
 648  
     {
 649  450
         if ( listener != null )
 650  
         {
 651  24
             switch ( state )
 652  
             {
 653  
                 case GOAL_START:
 654  2
                     listener.goalStart( name, getGoalPhases( name ) );
 655  2
                     break;
 656  
                 case GOAL_END:
 657  2
                     listener.goalEnd();
 658  2
                     break;
 659  
                 case PHASE_SKIP:
 660  0
                     listener.phaseSkip( name );
 661  0
                     break;
 662  
                 case PHASE_START:
 663  10
                     listener.phaseStart( name );
 664  10
                     break;
 665  
                 case PHASE_END:
 666  10
                     listener.phaseEnd();
 667  10
                     break;
 668  
                 default:
 669  0
                     listener.error( name );
 670  
             }
 671  
         }
 672  450
     }
 673  
 
 674  
     private List<String> getGoalPhases( String name )
 675  
     {
 676  2
         List<String> phases = new ArrayList<String>();
 677  
 
 678  2
         if ( "prepare".equals( name ) )
 679  
         {
 680  0
             phases.addAll( preparePhases );
 681  
         }
 682  2
         else if ( "perform".equals( name ) )
 683  
         {
 684  2
             phases.addAll( performPhases );
 685  
         }
 686  0
         else if ( "rollback".equals( name ) )
 687  
         {
 688  0
             phases.addAll( rollbackPhases );
 689  
         }
 690  0
         else if ( "branch".equals( name ) )
 691  
         {
 692  0
             phases.addAll( branchPhases );
 693  
         }
 694  0
         else if ( "updateVersions".equals( name ) )
 695  
         {
 696  0
             phases.addAll( updateVersionsPhases );
 697  
         }
 698  
 
 699  2
         return Collections.unmodifiableList( phases );
 700  
     }
 701  
 
 702  
     private void logInfo( ReleaseResult result, String message )
 703  
     {
 704  8
         if ( result != null )
 705  
         {
 706  0
             result.appendInfo( message );
 707  
         }
 708  
 
 709  8
         getLogger().info( message );
 710  8
     }
 711  
 
 712  
     private void captureException( ReleaseResult result, ReleaseManagerListener listener, Exception e )
 713  
     {
 714  0
         updateListener( listener, e.getMessage(), ERROR );
 715  
 
 716  0
         result.appendError( e );
 717  
 
 718  0
         result.setResultCode( ReleaseResult.ERROR );
 719  0
     }
 720  
 
 721  
     /** {@inheritDoc} */
 722  
     public void branch( ReleaseDescriptor releaseDescriptor, Settings settings, List<MavenProject> reactorProjects,
 723  
                         boolean dryRun )
 724  
         throws ReleaseExecutionException, ReleaseFailureException
 725  
     {
 726  0
         branch( releaseDescriptor, new DefaultReleaseEnvironment().setSettings( settings ), reactorProjects, dryRun );
 727  0
     }
 728  
 
 729  
     /** {@inheritDoc} */
 730  
     public void branch( ReleaseDescriptor releaseDescriptor, Settings settings, List<MavenProject> reactorProjects,
 731  
                         boolean dryRun, ReleaseManagerListener listener )
 732  
         throws ReleaseExecutionException, ReleaseFailureException
 733  
     {
 734  0
         branch( releaseDescriptor, new DefaultReleaseEnvironment().setSettings( settings ), reactorProjects, dryRun,
 735  
                 listener );
 736  0
     }
 737  
 
 738  
     /** {@inheritDoc} */
 739  
     public void perform( ReleaseDescriptor releaseDescriptor, Settings settings, List<MavenProject> reactorProjects )
 740  
         throws ReleaseExecutionException, ReleaseFailureException
 741  
     {
 742  0
         perform( releaseDescriptor, new DefaultReleaseEnvironment().setSettings( settings ), reactorProjects );
 743  0
     }
 744  
 
 745  
     /** {@inheritDoc} */
 746  
     public void perform( ReleaseDescriptor releaseDescriptor, Settings settings, List<MavenProject> reactorProjects,
 747  
                          ReleaseManagerListener listener )
 748  
         throws ReleaseExecutionException, ReleaseFailureException
 749  
     {
 750  0
         perform( releaseDescriptor, new DefaultReleaseEnvironment().setSettings( settings ), reactorProjects, listener );
 751  0
     }
 752  
 
 753  
     /** {@inheritDoc} */
 754  
     public void perform( ReleaseDescriptor releaseDescriptor, Settings settings, List<MavenProject> reactorProjects,
 755  
                          boolean clean )
 756  
         throws ReleaseExecutionException, ReleaseFailureException
 757  
     {
 758  0
         perform( releaseDescriptor, new DefaultReleaseEnvironment().setSettings( settings ), reactorProjects, clean );
 759  0
     }
 760  
 
 761  
     public ReleaseResult performWithResult( ReleaseDescriptor releaseDescriptor, Settings settings,
 762  
                                             List<MavenProject> reactorProjects, ReleaseManagerListener listener )
 763  
     {
 764  0
         return performWithResult( releaseDescriptor, new DefaultReleaseEnvironment().setSettings( settings ),
 765  
                                   reactorProjects, listener );
 766  
     }
 767  
 
 768  
     /** {@inheritDoc} */
 769  
     public void prepare( ReleaseDescriptor releaseDescriptor, Settings settings, List<MavenProject> reactorProjects )
 770  
         throws ReleaseExecutionException, ReleaseFailureException
 771  
     {
 772  0
         prepare( releaseDescriptor, new DefaultReleaseEnvironment().setSettings( settings ), reactorProjects );
 773  0
     }
 774  
 
 775  
     /** {@inheritDoc} */
 776  
     public void prepare( ReleaseDescriptor releaseDescriptor, Settings settings, List<MavenProject> reactorProjects,
 777  
                          boolean resume, boolean dryRun )
 778  
         throws ReleaseExecutionException, ReleaseFailureException
 779  
     {
 780  0
         prepare( releaseDescriptor, new DefaultReleaseEnvironment().setSettings( settings ), reactorProjects, resume,
 781  
                  dryRun );
 782  0
     }
 783  
 
 784  
     /** {@inheritDoc} */
 785  
     public void prepare( ReleaseDescriptor releaseDescriptor, Settings settings, List<MavenProject> reactorProjects,
 786  
                          boolean resume, boolean dryRun, ReleaseManagerListener listener )
 787  
         throws ReleaseExecutionException, ReleaseFailureException
 788  
     {
 789  0
         prepare( releaseDescriptor, new DefaultReleaseEnvironment().setSettings( settings ), reactorProjects, resume,
 790  
                  dryRun, listener );
 791  0
     }
 792  
 
 793  
     public ReleaseResult prepareWithResult( ReleaseDescriptor releaseDescriptor, Settings settings,
 794  
                                             List<MavenProject> reactorProjects, boolean resume, boolean dryRun,
 795  
                                             ReleaseManagerListener listener )
 796  
     {
 797  0
         return prepareWithResult( releaseDescriptor, new DefaultReleaseEnvironment().setSettings( settings ),
 798  
                                   reactorProjects, resume, dryRun, listener );
 799  
     }
 800  
 
 801  
     /** {@inheritDoc} */
 802  
     public void rollback( ReleaseDescriptor releaseDescriptor, Settings settings, List<MavenProject> reactorProjects,
 803  
                           ReleaseManagerListener listener )
 804  
         throws ReleaseExecutionException, ReleaseFailureException
 805  
     {
 806  0
         rollback( releaseDescriptor, new DefaultReleaseEnvironment().setSettings( settings ), reactorProjects, listener );
 807  0
     }
 808  
 
 809  
     /** {@inheritDoc} */
 810  
     public void rollback( ReleaseDescriptor releaseDescriptor, Settings settings, List<MavenProject> reactorProjects )
 811  
         throws ReleaseExecutionException, ReleaseFailureException
 812  
     {
 813  0
         rollback( releaseDescriptor, new DefaultReleaseEnvironment().setSettings( settings ), reactorProjects, null );
 814  0
     }
 815  
 }