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