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