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 import java.util.Properties;
25
26 import org.apache.maven.artifact.ArtifactUtils;
27 import org.apache.maven.project.MavenProject;
28 import org.apache.maven.scm.manager.NoSuchScmProviderException;
29 import org.apache.maven.scm.provider.ScmProvider;
30 import org.apache.maven.scm.repository.ScmRepository;
31 import org.apache.maven.scm.repository.ScmRepositoryException;
32 import org.apache.maven.shared.release.ReleaseExecutionException;
33 import org.apache.maven.shared.release.ReleaseResult;
34 import org.apache.maven.shared.release.config.ReleaseDescriptor;
35 import org.apache.maven.shared.release.env.ReleaseEnvironment;
36 import org.apache.maven.shared.release.policy.PolicyException;
37 import org.apache.maven.shared.release.policy.naming.NamingPolicy;
38 import org.apache.maven.shared.release.policy.naming.NamingPolicyRequest;
39 import org.apache.maven.shared.release.scm.ReleaseScmRepositoryException;
40 import org.apache.maven.shared.release.scm.ScmRepositoryConfigurator;
41 import org.apache.maven.shared.release.util.ReleaseUtil;
42 import org.codehaus.plexus.component.annotations.Requirement;
43 import org.codehaus.plexus.components.interactivity.Prompter;
44 import org.codehaus.plexus.components.interactivity.PrompterException;
45 import org.codehaus.plexus.interpolation.InterpolationException;
46 import org.codehaus.plexus.interpolation.Interpolator;
47 import org.codehaus.plexus.interpolation.PrefixAwareRecursionInterceptor;
48 import org.codehaus.plexus.interpolation.PrefixedPropertiesValueSource;
49 import org.codehaus.plexus.interpolation.RecursionInterceptor;
50 import org.codehaus.plexus.interpolation.StringSearchInterpolator;
51 import org.codehaus.plexus.util.StringUtils;
52
53
54
55
56
57
58 public class InputVariablesPhase
59 extends AbstractReleasePhase
60 {
61
62
63
64 @Requirement
65 private Prompter prompter;
66
67
68
69
70 private boolean branchOperation;
71
72
73
74
75 @Requirement
76 private ScmRepositoryConfigurator scmRepositoryConfigurator;
77
78
79
80
81 @Requirement
82 private Map<String, NamingPolicy> namingPolicies;
83
84
85
86
87 private String defaultNamingPolicy;
88
89 void setPrompter( Prompter prompter )
90 {
91 this.prompter = prompter;
92 }
93
94 boolean isBranchOperation()
95 {
96 return branchOperation;
97 }
98
99 protected ScmProvider getScmProvider( ReleaseDescriptor releaseDescriptor, ReleaseEnvironment releaseEnvironment )
100 throws ReleaseScmRepositoryException, ReleaseExecutionException
101 {
102 try
103 {
104 ScmRepository repository =
105 scmRepositoryConfigurator.getConfiguredRepository( releaseDescriptor,
106 releaseEnvironment.getSettings() );
107
108 return scmRepositoryConfigurator.getRepositoryProvider( repository );
109 }
110 catch ( ScmRepositoryException e )
111 {
112 throw new ReleaseScmRepositoryException(
113 e.getMessage() + " for URL: " + releaseDescriptor.getScmSourceUrl(), e.getValidationMessages() );
114 }
115 catch ( NoSuchScmProviderException e )
116 {
117 throw new ReleaseExecutionException( "Unable to configure SCM repository: " + e.getMessage(), e );
118 }
119 }
120
121 @Override
122 public ReleaseResult execute( ReleaseDescriptor releaseDescriptor, ReleaseEnvironment releaseEnvironment,
123 List<MavenProject> reactorProjects )
124 throws ReleaseExecutionException
125 {
126 ReleaseResult result = new ReleaseResult();
127
128
129 MavenProject project = ReleaseUtil.getRootProject( reactorProjects );
130
131 String tag = releaseDescriptor.getScmReleaseLabel();
132
133 if ( tag == null )
134 {
135
136 String key = ArtifactUtils.versionlessKey( project.getGroupId(), project.getArtifactId() );
137 String releaseVersion = releaseDescriptor.getProjectReleaseVersion( key );
138 if ( releaseVersion == null )
139 {
140 throw new ReleaseExecutionException( "Project tag cannot be selected if version is not yet mapped" );
141 }
142
143 String suggestedName;
144 String scmTagNameFormat = releaseDescriptor.getScmTagNameFormat();
145 if ( releaseDescriptor.getProjectNamingPolicyId() != null )
146 {
147 try
148 {
149 suggestedName =
150 resolveSuggestedName( releaseDescriptor.getProjectNamingPolicyId(), releaseVersion, project );
151 }
152 catch ( PolicyException e )
153 {
154 throw new ReleaseExecutionException( e.getMessage(), e );
155 }
156 }
157 else if ( scmTagNameFormat != null )
158 {
159 Interpolator interpolator = new StringSearchInterpolator( "@{", "}" );
160 List<String> possiblePrefixes = java.util.Arrays.asList( "project", "pom" );
161 Properties values = new Properties();
162 values.setProperty( "artifactId", project.getArtifactId() );
163 values.setProperty( "groupId", project.getGroupId() );
164 values.setProperty( "version", releaseVersion );
165 interpolator.addValueSource( new PrefixedPropertiesValueSource( possiblePrefixes, values, true ) );
166 RecursionInterceptor recursionInterceptor = new PrefixAwareRecursionInterceptor( possiblePrefixes );
167 try
168 {
169 suggestedName = interpolator.interpolate( scmTagNameFormat, recursionInterceptor );
170 }
171 catch ( InterpolationException e )
172 {
173 throw new ReleaseExecutionException(
174 "Could not interpolate specified tag name format: " + scmTagNameFormat, e );
175 }
176 }
177 else
178 {
179 try
180 {
181 suggestedName = resolveSuggestedName( defaultNamingPolicy, releaseVersion, project );
182 }
183 catch ( PolicyException e )
184 {
185 throw new ReleaseExecutionException( e.getMessage(), e );
186 }
187 }
188
189 ScmProvider provider = null;
190 try
191 {
192 provider = getScmProvider( releaseDescriptor, releaseEnvironment );
193 }
194 catch ( ReleaseScmRepositoryException e )
195 {
196 throw new ReleaseExecutionException(
197 "No scm provider can be found for url: " + releaseDescriptor.getScmSourceUrl(), e );
198 }
199
200 suggestedName = provider.sanitizeTagName( suggestedName );
201
202 if ( releaseDescriptor.isInteractive() )
203 {
204 try
205 {
206 if ( branchOperation )
207 {
208 tag = prompter.prompt( "What is the branch name for \"" + project.getName() + "\"? ("
209 + project.getGroupId() + ":" + project.getArtifactId() + ")" );
210 if ( StringUtils.isEmpty( tag ) )
211 {
212 throw new ReleaseExecutionException( "No branch name was given." );
213 }
214 }
215 else
216 {
217 tag = prompter.prompt( "What is the SCM release tag or label for \"" + project.getName()
218 + "\"? (" + project.getGroupId() + ":" + project.getArtifactId() + ")", suggestedName );
219 }
220 }
221 catch ( PrompterException e )
222 {
223 throw new ReleaseExecutionException( "Error reading version from input handler: " + e.getMessage(),
224 e );
225 }
226 }
227 else if ( suggestedName == null )
228 {
229 if ( isBranchOperation() )
230 {
231 throw new ReleaseExecutionException( "No branch name was given." );
232 }
233 else
234 {
235 throw new ReleaseExecutionException( "No tag name was given." );
236 }
237 }
238 else
239 {
240 tag = suggestedName;
241 }
242 releaseDescriptor.setScmReleaseLabel( tag );
243 }
244
245 result.setResultCode( ReleaseResult.SUCCESS );
246
247 return result;
248 }
249
250 @Override
251 public ReleaseResult simulate( ReleaseDescriptor releaseDescriptor, ReleaseEnvironment releaseEnvironment,
252 List<MavenProject> reactorProjects )
253 throws ReleaseExecutionException
254 {
255 ReleaseResult result = new ReleaseResult();
256
257
258 execute( releaseDescriptor, releaseEnvironment, reactorProjects );
259
260 result.setResultCode( ReleaseResult.SUCCESS );
261
262 return result;
263 }
264
265 private String resolveSuggestedName( String policyId, String version, MavenProject project )
266 throws PolicyException
267 {
268 if ( policyId == null )
269 {
270 return null;
271 }
272
273 NamingPolicy policy = namingPolicies.get( policyId );
274 if ( policy == null )
275 {
276 throw new PolicyException( "Policy '" + policyId + "' is unknown, available: "
277 + namingPolicies.keySet() );
278 }
279
280 NamingPolicyRequest request = new NamingPolicyRequest()
281 .setGroupId( project.getGroupId() )
282 .setArtifactId( project.getArtifactId() )
283 .setVersion( version );
284 return policy.getName( request ).getName();
285 }
286 }