View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.shared.release.phase;
20  
21  import javax.inject.Inject;
22  import javax.inject.Named;
23  import javax.inject.Singleton;
24  
25  import java.io.IOException;
26  import java.nio.file.LinkOption;
27  import java.nio.file.Path;
28  import java.nio.file.Paths;
29  import java.util.Map;
30  
31  import org.apache.maven.artifact.ArtifactUtils;
32  import org.apache.maven.model.Model;
33  import org.apache.maven.model.Scm;
34  import org.apache.maven.project.MavenProject;
35  import org.apache.maven.scm.repository.ScmRepository;
36  import org.apache.maven.shared.release.ReleaseExecutionException;
37  import org.apache.maven.shared.release.ReleaseResult;
38  import org.apache.maven.shared.release.config.ReleaseDescriptor;
39  import org.apache.maven.shared.release.scm.ScmRepositoryConfigurator;
40  import org.apache.maven.shared.release.scm.ScmTranslator;
41  import org.apache.maven.shared.release.transform.ModelETLFactory;
42  import org.apache.maven.shared.release.util.ReleaseUtil;
43  
44  /**
45   * Rewrite POMs for branch.
46   *
47   * @author <a href="mailto:evenisse@apache.org">Emmanuel Venisse</a>
48   */
49  @Singleton
50  @Named("rewrite-poms-for-branch")
51  public class RewritePomsForBranchPhase extends AbstractRewritePomsPhase {
52      @Inject
53      public RewritePomsForBranchPhase(
54              ScmRepositoryConfigurator scmRepositoryConfigurator,
55              Map<String, ModelETLFactory> modelETLFactories,
56              Map<String, ScmTranslator> scmTranslators) {
57          super(scmRepositoryConfigurator, modelETLFactories, scmTranslators);
58      }
59  
60      @Override
61      protected final String getPomSuffix() {
62          return "branch";
63      }
64  
65      @Override
66      protected void transformScm(
67              MavenProject project,
68              Model modelTarget,
69              ReleaseDescriptor releaseDescriptor,
70              String projectId,
71              ScmRepository scmRepository,
72              ReleaseResult result)
73              throws ReleaseExecutionException {
74          // If SCM is null in original model, it is inherited, no mods needed
75          if (project.getScm() != null) {
76              Scm scmRoot = modelTarget.getScm();
77  
78              if (scmRoot != null) {
79                  try {
80                      translateScm(project, releaseDescriptor, scmRoot, scmRepository, result);
81                  } catch (IOException e) {
82                      throw new ReleaseExecutionException(e.getMessage(), e);
83                  }
84              } else {
85                  MavenProject parent = project.getParent();
86                  if (parent != null) {
87                      // If the SCM element is not present, only add it if the parent was not mapped (ie, it's external to
88                      // the release process and so has not been modified, so the values will not be correct on the tag),
89                      String parentId = ArtifactUtils.versionlessKey(parent.getGroupId(), parent.getArtifactId());
90                      if (!releaseDescriptor.hasOriginalScmInfo(parentId)) {
91                          // we need to add it, since it has changed from the inherited value
92                          scmRoot = new Scm();
93                          // reset default value (HEAD)
94                          scmRoot.setTag(null);
95  
96                          try {
97                              if (translateScm(project, releaseDescriptor, scmRoot, scmRepository, result)) {
98                                  modelTarget.setScm(scmRoot);
99                              }
100                         } catch (IOException e) {
101                             throw new ReleaseExecutionException(e.getMessage(), e);
102                         }
103                     }
104                 }
105             }
106         }
107     }
108 
109     private boolean translateScm(
110             MavenProject project,
111             ReleaseDescriptor releaseDescriptor,
112             Scm scmTarget,
113             ScmRepository scmRepository,
114             ReleaseResult relResult)
115             throws IOException {
116         ScmTranslator translator = getScmTranslators().get(scmRepository.getProvider());
117         boolean result = false;
118         if (translator != null) {
119             Scm scm = project.getOriginalModel().getScm();
120             if (scm == null) {
121                 scm = project.getScm();
122             }
123 
124             String branchName = releaseDescriptor.getScmReleaseLabel();
125             String branchBase = releaseDescriptor.getScmBranchBase();
126 
127             // TODO: svn utils should take care of prepending this
128             if (branchBase != null) {
129                 branchBase = "scm:svn:" + branchBase;
130             }
131 
132             Path projectBasedir = project.getBasedir().toPath().toRealPath(LinkOption.NOFOLLOW_LINKS);
133             Path workingDirectory = Paths.get(releaseDescriptor.getWorkingDirectory());
134 
135             int count = ReleaseUtil.getBaseWorkingDirectoryParentCount(workingDirectory, projectBasedir);
136 
137             if (scm.getConnection() != null) {
138                 String rootUrl = ReleaseUtil.realignScmUrl(count, scm.getConnection());
139 
140                 String subDirectoryBranch = scm.getConnection().substring(rootUrl.length());
141                 if (!subDirectoryBranch.startsWith("/")) {
142                     subDirectoryBranch = "/" + subDirectoryBranch;
143                 }
144 
145                 String scmConnectionBranch = branchBase;
146                 if (scmConnectionBranch != null) {
147                     String trunkUrl = scm.getDeveloperConnection();
148                     if (trunkUrl == null) {
149                         trunkUrl = scm.getConnection();
150                     }
151                     scmConnectionBranch = translateUrlPath(trunkUrl, branchBase, scm.getConnection());
152                 }
153 
154                 String value = translator.translateBranchUrl(
155                         scm.getConnection(), branchName + subDirectoryBranch, scmConnectionBranch);
156                 if (!value.equals(scm.getConnection())) {
157                     scmTarget.setConnection(value);
158                     result = true;
159                 }
160             }
161 
162             if (scm.getDeveloperConnection() != null) {
163                 String rootUrl = ReleaseUtil.realignScmUrl(count, scm.getDeveloperConnection());
164 
165                 String subDirectoryBranch = scm.getDeveloperConnection().substring(rootUrl.length());
166                 if (!subDirectoryBranch.startsWith("/")) {
167                     subDirectoryBranch = "/" + subDirectoryBranch;
168                 }
169 
170                 String value = translator.translateBranchUrl(
171                         scm.getDeveloperConnection(), branchName + subDirectoryBranch, branchBase);
172                 if (!value.equals(scm.getDeveloperConnection())) {
173                     scmTarget.setDeveloperConnection(value);
174                     result = true;
175                 }
176             }
177 
178             if (scm.getUrl() != null) {
179                 String rootUrl = ReleaseUtil.realignScmUrl(count, scm.getUrl());
180 
181                 String subDirectoryBranch = scm.getUrl().substring(rootUrl.length());
182                 if (!subDirectoryBranch.startsWith("/")) {
183                     subDirectoryBranch = "/" + subDirectoryBranch;
184                 }
185 
186                 String tagScmUrl = branchBase;
187                 if (tagScmUrl != null) {
188                     String trunkUrl = scm.getDeveloperConnection();
189                     if (trunkUrl == null) {
190                         trunkUrl = scm.getConnection();
191                     }
192                     tagScmUrl = translateUrlPath(trunkUrl, branchBase, scm.getUrl());
193                 }
194 
195                 // use original branch base without protocol
196                 String value = translator.translateBranchUrl(scm.getUrl(), branchName + subDirectoryBranch, tagScmUrl);
197                 if (!value.equals(scm.getUrl())) {
198                     scmTarget.setUrl(value);
199                     result = true;
200                 }
201             }
202 
203             if (branchName != null) {
204                 String value = translator.resolveTag(branchName);
205                 if (value != null && !value.equals(scm.getTag())) {
206                     scmTarget.setTag(value);
207                     result = true;
208                 }
209             }
210         } else {
211             String message = "No SCM translator found - skipping rewrite";
212 
213             relResult.appendDebug(message);
214 
215             getLogger().debug(message);
216         }
217         return result;
218     }
219 
220     @Override
221     protected String getOriginalVersion(ReleaseDescriptor releaseDescriptor, String projectKey, boolean simulate) {
222         return releaseDescriptor.getProjectOriginalVersion(projectKey);
223     }
224 
225     @Override
226     protected String getNextVersion(ReleaseDescriptor releaseDescriptor, String key) {
227         return releaseDescriptor.getProjectReleaseVersion(key);
228     }
229 
230     @Override
231     protected String getResolvedSnapshotVersion(String artifactVersionlessKey, ReleaseDescriptor releaseDescriptor) {
232         return releaseDescriptor.getDependencyReleaseVersion(artifactVersionlessKey);
233     }
234 }