1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.shared.release.phase;
20
21 import java.util.List;
22 import java.util.Map;
23
24 import org.apache.maven.artifact.ArtifactUtils;
25 import org.apache.maven.project.MavenProject;
26 import org.apache.maven.scm.manager.NoSuchScmProviderException;
27 import org.apache.maven.scm.provider.ScmProvider;
28 import org.apache.maven.scm.repository.ScmRepository;
29 import org.apache.maven.scm.repository.ScmRepositoryException;
30 import org.apache.maven.shared.release.ReleaseExecutionException;
31 import org.apache.maven.shared.release.ReleaseResult;
32 import org.apache.maven.shared.release.config.ReleaseDescriptor;
33 import org.apache.maven.shared.release.env.ReleaseEnvironment;
34 import org.apache.maven.shared.release.policy.PolicyException;
35 import org.apache.maven.shared.release.policy.version.VersionPolicy;
36 import org.apache.maven.shared.release.policy.version.VersionPolicyRequest;
37 import org.apache.maven.shared.release.scm.ScmRepositoryConfigurator;
38 import org.apache.maven.shared.release.util.ReleaseUtil;
39 import org.apache.maven.shared.release.versions.VersionParseException;
40 import org.codehaus.plexus.components.interactivity.Prompter;
41 import org.codehaus.plexus.components.interactivity.PrompterException;
42 import org.slf4j.Logger;
43
44 import static java.util.Objects.requireNonNull;
45 import static org.apache.maven.shared.utils.logging.MessageUtils.buffer;
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74 public abstract class AbstractMapVersionsPhase extends AbstractReleasePhase {
75
76
77
78 private final ScmRepositoryConfigurator scmRepositoryConfigurator;
79
80
81
82
83 private final Prompter prompter;
84
85
86
87
88 private final Map<String, VersionPolicy> versionPolicies;
89
90
91
92
93 private final boolean convertToSnapshot;
94
95
96
97
98 private final boolean convertToBranch;
99
100 public AbstractMapVersionsPhase(
101 ScmRepositoryConfigurator scmRepositoryConfigurator,
102 Prompter prompter,
103 Map<String, VersionPolicy> versionPolicies,
104 boolean convertToSnapshot,
105 boolean convertToBranch) {
106 this.scmRepositoryConfigurator = requireNonNull(scmRepositoryConfigurator);
107 this.prompter = requireNonNull(prompter);
108 this.versionPolicies = requireNonNull(versionPolicies);
109 this.convertToSnapshot = convertToSnapshot;
110 this.convertToBranch = convertToBranch;
111 }
112
113 @Override
114 public ReleaseResult execute(
115 ReleaseDescriptor releaseDescriptor,
116 ReleaseEnvironment releaseEnvironment,
117 List<MavenProject> reactorProjects)
118 throws ReleaseExecutionException {
119 ReleaseResult result = new ReleaseResult();
120
121 MavenProject rootProject = ReleaseUtil.getRootProject(reactorProjects);
122
123 if (releaseDescriptor.isAutoVersionSubmodules() && ArtifactUtils.isSnapshot(rootProject.getVersion())) {
124
125 MavenProject project = rootProject;
126
127 String projectId = ArtifactUtils.versionlessKey(project.getGroupId(), project.getArtifactId());
128
129 String nextVersion = resolveNextVersion(project, projectId, releaseDescriptor, releaseEnvironment);
130
131 if (!convertToSnapshot) {
132 releaseDescriptor.addReleaseVersion(projectId, nextVersion);
133 } else if (releaseDescriptor.isBranchCreation() && convertToBranch) {
134 releaseDescriptor.addReleaseVersion(projectId, nextVersion);
135 } else {
136 releaseDescriptor.addDevelopmentVersion(projectId, nextVersion);
137 }
138
139 for (MavenProject subProject : reactorProjects) {
140 String subProjectId = ArtifactUtils.versionlessKey(subProject.getGroupId(), subProject.getArtifactId());
141
142 if (convertToSnapshot) {
143 String subProjectNextVersion = releaseDescriptor.getProjectDevelopmentVersion(subProjectId);
144 String v;
145 if (subProjectNextVersion != null) {
146 v = subProjectNextVersion;
147 } else if (ArtifactUtils.isSnapshot(subProject.getVersion())) {
148 v = nextVersion;
149 } else {
150 v = subProject.getVersion();
151 }
152
153 if (releaseDescriptor.isBranchCreation() && convertToBranch) {
154 releaseDescriptor.addReleaseVersion(subProjectId, v);
155 } else {
156 releaseDescriptor.addDevelopmentVersion(subProjectId, v);
157 }
158 } else {
159 String subProjectNextVersion = releaseDescriptor.getProjectReleaseVersion(subProjectId);
160 if (subProjectNextVersion != null) {
161 releaseDescriptor.addReleaseVersion(subProjectId, subProjectNextVersion);
162 } else {
163 releaseDescriptor.addReleaseVersion(subProjectId, nextVersion);
164 }
165 }
166 }
167 } else {
168 for (MavenProject project : reactorProjects) {
169 String projectId = ArtifactUtils.versionlessKey(project.getGroupId(), project.getArtifactId());
170
171 String nextVersion = resolveNextVersion(project, projectId, releaseDescriptor, releaseEnvironment);
172
173 if (!convertToSnapshot) {
174 releaseDescriptor.addReleaseVersion(projectId, nextVersion);
175 } else if (releaseDescriptor.isBranchCreation() && convertToBranch) {
176 releaseDescriptor.addReleaseVersion(projectId, nextVersion);
177 } else {
178 releaseDescriptor.addDevelopmentVersion(projectId, nextVersion);
179 }
180 }
181 }
182
183 result.setResultCode(ReleaseResult.SUCCESS);
184
185 return result;
186 }
187
188 private String resolveNextVersion(
189 MavenProject project,
190 String projectId,
191 ReleaseDescriptor releaseDescriptor,
192 ReleaseEnvironment releaseEnvironment)
193 throws ReleaseExecutionException {
194 String defaultVersion;
195 if (convertToBranch) {
196
197 if (!(releaseDescriptor.isUpdateBranchVersions()
198 && (ArtifactUtils.isSnapshot(project.getVersion())
199 || releaseDescriptor.isUpdateVersionsToSnapshot()))) {
200 return project.getVersion();
201 }
202
203 defaultVersion = getReleaseVersion(projectId, releaseDescriptor);
204 } else if (!convertToSnapshot)
205 {
206 defaultVersion = getReleaseVersion(projectId, releaseDescriptor);
207 } else if (releaseDescriptor.isBranchCreation()) {
208
209 if (!(ArtifactUtils.isSnapshot(project.getVersion()) && releaseDescriptor.isUpdateWorkingCopyVersions())) {
210 return project.getVersion();
211 }
212
213 defaultVersion = getDevelopmentVersion(projectId, releaseDescriptor);
214 } else {
215
216 if (!(releaseDescriptor.isUpdateWorkingCopyVersions())) {
217 return project.getVersion();
218 }
219
220 defaultVersion = getDevelopmentVersion(projectId, releaseDescriptor);
221 }
222
223
224 String suggestedVersion = null;
225 String nextVersion = defaultVersion;
226 String messageFormat = null;
227 try {
228 while (nextVersion == null || ArtifactUtils.isSnapshot(nextVersion) != convertToSnapshot) {
229 if (suggestedVersion == null) {
230 String baseVersion = null;
231 if (convertToSnapshot) {
232 baseVersion = getReleaseVersion(projectId, releaseDescriptor);
233 }
234
235 if (baseVersion == null) {
236 baseVersion = project.getVersion();
237 }
238
239 try {
240 try {
241 suggestedVersion =
242 resolveSuggestedVersion(baseVersion, releaseDescriptor, releaseEnvironment);
243 } catch (VersionParseException e) {
244 if (releaseDescriptor.isInteractive()) {
245 suggestedVersion =
246 resolveSuggestedVersion("1.0", releaseDescriptor, releaseEnvironment);
247 } else {
248 throw new ReleaseExecutionException(
249 "Error parsing version, cannot determine next " + "version: " + e.getMessage(),
250 e);
251 }
252 }
253 } catch (PolicyException | VersionParseException e) {
254 throw new ReleaseExecutionException(e.getMessage(), e);
255 }
256 }
257
258 if (releaseDescriptor.isInteractive()) {
259 if (messageFormat == null) {
260 messageFormat = "What is the " + getContextString(releaseDescriptor) + " version for \"%s\"? ("
261 + buffer().project("%s") + ")";
262 }
263 String message = String.format(messageFormat, project.getName(), project.getArtifactId());
264 nextVersion = prompter.prompt(message, suggestedVersion);
265
266
267 } else if (defaultVersion == null) {
268 nextVersion = suggestedVersion;
269 } else if (convertToSnapshot) {
270 throw new ReleaseExecutionException(defaultVersion + " is invalid, expected a snapshot");
271 } else {
272 throw new ReleaseExecutionException(defaultVersion + " is invalid, expected a non-snapshot");
273 }
274 }
275 } catch (PrompterException e) {
276 throw new ReleaseExecutionException("Error reading version from input handler: " + e.getMessage(), e);
277 }
278 return nextVersion;
279 }
280
281 private String getContextString(ReleaseDescriptor releaseDescriptor) {
282 if (convertToBranch) {
283 return "branch";
284 }
285 if (!convertToSnapshot) {
286 return "release";
287 }
288 if (releaseDescriptor.isBranchCreation()) {
289 return "new working copy";
290 }
291 return "new development";
292 }
293
294 private String resolveSuggestedVersion(
295 String baseVersion, ReleaseDescriptor releaseDescriptor, ReleaseEnvironment releaseEnvironment)
296 throws PolicyException, VersionParseException {
297 String policyId = releaseDescriptor.getProjectVersionPolicyId();
298 VersionPolicy policy = versionPolicies.get(policyId);
299 if (policy == null) {
300 throw new PolicyException("Policy '" + policyId + "' is unknown, available: " + versionPolicies.keySet());
301 }
302
303 VersionPolicyRequest request = new VersionPolicyRequest().setVersion(baseVersion);
304
305 if (releaseDescriptor.getProjectVersionPolicyConfig() != null) {
306 request.setConfig(releaseDescriptor.getProjectVersionPolicyConfig().toString());
307 }
308 request.setWorkingDirectory(releaseDescriptor.getWorkingDirectory());
309
310 if (scmRepositoryConfigurator != null && releaseDescriptor.getScmSourceUrl() != null) {
311 try {
312 ScmRepository repository = scmRepositoryConfigurator.getConfiguredRepository(
313 releaseDescriptor, releaseEnvironment.getSettings());
314
315 ScmProvider provider = scmRepositoryConfigurator.getRepositoryProvider(repository);
316
317 request.setScmRepository(repository);
318 request.setScmProvider(provider);
319 } catch (ScmRepositoryException | NoSuchScmProviderException e) {
320 Logger logger = getLogger();
321 if (logger.isWarnEnabled()) {
322 logger.warn("Next Version will NOT be based on the version control: {}", e.getMessage());
323 } else {
324 if (logger.isDebugEnabled()) {
325 logger.warn("Next Version will NOT be based on the version control", e);
326 }
327 }
328 }
329 }
330 return convertToSnapshot
331 ? policy.getDevelopmentVersion(request).getVersion()
332 : policy.getReleaseVersion(request).getVersion();
333 }
334
335 private String getDevelopmentVersion(String projectId, ReleaseDescriptor releaseDescriptor) {
336 String projectVersion = releaseDescriptor.getProjectDevelopmentVersion(projectId);
337
338 if (projectVersion == null || projectVersion.isEmpty()) {
339 projectVersion = releaseDescriptor.getDefaultDevelopmentVersion();
340 }
341
342 if (projectVersion == null || projectVersion.isEmpty()) {
343 return null;
344 }
345
346 return projectVersion;
347 }
348
349 private String getReleaseVersion(String projectId, ReleaseDescriptor releaseDescriptor) {
350 String projectVersion = releaseDescriptor.getProjectReleaseVersion(projectId);
351
352 if (projectVersion == null || projectVersion.isEmpty()) {
353 projectVersion = releaseDescriptor.getDefaultReleaseVersion();
354 }
355
356 if (projectVersion == null || projectVersion.isEmpty()) {
357 return null;
358 }
359
360 return projectVersion;
361 }
362
363 @Override
364 public ReleaseResult simulate(
365 ReleaseDescriptor releaseDescriptor,
366 ReleaseEnvironment releaseEnvironment,
367 List<MavenProject> reactorProjects)
368 throws ReleaseExecutionException {
369 ReleaseResult result = new ReleaseResult();
370
371
372 execute(releaseDescriptor, releaseEnvironment, reactorProjects);
373
374 result.setResultCode(ReleaseResult.SUCCESS);
375
376 return result;
377 }
378 }