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