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     protected abstract void runLogic( ReleaseDescriptor releaseDescriptor, ReleaseEnvironment releaseEnvironment,
101                                       List<MavenProject> reactorProjects, ReleaseResult result, boolean simulating )
102         throws ReleaseScmCommandException, ReleaseExecutionException, ReleaseScmRepositoryException;
103 
104     protected void performCheckins( ReleaseDescriptor releaseDescriptor, ReleaseEnvironment releaseEnvironment,
105                                     List<MavenProject> reactorProjects, String message )
106         throws ReleaseScmRepositoryException, ReleaseExecutionException, ReleaseScmCommandException
107     {
108 
109         getLogger().info( "Checking in modified POMs..." );
110 
111         ScmRepository repository;
112         ScmProvider provider;
113         try
114         {
115             repository = scmRepositoryConfigurator.getConfiguredRepository( releaseDescriptor,
116                                                                             releaseEnvironment.getSettings() );
117 
118             repository.getProviderRepository().setPushChanges( releaseDescriptor.isPushChanges() );
119 
120             repository.getProviderRepository().setWorkItem( releaseDescriptor.getWorkItem() );
121 
122             provider = scmRepositoryConfigurator.getRepositoryProvider( repository );
123         }
124         catch ( ScmRepositoryException e )
125         {
126             throw new ReleaseScmRepositoryException( e.getMessage(), e.getValidationMessages() );
127         }
128         catch ( NoSuchScmProviderException e )
129         {
130             throw new ReleaseExecutionException( "Unable to configure SCM repository: " + e.getMessage(), e );
131         }
132 
133         if ( releaseDescriptor.isCommitByProject() )
134         {
135             for ( MavenProject project : reactorProjects )
136             {
137                 List<File> pomFiles = createPomFiles( releaseDescriptor, project );
138                 ScmFileSet fileSet = new ScmFileSet( project.getFile().getParentFile(), pomFiles );
139 
140                 checkin( provider, repository, fileSet, releaseDescriptor, message );
141             }
142         }
143         else
144         {
145             List<File> pomFiles = createPomFiles( releaseDescriptor, reactorProjects );
146             ScmFileSet fileSet = new ScmFileSet( new File( releaseDescriptor.getWorkingDirectory() ), pomFiles );
147 
148             checkin( provider, repository, fileSet, releaseDescriptor, message );
149         }
150     }
151 
152     private void checkin( ScmProvider provider, ScmRepository repository, ScmFileSet fileSet,
153                           ReleaseDescriptor releaseDescriptor, String message )
154         throws ReleaseExecutionException, ReleaseScmCommandException
155     {
156         CheckInScmResult result;
157         try
158         {
159             result = provider.checkIn( repository, fileSet, (ScmVersion) null, message );
160         }
161         catch ( ScmException e )
162         {
163             throw new ReleaseExecutionException( "An error is occurred in the checkin process: " + e.getMessage(), e );
164         }
165 
166         if ( !result.isSuccess() )
167         {
168             throw new ReleaseScmCommandException( "Unable to commit files", result );
169         }
170         if ( releaseDescriptor.isRemoteTagging() )
171         {
172             releaseDescriptor.setScmReleasedPomRevision( result.getScmRevision() );
173         }
174     }
175 
176     protected void simulateCheckins( ReleaseDescriptor releaseDescriptor, List<MavenProject> reactorProjects,
177                                      ReleaseResult result, String message )
178     {
179         Collection<File> pomFiles = createPomFiles( releaseDescriptor, reactorProjects );
180         logInfo( result, "Full run would be commit " + pomFiles.size() + " files with message: '" + message + "'" );
181     }
182 
183     protected void validateConfiguration( ReleaseDescriptor releaseDescriptor )
184         throws ReleaseFailureException
185     {
186         if ( releaseDescriptor.getScmReleaseLabel() == null )
187         {
188             throw new ReleaseFailureException( "A release label is required for committing" );
189         }
190     }
191 
192     protected String createMessage( List<MavenProject> reactorProjects,
193                                     ReleaseDescriptor releaseDescriptor )
194                                     throws ReleaseExecutionException
195     {
196         String comment;
197         boolean branch = false;
198         if ( "getScmReleaseCommitComment".equals( descriptorCommentGetter ) )
199         {
200             comment = releaseDescriptor.getScmReleaseCommitComment();
201         }
202         else if ( "getScmDevelopmentCommitComment".equals( descriptorCommentGetter ) )
203         {
204             comment = releaseDescriptor.getScmDevelopmentCommitComment();
205         }
206         else if ( "getScmBranchCommitComment".equals( descriptorCommentGetter ) )
207         {
208             comment = releaseDescriptor.getScmBranchCommitComment();
209             branch = true;
210         }
211         else if ( "getScmRollbackCommitComment".equals( descriptorCommentGetter ) )
212         {
213             comment = releaseDescriptor.getScmRollbackCommitComment();
214         }
215         else
216         {
217             throw new ReleaseExecutionException( "Invalid configuration in components-fragment.xml" );
218         }
219         
220         MavenProject project = ReleaseUtil.getRootProject( reactorProjects );
221         comment = comment.replace( "@{prefix}", releaseDescriptor.getScmCommentPrefix().trim() );
222         comment = comment.replace( "@{groupId}", project.getGroupId() );
223         comment = comment.replace( "@{artifactId}", project.getArtifactId() );
224         if ( branch )
225         {
226             comment = comment.replace( "@{branchName}", releaseDescriptor.getScmReleaseLabel() );
227         }
228         else
229         {
230             comment = comment.replace( "@{releaseLabel}", releaseDescriptor.getScmReleaseLabel() );
231         }
232         return comment;
233     }
234 
235     protected static List<File> createPomFiles( ReleaseDescriptor releaseDescriptor, MavenProject project )
236     {
237         List<File> pomFiles = new ArrayList<>();
238 
239         pomFiles.add( ReleaseUtil.getStandardPom( project ) );
240 
241         if ( releaseDescriptor.isGenerateReleasePoms() && !releaseDescriptor.isSuppressCommitBeforeTagOrBranch() )
242         {
243             pomFiles.add( ReleaseUtil.getReleasePom( project ) );
244         }
245 
246         return pomFiles;
247     }
248 
249     protected static List<File> createPomFiles( ReleaseDescriptor releaseDescriptor,
250                                                 List<MavenProject> reactorProjects )
251     {
252         List<File> pomFiles = new ArrayList<>();
253         for ( MavenProject project : reactorProjects )
254         {
255             pomFiles.addAll( createPomFiles( releaseDescriptor, project ) );
256         }
257         return pomFiles;
258     }
259 }