View Javadoc

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.java 1333174 2012-05-02 19:52:18Z rfscholte $
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 default-value="${basedir}"
97       * @required
98       * @readonly
99       */
100     private File basedir;
101 
102     /**
103      * @parameter default-value="${settings}"
104      * @required
105      * @readonly
106      */
107     private Settings settings;
108 
109     /**
110      * @parameter default-value="${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 default-value="${reactorProjects}"
145      * @required
146      * @readonly
147      */
148     private List<MavenProject> reactorProjects;
149 
150     /**
151      * Add a new or overwrite the default implementation per provider. 
152      * The key is the scm prefix and the value is the role hint of the {@link org.apache.maven.scm.provider.ScmProvider}.
153      *
154      * @parameter
155      * @since 2.0-beta-6
156      * @see ScmManager#setScmProviderImplementation(String, String)
157      */
158     private Map<String, String> providerImplementations;
159 
160     /**
161      * The {@code M2_HOME} parameter to use for forked Maven invocations.
162      *
163      * @parameter default-value="${maven.home}"
164      * @since 2.0-beta-8
165      */
166     protected File mavenHome;
167 
168     /**
169      * The {@code JAVA_HOME} parameter to use for forked Maven invocations.
170      *
171      * @parameter default-value="${java.home}"
172      * @since 2.0-beta-8
173      */
174     private File javaHome;
175 
176     /**
177      * The command-line local repository directory in use for this build (if specified).
178      *
179      * @parameter default-value="${maven.repo.local}"
180      * @since 2.0-beta-8
181      */
182     private File localRepoDirectory;
183 
184     /**
185      * Role hint of the {@link org.apache.maven.shared.release.exec.MavenExecutor} implementation to use.
186      *
187      * @parameter expression="${mavenExecutorId}" default-value="invoker"
188      * @since 2.0-beta-8
189      */
190     private String mavenExecutorId;
191 
192     /**
193      * Use a local checkout instead of doing a checkout from the upstream repository.
194      * ATTENTION: This will only work with distributed SCMs which support the file:// protocol
195      * like e.g. git, jgit or hg!
196      *
197      * TODO: we should think about having the defaults for the various SCM providers provided via modello!
198      *
199      * @parameter expression="${localCheckout}" default-value="false"
200      * @since 2.0
201      */
202     private boolean localCheckout;
203     
204     /**
205      * Implemented with git will or not push changes to the upstream repository.
206      * <code>true</code> by default to preserve backward compatibility.
207      * @parameter expression="${pushChanges}" default-value="true"
208      * @since 2.1
209      */
210     private boolean pushChanges = true;
211 
212     /**
213      * The SCM manager.
214      *
215      * @component
216      */
217     private ScmManager scmManager;
218 
219     /**
220      * @parameter default-value="${session}"
221      * @readonly
222      * @required
223      * @since 2.0
224      */
225     protected MavenSession session;
226 
227 
228     /**
229      * Gets the enviroment settings configured for this release.
230      *
231      * @return The release environment, never <code>null</code>.
232      */
233     protected ReleaseEnvironment getReleaseEnvironment()
234     {
235         return new DefaultReleaseEnvironment().setSettings( settings )
236                                               .setJavaHome( javaHome )
237                                               .setMavenHome( mavenHome )
238                                               .setLocalRepositoryDirectory( localRepoDirectory )
239                                               .setMavenExecutorId( mavenExecutorId );
240     }
241 
242     /**
243      * {@inheritDoc}
244      */
245     public void execute()
246         throws MojoExecutionException, MojoFailureException
247     {
248         if ( providerImplementations != null )
249         {
250             for ( Map.Entry<String, String> providerEntry : providerImplementations.entrySet() )
251             {
252                 getLog().info( "Change the default '" + providerEntry.getKey() + "' provider implementation to '"
253                     + providerEntry.getValue() + "'." );
254                 scmManager.setScmProviderImplementation( providerEntry.getKey(), providerEntry.getValue() );
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         @SuppressWarnings("unchecked")
286         List<Profile> profiles = project.getActiveProfiles();
287 
288         String arguments = this.arguments;
289         if ( profiles != null && !profiles.isEmpty() )
290         {
291             if ( !StringUtils.isEmpty( arguments ) )
292             {
293                 arguments += " -P ";
294             }
295             else
296             {
297                 arguments = "-P ";
298             }
299 
300             for ( Iterator<Profile> it = profiles.iterator(); it.hasNext(); )
301             {
302                 Profile profile = it.next();
303 
304                 arguments += profile.getId();
305                 if ( it.hasNext() )
306                 {
307                     arguments += ",";
308                 }
309             }
310 
311             String additionalProfiles = getAdditionalProfiles();
312             if ( additionalProfiles != null )
313             {
314                 if ( !profiles.isEmpty() )
315                 {
316                     arguments += ",";
317                 }
318                 arguments += additionalProfiles;
319             }
320         }
321         descriptor.setAdditionalArguments( arguments );
322 
323         return descriptor;
324     }
325 
326     /**
327      * Gets the comma separated list of additional profiles for the release build.
328      *
329      * @return additional profiles to enable during release
330      */
331     protected String getAdditionalProfiles()
332     {
333         return null;
334     }
335 
336     /**
337      * Sets the component used to perform release actions.
338      *
339      * @param releaseManager The release manager implementation to use, must not be <code>null</code>.
340      */
341     void setReleaseManager( ReleaseManager releaseManager )
342     {
343         this.releaseManager = releaseManager;
344     }
345 
346     /**
347      * Gets the effective settings for this build.
348      *
349      * @return The effective settings for this build, never <code>null</code>.
350      */
351     Settings getSettings()
352     {
353         return settings;
354     }
355     
356     protected final File getBasedir()
357     {
358         return basedir;
359     }
360 
361     /**
362      * Sets the base directory of the build.
363      *
364      * @param basedir The build's base directory, must not be <code>null</code>.
365      */
366     public void setBasedir( File basedir )
367     {
368         this.basedir = basedir;
369     }
370 
371     /**
372      * Gets the list of projects in the build reactor.
373      *
374      * @return The list of reactor project, never <code>null</code>.
375      */
376     public List<MavenProject> getReactorProjects()
377     {
378         return reactorProjects;
379     }
380 
381     /**
382      * Add additional arguments.
383      *
384      * @param argument The argument to add, must not be <code>null</code>.
385      */
386     protected void addArgument( String argument )
387     {
388         if ( arguments != null )
389         {
390             arguments += " " + argument;
391         }
392         else
393         {
394             arguments = argument;
395         }
396     }
397 
398     /**
399      * This method takes some of the release configuration picked up from the command line system properties and copies
400      * it into the release config object.
401      *
402      * @param config The release configuration to merge the system properties into, must not be <code>null</code>.
403      * @param sysPropertiesConfig The configuration from the system properties to merge in, must not be
404      *            <code>null</code>.
405      */
406     protected void mergeCommandLineConfig( ReleaseDescriptor config, ReleaseDescriptor sysPropertiesConfig )
407     {
408         // If the user specifies versions, these should override the existing versions
409         if ( sysPropertiesConfig.getReleaseVersions() != null )
410         {
411             config.getReleaseVersions().putAll( sysPropertiesConfig.getReleaseVersions() );
412         }
413         if ( sysPropertiesConfig.getDevelopmentVersions() != null )
414         {
415             config.getDevelopmentVersions().putAll( sysPropertiesConfig.getDevelopmentVersions() );
416         }
417     }
418 }