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 816531 2012-05-08 11:38:11Z 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 * Format to use when generating the tag name if none is specified. Property interpolation is performed on the 73 * tag, but in order to ensure that the interpolation occurs during release, you must use <code>@{...}</code> 74 * to reference the properties rather than <code>${...}</code>. The following properties are available: 75 * <ul> 76 * <li><code>groupId</code> or <code>project.groupId</code> - The groupId of the root project. 77 * <li><code>artifactId</code> or <code>project.artifactId</code> - The artifactId of the root project. 78 * <li><code>version</code> or <code>project.version</code> - The release version of the root project. 79 * </ul> 80 * 81 * @parameter expression="${tagNameFormat}" default-value="@{project.artifactId}-@{project.version}" 82 * @since 2.2.0 83 */ 84 private String tagNameFormat; 85 86 /** 87 * The tag base directory in SVN, you must define it if you don't use the standard svn layout (trunk/tags/branches). 88 * For example, <code>http://svn.apache.org/repos/asf/maven/plugins/tags</code>. The URL is an SVN URL and does not 89 * include the SCM provider and protocol. 90 * 91 * @parameter expression="${tagBase}" 92 */ 93 private String tagBase; 94 95 /** 96 * @parameter expression="${basedir}" 97 * @required 98 * @readonly 99 */ 100 protected File basedir; 101 102 /** 103 * @parameter expression="${settings}" 104 * @required 105 * @readonly 106 */ 107 protected Settings settings; 108 109 /** 110 * @parameter expression="${project}" 111 * @required 112 * @readonly 113 */ 114 protected MavenProject project; 115 116 /** 117 * @component 118 */ 119 protected ReleaseManager releaseManager; 120 121 /** 122 * Additional arguments to pass to the Maven executions, separated by spaces. 123 * 124 * @parameter expression="${arguments}" alias="prepareVerifyArgs" 125 */ 126 private String arguments; 127 128 /** 129 * The file name of the POM to execute any goals against. 130 * 131 * @parameter expression="${pomFileName}" 132 */ 133 private String pomFileName; 134 135 /** 136 * The message prefix to use for all SCM changes. 137 * 138 * @parameter expression="${scmCommentPrefix}" default-value="[maven-release-plugin] " 139 * @since 2.0-beta-5 140 */ 141 private String scmCommentPrefix; 142 143 /** 144 * @parameter expression="${reactorProjects}" 145 * @required 146 * @readonly 147 */ 148 protected List reactorProjects; 149 150 /** 151 * List of provider implementations. 152 * 153 * @parameter 154 * @since 2.0-beta-6 155 */ 156 private Map providerImplementations; 157 158 /** 159 * The M2_HOME parameter to use for forked Maven invocations. 160 * 161 * @parameter default-value="${maven.home}" 162 * @since 2.0-beta-8 163 */ 164 protected File mavenHome; 165 166 /** 167 * The JAVA_HOME parameter to use for forked Maven invocations. 168 * 169 * @parameter default-value="${java.home}" 170 * @since 2.0-beta-8 171 */ 172 protected File javaHome; 173 174 /** 175 * The command-line local repository directory in use for this build (if specified). 176 * 177 * @parameter default-value="${maven.repo.local}" 178 * @since 2.0-beta-8 179 */ 180 protected File localRepoDirectory; 181 182 /** 183 * Role hint of the {@link org.apache.maven.shared.release.exec.MavenExecutor} implementation to use. 184 * 185 * @parameter expression="${mavenExecutorId}" default-value="invoker" 186 * @since 2.0-beta-8 187 */ 188 protected String mavenExecutorId; 189 190 /** 191 * Use a local checkout instead of doing a checkout from the upstream repository. 192 * ATTENTION: This will only work with distributed SCMs which support the file:// protocol 193 * like e.g. git, jgit or hg! 194 * 195 * TODO: we should think about having the defaults for the various SCM providers provided via modello! 196 * 197 * @parameter expression="${localCheckout}" default-value="false" 198 * @since 2.0 199 */ 200 private boolean localCheckout; 201 202 /** 203 * Implemented with git will or not push changes to the upstream repository. 204 * <code>true</code> by default to preserve backward compatibility. 205 * @parameter expression="${pushChanges}" default-value="true" 206 * @since 2.1 207 */ 208 private boolean pushChanges = true; 209 210 /** 211 * The SCM manager. 212 * 213 * @component 214 */ 215 private ScmManager scmManager; 216 217 /** 218 * @parameter expression="${session}" 219 * @readonly 220 * @required 221 * @since 2.0 222 */ 223 protected MavenSession session; 224 225 226 /** 227 * Gets the enviroment settings configured for this release. 228 * 229 * @return The release environment, never <code>null</code>. 230 */ 231 protected ReleaseEnvironment getReleaseEnvironment() 232 { 233 return new DefaultReleaseEnvironment().setSettings( settings ) 234 .setJavaHome( javaHome ) 235 .setMavenHome( mavenHome ) 236 .setLocalRepositoryDirectory( localRepoDirectory ) 237 .setMavenExecutorId( mavenExecutorId ); 238 } 239 240 /** 241 * {@inheritDoc} 242 */ 243 public void execute() 244 throws MojoExecutionException, MojoFailureException 245 { 246 if ( providerImplementations != null ) 247 { 248 for ( Iterator i = providerImplementations.keySet().iterator(); i.hasNext(); ) 249 { 250 String providerType = (String) i.next(); 251 String providerImplementation = (String) providerImplementations.get( providerType ); 252 getLog().info( "Change the default '" + providerType + "' provider implementation to '" 253 + providerImplementation + "'." ); 254 scmManager.setScmProviderImplementation( providerType, providerImplementation ); 255 } 256 } 257 } 258 259 /** 260 * Creates the release descriptor from the various goal parameters. 261 * 262 * @return The release descriptor, never <code>null</code>. 263 */ 264 protected ReleaseDescriptor createReleaseDescriptor() 265 { 266 ReleaseDescriptor descriptor = new ReleaseDescriptor(); 267 268 descriptor.setInteractive( settings.isInteractiveMode() ); 269 270 descriptor.setScmPassword( password ); 271 descriptor.setScmReleaseLabel( tag ); 272 descriptor.setScmTagNameFormat( tagNameFormat ); 273 descriptor.setScmTagBase( tagBase ); 274 descriptor.setScmUsername( username ); 275 descriptor.setScmCommentPrefix( scmCommentPrefix ); 276 277 descriptor.setWorkingDirectory( basedir.getAbsolutePath() ); 278 279 descriptor.setPomFileName( pomFileName ); 280 281 descriptor.setLocalCheckout( localCheckout ); 282 283 descriptor.setPushChanges( pushChanges ); 284 285 List profiles = project.getActiveProfiles(); 286 287 String arguments = this.arguments; 288 if ( profiles != null && !profiles.isEmpty() ) 289 { 290 if ( !StringUtils.isEmpty( arguments ) ) 291 { 292 arguments += " -P "; 293 } 294 else 295 { 296 arguments = "-P "; 297 } 298 299 for ( Iterator it = profiles.iterator(); it.hasNext(); ) 300 { 301 Profile profile = (Profile) it.next(); 302 303 arguments += profile.getId(); 304 if ( it.hasNext() ) 305 { 306 arguments += ","; 307 } 308 } 309 310 String additionalProfiles = getAdditionalProfiles(); 311 if ( additionalProfiles != null ) 312 { 313 if ( !profiles.isEmpty() ) 314 { 315 arguments += ","; 316 } 317 arguments += additionalProfiles; 318 } 319 } 320 descriptor.setAdditionalArguments( arguments ); 321 322 return descriptor; 323 } 324 325 /** 326 * Gets the comma separated list of additional profiles for the release build. 327 * 328 * @return additional profiles to enable during release 329 */ 330 protected String getAdditionalProfiles() 331 { 332 return null; 333 } 334 335 /** 336 * Sets the component used to perform release actions. 337 * 338 * @param releaseManager The release manager implementation to use, must not be <code>null</code>. 339 */ 340 void setReleaseManager( ReleaseManager releaseManager ) 341 { 342 this.releaseManager = releaseManager; 343 } 344 345 /** 346 * Gets the effective settings for this build. 347 * 348 * @return The effective settings for this build, never <code>null</code>. 349 */ 350 Settings getSettings() 351 { 352 return settings; 353 } 354 355 /** 356 * Sets the base directory of the build. 357 * 358 * @param basedir The build's base directory, must not be <code>null</code>. 359 */ 360 public void setBasedir( File basedir ) 361 { 362 this.basedir = basedir; 363 } 364 365 /** 366 * Gets the list of projects in the build reactor. 367 * 368 * @return The list of reactor project, never <code>null</code>. 369 */ 370 public List getReactorProjects() 371 { 372 return reactorProjects; 373 } 374 375 /** 376 * Add additional arguments. 377 * 378 * @param argument The argument to add, must not be <code>null</code>. 379 */ 380 protected void addArgument( String argument ) 381 { 382 if ( arguments != null ) 383 { 384 arguments += " " + argument; 385 } 386 else 387 { 388 arguments = argument; 389 } 390 } 391 392 /** 393 * This method takes some of the release configuration picked up from the command line system properties and copies 394 * it into the release config object. 395 * 396 * @param config The release configuration to merge the system properties into, must not be <code>null</code>. 397 * @param sysPropertiesConfig The configuration from the system properties to merge in, must not be 398 * <code>null</code>. 399 */ 400 protected void mergeCommandLineConfig( ReleaseDescriptor config, ReleaseDescriptor sysPropertiesConfig ) 401 { 402 // If the user specifies versions, these should override the existing versions 403 if ( sysPropertiesConfig.getReleaseVersions() != null ) 404 { 405 config.getReleaseVersions().putAll( sysPropertiesConfig.getReleaseVersions() ); 406 } 407 if ( sysPropertiesConfig.getDevelopmentVersions() != null ) 408 { 409 config.getDevelopmentVersions().putAll( sysPropertiesConfig.getDevelopmentVersions() ); 410 } 411 } 412 }