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.util.ArrayList;
43  import java.util.Collection;
44  import java.util.List;
45  
46  /**
47   * Holds the basic concept of committing changes to the current working copy.
48   *
49   * @author <a href="mailto:brett@apache.org">Brett Porter</a>
50   * @author <a href="mailto:me@lcorneliussen.de">Lars Corneliussen</a>
51   */
52  public abstract class AbstractScmCommitPhase
53      extends AbstractReleasePhase
54  {
55      protected boolean beforeBranchOrTag = false;
56  
57      protected boolean afterBranchOrTag = false;
58  
59      /**
60       * Tool that gets a configured SCM repository from release configuration.
61       */
62      protected ScmRepositoryConfigurator scmRepositoryConfigurator;
63  
64      /**
65       * The getter in the descriptor for the comment.
66       */
67      protected String descriptorCommentGetter;
68  
69      @Override
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      @Override
86      public ReleaseResult simulate( ReleaseDescriptor releaseDescriptor, ReleaseEnvironment releaseEnvironment,
87                                     List<MavenProject> reactorProjects )
88          throws ReleaseExecutionException, ReleaseFailureException
89      {
90          ReleaseResult result = new ReleaseResult();
91  
92          validateConfiguration( releaseDescriptor );
93  
94          runLogic( releaseDescriptor, releaseEnvironment, reactorProjects, result, true );
95  
96          result.setResultCode( ReleaseResult.SUCCESS );
97          return result;
98      }
99  
100     /**
101      * <p>runLogic.</p>
102      *
103      * @param releaseDescriptor a {@link org.apache.maven.shared.release.config.ReleaseDescriptor} object
104      * @param releaseEnvironment a {@link org.apache.maven.shared.release.env.ReleaseEnvironment} object
105      * @param reactorProjects a {@link java.util.List} object
106      * @param result a {@link org.apache.maven.shared.release.ReleaseResult} object
107      * @param simulating a boolean
108      * @throws org.apache.maven.shared.release.scm.ReleaseScmCommandException if any.
109      * @throws org.apache.maven.shared.release.ReleaseExecutionException if any.
110      * @throws org.apache.maven.shared.release.scm.ReleaseScmRepositoryException if any.
111      */
112     protected abstract void runLogic( ReleaseDescriptor releaseDescriptor, ReleaseEnvironment releaseEnvironment,
113                                       List<MavenProject> reactorProjects, ReleaseResult result, boolean simulating )
114         throws ReleaseScmCommandException, ReleaseExecutionException, ReleaseScmRepositoryException;
115 
116     /**
117      * <p>performCheckins.</p>
118      *
119      * @param releaseDescriptor a {@link org.apache.maven.shared.release.config.ReleaseDescriptor} object
120      * @param releaseEnvironment a {@link org.apache.maven.shared.release.env.ReleaseEnvironment} object
121      * @param reactorProjects a {@link java.util.List} object
122      * @param message a {@link java.lang.String} object
123      * @throws org.apache.maven.shared.release.scm.ReleaseScmRepositoryException if any.
124      * @throws org.apache.maven.shared.release.ReleaseExecutionException if any.
125      * @throws org.apache.maven.shared.release.scm.ReleaseScmCommandException if any.
126      */
127     protected void performCheckins( ReleaseDescriptor releaseDescriptor, ReleaseEnvironment releaseEnvironment,
128                                     List<MavenProject> reactorProjects, String message )
129         throws ReleaseScmRepositoryException, ReleaseExecutionException, ReleaseScmCommandException
130     {
131 
132         getLogger().info( "Checking in modified POMs..." );
133 
134         ScmRepository repository;
135         ScmProvider provider;
136         try
137         {
138             repository = scmRepositoryConfigurator.getConfiguredRepository( releaseDescriptor,
139                                                                             releaseEnvironment.getSettings() );
140 
141             repository.getProviderRepository().setPushChanges( releaseDescriptor.isPushChanges() );
142 
143             repository.getProviderRepository().setWorkItem( releaseDescriptor.getWorkItem() );
144 
145             provider = scmRepositoryConfigurator.getRepositoryProvider( repository );
146         }
147         catch ( ScmRepositoryException e )
148         {
149             throw new ReleaseScmRepositoryException( e.getMessage(), e.getValidationMessages() );
150         }
151         catch ( NoSuchScmProviderException e )
152         {
153             throw new ReleaseExecutionException( "Unable to configure SCM repository: " + e.getMessage(), e );
154         }
155 
156         if ( releaseDescriptor.isCommitByProject() )
157         {
158             for ( MavenProject project : reactorProjects )
159             {
160                 List<File> pomFiles = createPomFiles( releaseDescriptor, project );
161                 ScmFileSet fileSet = new ScmFileSet( project.getFile().getParentFile(), pomFiles );
162 
163                 checkin( provider, repository, fileSet, releaseDescriptor, message );
164             }
165         }
166         else
167         {
168             List<File> pomFiles = createPomFiles( releaseDescriptor, reactorProjects );
169             ScmFileSet fileSet = new ScmFileSet( new File( releaseDescriptor.getWorkingDirectory() ), pomFiles );
170 
171             checkin( provider, repository, fileSet, releaseDescriptor, message );
172         }
173     }
174 
175     private void checkin( ScmProvider provider, ScmRepository repository, ScmFileSet fileSet,
176                           ReleaseDescriptor releaseDescriptor, String message )
177         throws ReleaseExecutionException, ReleaseScmCommandException
178     {
179         CheckInScmResult result;
180         try
181         {
182             result = provider.checkIn( repository, fileSet, (ScmVersion) null, message );
183         }
184         catch ( ScmException e )
185         {
186             throw new ReleaseExecutionException( "An error is occurred in the checkin process: " + e.getMessage(), e );
187         }
188 
189         if ( !result.isSuccess() )
190         {
191             throw new ReleaseScmCommandException( "Unable to commit files", result );
192         }
193         if ( releaseDescriptor.isRemoteTagging() )
194         {
195             releaseDescriptor.setScmReleasedPomRevision( result.getScmRevision() );
196         }
197     }
198 
199     /**
200      * <p>simulateCheckins.</p>
201      *
202      * @param releaseDescriptor a {@link org.apache.maven.shared.release.config.ReleaseDescriptor} object
203      * @param reactorProjects a {@link java.util.List} object
204      * @param result a {@link org.apache.maven.shared.release.ReleaseResult} object
205      * @param message a {@link java.lang.String} object
206      */
207     protected void simulateCheckins( ReleaseDescriptor releaseDescriptor, List<MavenProject> reactorProjects,
208                                      ReleaseResult result, String message )
209     {
210         Collection<File> pomFiles = createPomFiles( releaseDescriptor, reactorProjects );
211         logInfo( result, "Full run would be commit " + pomFiles.size() + " files with message: '" + message + "'" );
212     }
213 
214     /**
215      * <p>validateConfiguration.</p>
216      *
217      * @param releaseDescriptor a {@link org.apache.maven.shared.release.config.ReleaseDescriptor} object
218      * @throws org.apache.maven.shared.release.ReleaseFailureException if any.
219      */
220     protected void validateConfiguration( ReleaseDescriptor releaseDescriptor )
221         throws ReleaseFailureException
222     {
223         if ( releaseDescriptor.getScmReleaseLabel() == null )
224         {
225             throw new ReleaseFailureException( "A release label is required for committing" );
226         }
227     }
228 
229     /**
230      * <p>createMessage.</p>
231      *
232      * @param reactorProjects a {@link java.util.List} object
233      * @param releaseDescriptor a {@link org.apache.maven.shared.release.config.ReleaseDescriptor} object
234      * @return a {@link java.lang.String} object
235      * @throws org.apache.maven.shared.release.ReleaseExecutionException if any.
236      */
237     protected String createMessage( List<MavenProject> reactorProjects,
238                                     ReleaseDescriptor releaseDescriptor )
239                                     throws ReleaseExecutionException
240     {
241         String comment;
242         boolean branch = false;
243         if ( "getScmReleaseCommitComment".equals( descriptorCommentGetter ) )
244         {
245             comment = releaseDescriptor.getScmReleaseCommitComment();
246         }
247         else if ( "getScmDevelopmentCommitComment".equals( descriptorCommentGetter ) )
248         {
249             comment = releaseDescriptor.getScmDevelopmentCommitComment();
250         }
251         else if ( "getScmBranchCommitComment".equals( descriptorCommentGetter ) )
252         {
253             comment = releaseDescriptor.getScmBranchCommitComment();
254             branch = true;
255         }
256         else if ( "getScmRollbackCommitComment".equals( descriptorCommentGetter ) )
257         {
258             comment = releaseDescriptor.getScmRollbackCommitComment();
259         }
260         else
261         {
262             throw new ReleaseExecutionException( "Invalid configuration in components-fragment.xml" );
263         }
264         
265         MavenProject project = ReleaseUtil.getRootProject( reactorProjects );
266         comment = comment.replace( "@{prefix}", releaseDescriptor.getScmCommentPrefix().trim() );
267         comment = comment.replace( "@{groupId}", project.getGroupId() );
268         comment = comment.replace( "@{artifactId}", project.getArtifactId() );
269         if ( branch )
270         {
271             comment = comment.replace( "@{branchName}", releaseDescriptor.getScmReleaseLabel() );
272         }
273         else
274         {
275             comment = comment.replace( "@{releaseLabel}", releaseDescriptor.getScmReleaseLabel() );
276         }
277         return comment;
278     }
279 
280     /**
281      * <p>createPomFiles.</p>
282      *
283      * @param releaseDescriptor a {@link org.apache.maven.shared.release.config.ReleaseDescriptor} object
284      * @param project a {@link org.apache.maven.project.MavenProject} object
285      * @return a {@link java.util.List} object
286      */
287     protected static List<File> createPomFiles( ReleaseDescriptor releaseDescriptor, MavenProject project )
288     {
289         List<File> pomFiles = new ArrayList<>();
290 
291         pomFiles.add( ReleaseUtil.getStandardPom( project ) );
292 
293         if ( releaseDescriptor.isGenerateReleasePoms() && !releaseDescriptor.isSuppressCommitBeforeTagOrBranch() )
294         {
295             pomFiles.add( ReleaseUtil.getReleasePom( project ) );
296         }
297 
298         return pomFiles;
299     }
300 
301     /**
302      * <p>createPomFiles.</p>
303      *
304      * @param releaseDescriptor a {@link org.apache.maven.shared.release.config.ReleaseDescriptor} object
305      * @param reactorProjects a {@link java.util.List} object
306      * @return a {@link java.util.List} object
307      */
308     protected static List<File> createPomFiles( ReleaseDescriptor releaseDescriptor,
309                                                 List<MavenProject> reactorProjects )
310     {
311         List<File> pomFiles = new ArrayList<>();
312         for ( MavenProject project : reactorProjects )
313         {
314             pomFiles.addAll( createPomFiles( releaseDescriptor, project ) );
315         }
316         return pomFiles;
317     }
318 }