View Javadoc
1   package org.apache.maven.shared.release.phase;
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.maven.project.MavenProject;
23  import org.apache.maven.scm.ScmException;
24  import org.apache.maven.scm.ScmFileSet;
25  import org.apache.maven.scm.ScmVersion;
26  import org.apache.maven.scm.command.checkin.CheckInScmResult;
27  import org.apache.maven.scm.manager.NoSuchScmProviderException;
28  import org.apache.maven.scm.provider.ScmProvider;
29  import org.apache.maven.scm.repository.ScmRepository;
30  import org.apache.maven.scm.repository.ScmRepositoryException;
31  import org.apache.maven.shared.release.ReleaseExecutionException;
32  import org.apache.maven.shared.release.ReleaseFailureException;
33  import org.apache.maven.shared.release.ReleaseResult;
34  import org.apache.maven.shared.release.config.ReleaseDescriptor;
35  import org.apache.maven.shared.release.env.ReleaseEnvironment;
36  import org.apache.maven.shared.release.scm.ReleaseScmCommandException;
37  import org.apache.maven.shared.release.scm.ReleaseScmRepositoryException;
38  import org.apache.maven.shared.release.scm.ScmRepositoryConfigurator;
39  import org.apache.maven.shared.release.util.ReleaseUtil;
40  
41  import java.io.File;
42  import java.text.MessageFormat;
43  import java.util.ArrayList;
44  import java.util.Collection;
45  import java.util.List;
46  
47  /**
48   * Holds the basic concept of committing changes to the current working copy.
49   *
50   * @author <a href="mailto:brett@apache.org">Brett Porter</a>
51   * @author <a href="mailto:me@lcorneliussen.de">Lars Corneliussen</a>
52   */
53  public abstract class AbstractScmCommitPhase
54      extends AbstractReleasePhase
55  {
56      protected boolean beforeBranchOrTag = false;
57  
58      protected boolean afterBranchOrTag = false;
59  
60      /**
61       * Tool that gets a configured SCM repository from release configuration.
62       */
63      protected ScmRepositoryConfigurator scmRepositoryConfigurator;
64  
65      /**
66       * The format for the commit message.
67       */
68      protected String messageFormat;
69  
70      public ReleaseResult execute( ReleaseDescriptor releaseDescriptor, ReleaseEnvironment releaseEnvironment,
71                                    List<MavenProject> reactorProjects )
72          throws ReleaseExecutionException, ReleaseFailureException
73      {
74          ReleaseResult relResult = new ReleaseResult();
75  
76          validateConfiguration( releaseDescriptor );
77  
78          runLogic( releaseDescriptor, releaseEnvironment, reactorProjects, relResult, false );
79  
80          relResult.setResultCode( ReleaseResult.SUCCESS );
81  
82          return relResult;
83      }
84  
85      public ReleaseResult simulate( ReleaseDescriptor releaseDescriptor, ReleaseEnvironment releaseEnvironment,
86                                     List<MavenProject> reactorProjects )
87          throws ReleaseExecutionException, ReleaseFailureException
88      {
89          ReleaseResult result = new ReleaseResult();
90  
91          validateConfiguration( releaseDescriptor );
92  
93          runLogic( releaseDescriptor, releaseEnvironment, reactorProjects, result, true );
94  
95          result.setResultCode( ReleaseResult.SUCCESS );
96          return result;
97      }
98  
99      protected abstract void runLogic( ReleaseDescriptor releaseDescriptor, ReleaseEnvironment releaseEnvironment,
100                                       List<MavenProject> reactorProjects, ReleaseResult result, boolean simulating )
101         throws ReleaseScmCommandException, ReleaseExecutionException, ReleaseScmRepositoryException;
102 
103     protected void performCheckins( ReleaseDescriptor releaseDescriptor, ReleaseEnvironment releaseEnvironment,
104                                     List<MavenProject> reactorProjects, String message )
105         throws ReleaseScmRepositoryException, ReleaseExecutionException, ReleaseScmCommandException
106     {
107 
108         getLogger().info( "Checking in modified POMs..." );
109 
110         ScmRepository repository;
111         ScmProvider provider;
112         try
113         {
114             repository = scmRepositoryConfigurator.getConfiguredRepository( releaseDescriptor,
115                                                                             releaseEnvironment.getSettings() );
116 
117             repository.getProviderRepository().setPushChanges( releaseDescriptor.isPushChanges() );
118 
119             provider = scmRepositoryConfigurator.getRepositoryProvider( repository );
120         }
121         catch ( ScmRepositoryException e )
122         {
123             throw new ReleaseScmRepositoryException( e.getMessage(), e.getValidationMessages() );
124         }
125         catch ( NoSuchScmProviderException e )
126         {
127             throw new ReleaseExecutionException( "Unable to configure SCM repository: " + e.getMessage(), e );
128         }
129 
130         if ( releaseDescriptor.isCommitByProject() )
131         {
132             for ( MavenProject project : reactorProjects )
133             {
134                 List<File> pomFiles = createPomFiles( releaseDescriptor, project );
135                 ScmFileSet fileSet = new ScmFileSet( project.getFile().getParentFile(), pomFiles );
136 
137                 checkin( provider, repository, fileSet, releaseDescriptor, message );
138             }
139         }
140         else
141         {
142             List<File> pomFiles = createPomFiles( releaseDescriptor, reactorProjects );
143             ScmFileSet fileSet = new ScmFileSet( new File( releaseDescriptor.getWorkingDirectory() ), pomFiles );
144 
145             checkin( provider, repository, fileSet, releaseDescriptor, message );
146         }
147     }
148 
149     private void checkin( ScmProvider provider, ScmRepository repository, ScmFileSet fileSet,
150                           ReleaseDescriptor releaseDescriptor, String message )
151         throws ReleaseExecutionException, ReleaseScmCommandException
152     {
153         CheckInScmResult result;
154         try
155         {
156             result = provider.checkIn( repository, fileSet, (ScmVersion) null, message );
157         }
158         catch ( ScmException e )
159         {
160             throw new ReleaseExecutionException( "An error is occurred in the checkin process: " + e.getMessage(), e );
161         }
162 
163         if ( !result.isSuccess() )
164         {
165             throw new ReleaseScmCommandException( "Unable to commit files", result );
166         }
167         if ( releaseDescriptor.isRemoteTagging() )
168         {
169             releaseDescriptor.setScmReleasedPomRevision( result.getScmRevision() );
170         }
171     }
172 
173     protected void simulateCheckins( ReleaseDescriptor releaseDescriptor, List<MavenProject> reactorProjects,
174                                      ReleaseResult result, String message )
175     {
176         Collection<File> pomFiles = createPomFiles( releaseDescriptor, reactorProjects );
177         logInfo( result, "Full run would be commit " + pomFiles.size() + " files with message: '" + message + "'" );
178     }
179 
180     protected void validateConfiguration( ReleaseDescriptor releaseDescriptor )
181         throws ReleaseFailureException
182     {
183         if ( releaseDescriptor.getScmReleaseLabel() == null )
184         {
185             throw new ReleaseFailureException( "A release label is required for committing" );
186         }
187     }
188 
189     protected String createMessage( ReleaseDescriptor releaseDescriptor )
190     {
191         return MessageFormat.format( releaseDescriptor.getScmCommentPrefix() + messageFormat,
192                                      new Object[]{releaseDescriptor.getScmReleaseLabel()} );
193     }
194 
195     protected static List<File> createPomFiles( ReleaseDescriptor releaseDescriptor, MavenProject project )
196     {
197         List<File> pomFiles = new ArrayList<File>();
198 
199         pomFiles.add( ReleaseUtil.getStandardPom( project ) );
200 
201         if ( releaseDescriptor.isGenerateReleasePoms() && !releaseDescriptor.isSuppressCommitBeforeTagOrBranch() )
202         {
203             pomFiles.add( ReleaseUtil.getReleasePom( project ) );
204         }
205 
206         return pomFiles;
207     }
208 
209     protected static List<File> createPomFiles( ReleaseDescriptor releaseDescriptor,
210                                                 List<MavenProject> reactorProjects )
211     {
212         List<File> pomFiles = new ArrayList<File>();
213         for ( MavenProject project : reactorProjects )
214         {
215             pomFiles.addAll( createPomFiles( releaseDescriptor, project ) );
216         }
217         return pomFiles;
218     }
219 }