1 package org.apache.maven.plugins.release;
2
3 /*
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
19 * under the License.
20 */
21
22 import java.io.File;
23 import java.util.Iterator;
24 import java.util.List;
25 import java.util.Map;
26
27 import org.apache.maven.execution.MavenSession;
28 import org.apache.maven.model.Profile;
29 import org.apache.maven.plugin.AbstractMojo;
30 import org.apache.maven.plugin.MojoExecutionException;
31 import org.apache.maven.plugin.MojoFailureException;
32 import org.apache.maven.project.MavenProject;
33 import org.apache.maven.scm.manager.ScmManager;
34 import org.apache.maven.settings.Settings;
35 import org.apache.maven.shared.release.ReleaseManager;
36 import org.apache.maven.shared.release.config.ReleaseDescriptor;
37 import org.apache.maven.shared.release.env.DefaultReleaseEnvironment;
38 import org.apache.maven.shared.release.env.ReleaseEnvironment;
39 import org.codehaus.plexus.util.StringUtils;
40
41 /**
42 * Base class with shared configuration.
43 *
44 * @author <a href="mailto:brett@apache.org">Brett Porter</a>
45 * @version $Id: AbstractReleaseMojo.html 816529 2012-05-08 11:36:38Z hboutemy $
46 */
47 public abstract class AbstractReleaseMojo
48 extends AbstractMojo
49 {
50 /**
51 * The SCM username to use.
52 *
53 * @parameter expression="${username}"
54 */
55 private String username;
56
57 /**
58 * The SCM password to use.
59 *
60 * @parameter expression="${password}"
61 */
62 private String password;
63
64 /**
65 * The SCM tag to use.
66 *
67 * @parameter expression="${tag}" alias="releaseLabel"
68 */
69 private String tag;
70
71 /**
72 * The tag base directory in SVN, you must define it if you don't use the standard svn layout (trunk/tags/branches).
73 * For example, <code>http://svn.apache.org/repos/asf/maven/plugins/tags</code>. The URL is an SVN URL and does not
74 * include the SCM provider and protocol.
75 *
76 * @parameter expression="${tagBase}"
77 */
78 private String tagBase;
79
80 /**
81 * @parameter expression="${basedir}"
82 * @required
83 * @readonly
84 */
85 protected File basedir;
86
87 /**
88 * @parameter expression="${settings}"
89 * @required
90 * @readonly
91 */
92 protected Settings settings;
93
94 /**
95 * @parameter expression="${project}"
96 * @required
97 * @readonly
98 */
99 protected MavenProject project;
100
101 /**
102 * @component
103 */
104 protected ReleaseManager releaseManager;
105
106 /**
107 * Additional arguments to pass to the Maven executions, separated by spaces.
108 *
109 * @parameter expression="${arguments}" alias="prepareVerifyArgs"
110 */
111 private String arguments;
112
113 /**
114 * The file name of the POM to execute any goals against.
115 *
116 * @parameter expression="${pomFileName}"
117 */
118 private String pomFileName;
119
120 /**
121 * The message prefix to use for all SCM changes.
122 *
123 * @parameter expression="${scmCommentPrefix}" default-value="[maven-release-plugin] "
124 * @since 2.0-beta-5
125 */
126 private String scmCommentPrefix;
127
128 /**
129 * @parameter expression="${reactorProjects}"
130 * @required
131 * @readonly
132 */
133 protected List reactorProjects;
134
135 /**
136 * List of provider implementations.
137 *
138 * @parameter
139 * @since 2.0-beta-6
140 */
141 private Map providerImplementations;
142
143 /**
144 * The M2_HOME parameter to use for forked Maven invocations.
145 *
146 * @parameter default-value="${maven.home}"
147 * @since 2.0-beta-8
148 */
149 protected File mavenHome;
150
151 /**
152 * The JAVA_HOME parameter to use for forked Maven invocations.
153 *
154 * @parameter default-value="${java.home}"
155 * @since 2.0-beta-8
156 */
157 protected File javaHome;
158
159 /**
160 * The command-line local repository directory in use for this build (if specified).
161 *
162 * @parameter default-value="${maven.repo.local}"
163 * @since 2.0-beta-8
164 */
165 protected File localRepoDirectory;
166
167 /**
168 * Role hint of the {@link org.apache.maven.shared.release.exec.MavenExecutor} implementation to use.
169 *
170 * @parameter expression="${mavenExecutorId}" default-value="invoker"
171 * @since 2.0-beta-8
172 */
173 protected String mavenExecutorId;
174
175 /**
176 * Use a local checkout instead of doing a checkout from the upstream repository.
177 * ATTENTION: This will only work with distributed SCMs which support the file:// protocol
178 * like e.g. git, jgit or hg!
179 *
180 * TODO: we should think about having the defaults for the various SCM providers provided via modello!
181 *
182 * @parameter expression="${localCheckout}" default-value="false"
183 * @since 2.0
184 */
185 private boolean localCheckout;
186
187 /**
188 * Implemented with git will or not push changes to the upstream repository.
189 * <code>true</code> by default to preserve backward compatibility.
190 * @parameter expression="${pushChanges}" default-value="true"
191 * @since 2.1
192 */
193 private boolean pushChanges = true;
194
195 /**
196 * The SCM manager.
197 *
198 * @component
199 */
200 private ScmManager scmManager;
201
202 /**
203 * @parameter expression="${session}"
204 * @readonly
205 * @required
206 * @since 2.0
207 */
208 protected MavenSession session;
209
210
211 /**
212 * Gets the enviroment settings configured for this release.
213 *
214 * @return The release environment, never <code>null</code>.
215 */
216 protected ReleaseEnvironment getReleaseEnvironment()
217 {
218 return new DefaultReleaseEnvironment().setSettings( settings )
219 .setJavaHome( javaHome )
220 .setMavenHome( mavenHome )
221 .setLocalRepositoryDirectory( localRepoDirectory )
222 .setMavenExecutorId( mavenExecutorId );
223 }
224
225 /**
226 * {@inheritDoc}
227 */
228 public void execute()
229 throws MojoExecutionException, MojoFailureException
230 {
231 if ( providerImplementations != null )
232 {
233 for ( Iterator i = providerImplementations.keySet().iterator(); i.hasNext(); )
234 {
235 String providerType = (String) i.next();
236 String providerImplementation = (String) providerImplementations.get( providerType );
237 getLog().info( "Change the default '" + providerType + "' provider implementation to '"
238 + providerImplementation + "'." );
239 scmManager.setScmProviderImplementation( providerType, providerImplementation );
240 }
241 }
242 }
243
244 /**
245 * Creates the release descriptor from the various goal parameters.
246 *
247 * @return The release descriptor, never <code>null</code>.
248 */
249 protected ReleaseDescriptor createReleaseDescriptor()
250 {
251 ReleaseDescriptor descriptor = new ReleaseDescriptor();
252
253 descriptor.setInteractive( settings.isInteractiveMode() );
254
255 descriptor.setScmPassword( password );
256 descriptor.setScmReleaseLabel( tag );
257 descriptor.setScmTagBase( tagBase );
258 descriptor.setScmUsername( username );
259 descriptor.setScmCommentPrefix( scmCommentPrefix );
260
261 descriptor.setWorkingDirectory( basedir.getAbsolutePath() );
262
263 descriptor.setPomFileName( pomFileName );
264
265 descriptor.setLocalCheckout( localCheckout );
266
267 descriptor.setPushChanges( pushChanges );
268
269 List profiles = project.getActiveProfiles();
270
271 String arguments = this.arguments;
272 if ( profiles != null && !profiles.isEmpty() )
273 {
274 if ( !StringUtils.isEmpty( arguments ) )
275 {
276 arguments += " -P ";
277 }
278 else
279 {
280 arguments = "-P ";
281 }
282
283 for ( Iterator it = profiles.iterator(); it.hasNext(); )
284 {
285 Profile profile = (Profile) it.next();
286
287 arguments += profile.getId();
288 if ( it.hasNext() )
289 {
290 arguments += ",";
291 }
292 }
293
294 String additionalProfiles = getAdditionalProfiles();
295 if ( additionalProfiles != null )
296 {
297 if ( !profiles.isEmpty() )
298 {
299 arguments += ",";
300 }
301 arguments += additionalProfiles;
302 }
303 }
304 descriptor.setAdditionalArguments( arguments );
305
306 return descriptor;
307 }
308
309 /**
310 * Gets the comma separated list of additional profiles for the release build.
311 *
312 * @return additional profiles to enable during release
313 */
314 protected String getAdditionalProfiles()
315 {
316 return null;
317 }
318
319 /**
320 * Sets the component used to perform release actions.
321 *
322 * @param releaseManager The release manager implementation to use, must not be <code>null</code>.
323 */
324 void setReleaseManager( ReleaseManager releaseManager )
325 {
326 this.releaseManager = releaseManager;
327 }
328
329 /**
330 * Gets the effective settings for this build.
331 *
332 * @return The effective settings for this build, never <code>null</code>.
333 */
334 Settings getSettings()
335 {
336 return settings;
337 }
338
339 /**
340 * Sets the base directory of the build.
341 *
342 * @param basedir The build's base directory, must not be <code>null</code>.
343 */
344 public void setBasedir( File basedir )
345 {
346 this.basedir = basedir;
347 }
348
349 /**
350 * Gets the list of projects in the build reactor.
351 *
352 * @return The list of reactor project, never <code>null</code>.
353 */
354 public List getReactorProjects()
355 {
356 return reactorProjects;
357 }
358
359 /**
360 * Add additional arguments.
361 *
362 * @param argument The argument to add, must not be <code>null</code>.
363 */
364 protected void addArgument( String argument )
365 {
366 if ( arguments != null )
367 {
368 arguments += " " + argument;
369 }
370 else
371 {
372 arguments = argument;
373 }
374 }
375
376 /**
377 * This method takes some of the release configuration picked up from the command line system properties and copies
378 * it into the release config object.
379 *
380 * @param config The release configuration to merge the system properties into, must not be <code>null</code>.
381 * @param sysPropertiesConfig The configuration from the system properties to merge in, must not be
382 * <code>null</code>.
383 */
384 protected void mergeCommandLineConfig( ReleaseDescriptor config, ReleaseDescriptor sysPropertiesConfig )
385 {
386 // If the user specifies versions, these should override the existing versions
387 if ( sysPropertiesConfig.getReleaseVersions() != null )
388 {
389 config.getReleaseVersions().putAll( sysPropertiesConfig.getReleaseVersions() );
390 }
391 if ( sysPropertiesConfig.getDevelopmentVersions() != null )
392 {
393 config.getDevelopmentVersions().putAll( sysPropertiesConfig.getDevelopmentVersions() );
394 }
395 }
396 }