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.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 }