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.io.IOException;
24  import java.nio.file.Path;
25  import java.util.ArrayList;
26  import java.util.Arrays;
27  import java.util.List;
28  
29  import org.apache.maven.artifact.ArtifactUtils;
30  import org.apache.maven.execution.MavenSession;
31  import org.apache.maven.plugin.AbstractMojo;
32  import org.apache.maven.plugins.annotations.Component;
33  import org.apache.maven.plugins.annotations.Parameter;
34  import org.apache.maven.project.MavenProject;
35  import org.apache.maven.settings.Settings;
36  import org.apache.maven.shared.release.ReleaseManager;
37  import org.apache.maven.shared.release.config.ReleaseDescriptorBuilder;
38  import org.apache.maven.shared.release.env.DefaultReleaseEnvironment;
39  import org.apache.maven.shared.release.env.ReleaseEnvironment;
40  import org.codehaus.plexus.util.StringUtils;
41  
42  /**
43   * Base class with shared configuration.
44   *
45   * @author <a href="mailto:brett@apache.org">Brett Porter</a>
46   */
47  public abstract class AbstractReleaseMojo
48      extends AbstractMojo
49  {
50      /**
51       */
52      @Parameter( defaultValue = "${basedir}", readonly = true, required = true )
53      private File basedir;
54  
55      /**
56       */
57      @Parameter( defaultValue = "${settings}", readonly = true, required = true )
58      private Settings settings;
59  
60      /**
61       */
62      @Parameter( defaultValue = "${project}", readonly = true, required = true )
63      protected MavenProject project;
64  
65      /**
66       */
67      @Component
68      protected ReleaseManager releaseManager;
69  
70      /**
71       * Additional arguments to pass to the Maven executions, separated by spaces.
72       */
73      @Parameter( alias = "prepareVerifyArgs", property = "arguments" )
74      private String arguments;
75  
76      /**
77       * The file name of the POM to execute any goals against. As of version 3.0.0, this defaults to the name of
78       * POM file of the project being built.
79       */
80      @Parameter( property = "pomFileName", defaultValue = "${project.file.name}" )
81      private String pomFileName;
82  
83      /**
84       */
85      @Parameter( defaultValue = "${reactorProjects}", readonly = true, required = true )
86      private List<MavenProject> reactorProjects;
87  
88      /**
89       * The Maven home parameter to use for forked Maven invocations.
90       *
91       * @since 2.0-beta-8
92       */
93      @Parameter( defaultValue = "${maven.home}" )
94      private File mavenHome;
95  
96      /**
97       * The {@code JAVA_HOME} parameter to use for forked Maven invocations.
98       *
99       * @since 2.0-beta-8
100      */
101     @Parameter( defaultValue = "${java.home}" )
102     private File javaHome;
103 
104     /**
105      * The command-line local repository directory in use for this build (if specified).
106      *
107      * @since 2.0-beta-8
108      */
109     @Parameter ( defaultValue = "${maven.repo.local}" )
110     private File localRepoDirectory;
111 
112     /**
113      * Role hint of the {@link org.apache.maven.shared.release.exec.MavenExecutor} implementation to use.
114      *
115      * @since 2.0-beta-8
116      */
117     @Parameter( defaultValue = "invoker", property = "mavenExecutorId" )
118     private String mavenExecutorId;
119 
120     /**
121      * @since 2.0
122      */
123     @Parameter( defaultValue = "${session}", readonly = true, required = true )
124     protected MavenSession session;
125 
126     /**
127      * The role-hint for the {@link org.apache.maven.shared.release.strategy.Strategy}
128      * implementation used to specify the phases per goal.
129      *
130      * @since 3.0.0-M5
131      * @see org.apache.maven.shared.release.strategies.DefaultStrategy
132      */
133     @Parameter( defaultValue = "default", property = "releaseStrategyId" )
134     private String releaseStrategyId;
135 
136     /**
137      * Gets the environment settings configured for this release.
138      *
139      * @return The release environment, never <code>null</code>.
140      */
141     protected ReleaseEnvironment getReleaseEnvironment()
142     {
143         return new DefaultReleaseEnvironment().setSettings( settings )
144                                               .setJavaHome( javaHome )
145                                               .setMavenHome( mavenHome )
146                                               .setLocalRepositoryDirectory( localRepoDirectory )
147                                               .setMavenExecutorId( mavenExecutorId );
148     }
149 
150     /**
151      * Creates the release descriptor from the various goal parameters.
152      *
153      * @return The release descriptor, never <code>null</code>.
154      */
155     protected ReleaseDescriptorBuilder createReleaseDescriptor()
156     {
157         ReleaseDescriptorBuilder descriptor = new ReleaseDescriptorBuilder();
158 
159         descriptor.setInteractive( settings.isInteractiveMode() );
160 
161         Path workingDirectory;
162         try
163         {
164             workingDirectory = getCommonBasedir( reactorProjects );
165         }
166         catch ( IOException e )
167         {
168             throw new RuntimeException( e.getMessage() );
169         }
170         descriptor.setWorkingDirectory( workingDirectory.toFile().getAbsolutePath() );
171 
172         Path rootBasedir = basedir.toPath();
173         if ( rootBasedir.equals( workingDirectory ) )
174         {
175             descriptor.setPomFileName( pomFileName );
176         }
177         else
178         {
179             descriptor.setPomFileName( workingDirectory.relativize( rootBasedir ).resolve( pomFileName ).toString() );
180         }
181 
182         for ( MavenProject project : reactorProjects )
183         {
184             String versionlessKey = ArtifactUtils.versionlessKey( project.getGroupId(), project.getArtifactId() );
185             descriptor.putOriginalVersion( versionlessKey, project.getVersion() );
186         }
187 
188         descriptor.setAdditionalArguments( this.arguments );
189 
190         List<String> profileIds = session.getRequest().getActiveProfiles();
191         String additionalProfiles = getAdditionalProfiles();
192 
193         if ( !profileIds.isEmpty() || StringUtils.isNotBlank( additionalProfiles ) )
194         {
195             List<String> profiles = new ArrayList<>( profileIds );
196 
197             if ( additionalProfiles != null )
198             {
199                 profiles.addAll( Arrays.asList( additionalProfiles.split( "," ) ) );
200             }
201 
202             descriptor.setActivateProfiles( profiles );
203         }
204 
205         descriptor.setReleaseStrategyId( releaseStrategyId );
206 
207         return descriptor;
208     }
209 
210     /**
211      * Gets the comma separated list of additional profiles for the release build.
212      *
213      * @return additional profiles to enable during release
214      */
215     protected String getAdditionalProfiles()
216     {
217         return null;
218     }
219 
220     /**
221      * Sets the component used to perform release actions.
222      *
223      * @param releaseManager The release manager implementation to use, must not be <code>null</code>.
224      */
225     void setReleaseManager( ReleaseManager releaseManager )
226     {
227         this.releaseManager = releaseManager;
228     }
229 
230     /**
231      * Gets the effective settings for this build.
232      *
233      * @return The effective settings for this build, never <code>null</code>.
234      */
235     Settings getSettings()
236     {
237         return settings;
238     }
239 
240     protected final File getBasedir()
241     {
242         return basedir;
243     }
244 
245     /**
246      * Sets the base directory of the build.
247      *
248      * @param basedir The build's base directory, must not be <code>null</code>.
249      */
250     public void setBasedir( File basedir )
251     {
252         this.basedir = basedir;
253     }
254 
255     public void setPomFileName( String pomFileName )
256     {
257         this.pomFileName = pomFileName;
258     }
259 
260     /**
261      * only used for unit tests in which some required values of the project would be null
262      */
263     protected MavenProject getProject()
264     {
265         return this.project;
266     }
267 
268     /**
269      * Gets the list of projects in the build reactor.
270      *
271      * @return The list of reactor project, never <code>null</code>.
272      */
273     public List<MavenProject> getReactorProjects()
274     {
275         return reactorProjects;
276     }
277 
278     /**
279      * Add additional arguments.
280      *
281      * @param argument The argument to add, must not be <code>null</code>.
282      */
283     protected void addArgument( String argument )
284     {
285         if ( arguments != null )
286         {
287             arguments += " " + argument;
288         }
289         else
290         {
291             arguments = argument;
292         }
293     }
294 
295     static Path getCommonBasedir( List<MavenProject> reactorProjects )
296                     throws IOException
297     {
298         Path basePath = reactorProjects.get( 0 ).getBasedir().toPath();
299 
300         for ( MavenProject reactorProject : reactorProjects )
301         {
302             Path matchPath = reactorProject.getBasedir().toPath();
303             while ( !basePath.startsWith( matchPath ) )
304             {
305                 matchPath = matchPath.getParent();
306             }
307             basePath = matchPath;
308         }
309 
310         return basePath;
311     }
312 }