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