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 java.io.IOException;
23  import java.nio.file.LinkOption;
24  import java.nio.file.Path;
25  import java.nio.file.Paths;
26  
27  import org.apache.maven.artifact.ArtifactUtils;
28  import org.apache.maven.model.Model;
29  import org.apache.maven.model.Scm;
30  import org.apache.maven.project.MavenProject;
31  import org.apache.maven.scm.repository.ScmRepository;
32  import org.apache.maven.shared.release.ReleaseExecutionException;
33  import org.apache.maven.shared.release.ReleaseResult;
34  import org.apache.maven.shared.release.config.ReleaseDescriptor;
35  import org.apache.maven.shared.release.scm.ScmTranslator;
36  import org.apache.maven.shared.release.util.ReleaseUtil;
37  import org.codehaus.plexus.component.annotations.Component;
38  
39  /**
40   * Rewrite POMs for release.
41   *
42   * @author <a href="mailto:brett@apache.org">Brett Porter</a>
43   */
44  @Component( role = ReleasePhase.class, hint = "rewrite-poms-for-release" )
45  public class RewritePomsForReleasePhase
46      extends AbstractRewritePomsPhase
47  {
48      @Override
49      protected final String getPomSuffix()
50      {
51          return "tag";
52      }
53  
54      @Override
55      protected void transformScm( MavenProject project, Model modelTarget, ReleaseDescriptor releaseDescriptor,
56                                   String projectId, ScmRepository scmRepository, ReleaseResult result )
57      throws ReleaseExecutionException
58      {
59          // If SCM is null in original model, it is inherited, no mods needed
60          if ( project.getScm() != null )
61          {
62              Scm scmRoot = modelTarget.getScm();
63              if ( scmRoot != null )
64              {
65                  try
66                  {
67                      translateScm( project, releaseDescriptor, scmRoot, scmRepository, result );
68                  }
69                  catch ( IOException e )
70                  {
71                      throw new ReleaseExecutionException( e.getMessage(), e );
72                  }
73              }
74              else
75              {
76                  MavenProject parent = project.getParent();
77                  if ( parent != null )
78                  {
79                      // If the SCM element is not present, only add it if the parent was not mapped (ie, it's external to
80                      // the release process and so has not been modified, so the values will not be correct on the tag),
81                      String parentId = ArtifactUtils.versionlessKey( parent.getGroupId(), parent.getArtifactId() );
82                      if ( releaseDescriptor.getOriginalScmInfo( parentId ) == null )
83                      {
84                          // we need to add it, since it has changed from the inherited value
85                          Scm scmTarget = new Scm();
86                          // reset default value (HEAD)
87                          scmTarget.setTag( null );
88  
89                          try
90                          {
91                              if ( translateScm( project, releaseDescriptor, scmTarget, scmRepository, result ) )
92                              {
93                                  modelTarget.setScm( scmTarget );
94                              }
95                          }
96                          catch ( IOException e )
97                          {
98                              throw new ReleaseExecutionException( e.getMessage(), e );
99                          }
100                     }
101                 }
102             }
103         }
104     }
105 
106     private boolean translateScm( MavenProject project, ReleaseDescriptor releaseDescriptor, Scm scmTarget,
107                                   ScmRepository scmRepository, ReleaseResult relResult )
108         throws IOException
109     {
110         ScmTranslator translator = getScmTranslators().get( scmRepository.getProvider() );
111         boolean result = false;
112         if ( translator != null )
113         {
114             Scm scm = project.getOriginalModel().getScm();
115             if ( scm == null )
116             {
117                 scm = project.getScm();
118             }
119 
120             String tag = releaseDescriptor.getScmReleaseLabel();
121             String tagBase = releaseDescriptor.getScmTagBase();
122 
123             // TODO: svn utils should take care of prepending this
124             if ( tagBase != null )
125             {
126                 tagBase = "scm:svn:" + tagBase;
127             }
128 
129             Path projectBasedir = project.getBasedir().toPath().toRealPath( LinkOption.NOFOLLOW_LINKS );
130             Path workingDirectory = Paths.get( releaseDescriptor.getWorkingDirectory() );
131 
132             int count = ReleaseUtil.getBaseWorkingDirectoryParentCount( workingDirectory, projectBasedir );
133             
134             if ( scm.getConnection() != null )
135             {
136                 String rootUrl = ReleaseUtil.realignScmUrl( count, scm.getConnection() );
137 
138                 String subDirectoryTag = scm.getConnection().substring( rootUrl.length() );
139                 if ( !subDirectoryTag.startsWith( "/" ) )
140                 {
141                     subDirectoryTag = "/" + subDirectoryTag;
142                 }
143 
144                 String scmConnectionTag = tagBase;
145                 if ( scmConnectionTag != null )
146                 {
147                     String trunkUrl = scm.getDeveloperConnection();
148                     if ( trunkUrl == null )
149                     {
150                         trunkUrl = scm.getConnection();
151                     }
152                     scmConnectionTag = translateUrlPath( trunkUrl, tagBase, scm.getConnection() );
153                 }
154                 String value =
155                     translator.translateTagUrl( scm.getConnection(), tag + subDirectoryTag, scmConnectionTag );
156 
157                 if ( !value.equals( scm.getConnection() ) )
158                 {
159                     scmTarget.setConnection( value );
160                     result = true;
161                 }
162             }
163 
164             if ( scm.getDeveloperConnection() != null )
165             {
166                 String rootUrl = ReleaseUtil.realignScmUrl( count, scm.getDeveloperConnection() );
167 
168                 String subDirectoryTag = scm.getDeveloperConnection().substring( rootUrl.length() );
169                 if ( !subDirectoryTag.startsWith( "/" ) )
170                 {
171                     subDirectoryTag = "/" + subDirectoryTag;
172                 }
173 
174                 String value =
175                     translator.translateTagUrl( scm.getDeveloperConnection(), tag + subDirectoryTag, tagBase );
176 
177                 if ( !value.equals( scm.getDeveloperConnection() ) )
178                 {
179                     scmTarget.setDeveloperConnection( value );
180                     result = true;
181                 }
182             }
183 
184             if ( scm.getUrl() != null )
185             {
186                 String rootUrl = ReleaseUtil.realignScmUrl( count, scm.getUrl() );
187 
188                 String subDirectoryTag = scm.getUrl().substring( rootUrl.length() );
189                 if ( !subDirectoryTag.startsWith( "/" ) )
190                 {
191                     subDirectoryTag = "/" + subDirectoryTag;
192                 }
193 
194                 String tagScmUrl = tagBase;
195                 if ( tagScmUrl != null )
196                 {
197                     String trunkUrl = scm.getDeveloperConnection();
198                     if ( trunkUrl == null )
199                     {
200                         trunkUrl = scm.getConnection();
201                     }
202                     tagScmUrl = translateUrlPath( trunkUrl, tagBase, scm.getUrl() );
203                 }
204                 // use original tag base without protocol
205                 String value = translator.translateTagUrl( scm.getUrl(), tag + subDirectoryTag, tagScmUrl );
206                 if ( !value.equals( scm.getUrl() ) )
207                 {
208                     scmTarget.setUrl( value );
209                     result = true;
210                 }
211             }
212 
213             if ( tag != null )
214             {
215                 String value = translator.resolveTag( tag );
216                 if ( value != null && !value.equals( scm.getTag() ) )
217                 {
218                     scmTarget.setTag( value );
219                     result = true;
220                 }
221             }
222         }
223         else
224         {
225             String message = "No SCM translator found - skipping rewrite";
226 
227             relResult.appendDebug( message );
228 
229             getLogger().debug( message );
230         }
231         return result;
232     }
233 
234     @Override
235     protected String getOriginalVersion( ReleaseDescriptor releaseDescriptor, String projectKey, boolean simulate )
236     {
237         return releaseDescriptor.getProjectOriginalVersion( projectKey );
238     }
239 
240     @Override
241     protected String getNextVersion( ReleaseDescriptor releaseDescriptor, String key )
242     {
243         return releaseDescriptor.getProjectReleaseVersion( key );
244     }
245 
246     @Override
247     protected String getResolvedSnapshotVersion( String artifactVersionlessKey,
248                                                  ReleaseDescriptor releaseDescriptor )
249     {
250         return releaseDescriptor.getDependencyReleaseVersion( artifactVersionlessKey );
251     }
252 }