View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.plugins.release;
20  
21  import java.io.File;
22  import java.nio.file.Path;
23  import java.util.ArrayList;
24  import java.util.Arrays;
25  import java.util.List;
26  
27  import org.apache.maven.artifact.ArtifactUtils;
28  import org.apache.maven.execution.MavenSession;
29  import org.apache.maven.plugin.AbstractMojo;
30  import org.apache.maven.plugins.annotations.Parameter;
31  import org.apache.maven.project.MavenProject;
32  import org.apache.maven.settings.Settings;
33  import org.apache.maven.shared.release.ReleaseManager;
34  import org.apache.maven.shared.release.config.ReleaseDescriptorBuilder;
35  import org.apache.maven.shared.release.env.DefaultReleaseEnvironment;
36  import org.apache.maven.shared.release.env.ReleaseEnvironment;
37  import org.codehaus.plexus.util.StringUtils;
38  
39  /**
40   * Base class with shared configuration.
41   *
42   * @author <a href="mailto:brett@apache.org">Brett Porter</a>
43   */
44  public abstract class AbstractReleaseMojo extends AbstractMojo {
45      @Parameter(defaultValue = "${basedir}", readonly = true, required = true)
46      private File basedir;
47  
48      @Parameter(defaultValue = "${settings}", readonly = true, required = true)
49      private Settings settings;
50  
51      @Parameter(defaultValue = "${project}", readonly = true, required = true)
52      protected MavenProject project;
53  
54      /**
55       * Additional arguments to pass to the Maven executions, separated by spaces.
56       */
57      @Parameter(alias = "prepareVerifyArgs", property = "arguments")
58      private String arguments;
59  
60      /**
61       * The file name of the POM to execute any goals against. As of version 3.0.0, this defaults to the name of
62       * POM file of the project being built.
63       */
64      @Parameter(property = "pomFileName", defaultValue = "${project.file.name}")
65      private String pomFileName;
66  
67      @Parameter(defaultValue = "${reactorProjects}", readonly = true, required = true)
68      private List<MavenProject> reactorProjects;
69  
70      /**
71       * The Maven home parameter to use for forked Maven invocations.
72       *
73       * @since 2.0-beta-8
74       */
75      @Parameter(defaultValue = "${maven.home}")
76      private File mavenHome;
77  
78      /**
79       * The Java home parameter to use for forked Maven invocations.
80       *
81       * @since 2.0-beta-8
82       */
83      @Parameter(defaultValue = "${java.home}")
84      private File javaHome;
85  
86      /**
87       * The command-line local repository directory in use for this build (if specified).
88       *
89       * @since 2.0-beta-8
90       */
91      @Parameter(defaultValue = "${maven.repo.local}")
92      private File localRepoDirectory;
93  
94      /**
95       * Role hint of the {@link org.apache.maven.shared.release.exec.MavenExecutor} implementation to use.
96       *
97       * @since 2.0-beta-8
98       */
99      @Parameter(defaultValue = "invoker", property = "mavenExecutorId")
100     private String mavenExecutorId;
101 
102     /**
103      * @since 2.0
104      */
105     @Parameter(defaultValue = "${session}", readonly = true, required = true)
106     protected MavenSession session;
107 
108     /**
109      * The role-hint for the {@link org.apache.maven.shared.release.strategy.Strategy}
110      * implementation used to specify the phases per goal.
111      *
112      * @see org.apache.maven.shared.release.strategies.DefaultStrategy
113      * @since 3.0.0-M5
114      */
115     @Parameter(defaultValue = "default", property = "releaseStrategyId")
116     private String releaseStrategyId;
117 
118     protected ReleaseManager releaseManager;
119 
120     protected AbstractReleaseMojo(ReleaseManager releaseManager) {
121         this.releaseManager = releaseManager;
122     }
123 
124     /**
125      * Gets the environment settings configured for this release.
126      *
127      * @return the release environment, never <code>null</code>
128      */
129     protected ReleaseEnvironment getReleaseEnvironment() {
130         return new DefaultReleaseEnvironment()
131                 .setSettings(settings)
132                 .setJavaHome(javaHome)
133                 .setMavenHome(mavenHome)
134                 .setLocalRepositoryDirectory(localRepoDirectory)
135                 .setMavenExecutorId(mavenExecutorId);
136     }
137 
138     /**
139      * Creates the release descriptor from the various goal parameters.
140      *
141      * @return the release descriptor, never <code>null</code>
142      */
143     protected ReleaseDescriptorBuilder createReleaseDescriptor() {
144         ReleaseDescriptorBuilder descriptor = new ReleaseDescriptorBuilder();
145 
146         descriptor.setInteractive(settings.isInteractiveMode());
147 
148         Path workingDirectory = getCommonBasedir(reactorProjects);
149         descriptor.setWorkingDirectory(workingDirectory.toFile().getAbsolutePath());
150 
151         Path rootBasedir = basedir.toPath();
152         if (rootBasedir.equals(workingDirectory)) {
153             descriptor.setPomFileName(pomFileName);
154         } else {
155             descriptor.setPomFileName(workingDirectory
156                     .relativize(rootBasedir)
157                     .resolve(pomFileName)
158                     .toString());
159         }
160 
161         for (MavenProject project : reactorProjects) {
162             String versionlessKey = ArtifactUtils.versionlessKey(project.getGroupId(), project.getArtifactId());
163             descriptor.putOriginalVersion(versionlessKey, project.getVersion());
164         }
165 
166         descriptor.setAdditionalArguments(this.arguments);
167 
168         List<String> profileIds = session.getRequest().getActiveProfiles();
169         String additionalProfiles = getAdditionalProfiles();
170 
171         if (!profileIds.isEmpty() || StringUtils.isNotBlank(additionalProfiles)) {
172             List<String> profiles = new ArrayList<>(profileIds);
173 
174             if (additionalProfiles != null) {
175                 profiles.addAll(Arrays.asList(additionalProfiles.split(",")));
176             }
177 
178             descriptor.setActivateProfiles(profiles);
179         }
180 
181         descriptor.setReleaseStrategyId(releaseStrategyId);
182 
183         return descriptor;
184     }
185 
186     /**
187      * Gets the comma separated list of additional profiles for the release build.
188      *
189      * @return additional profiles to enable during release
190      */
191     protected String getAdditionalProfiles() {
192         return null;
193     }
194 
195     /**
196      * Sets the component used to perform release actions.
197      *
198      * @param releaseManager the release manager implementation to use, must not be <code>null</code>
199      */
200     void setReleaseManager(ReleaseManager releaseManager) {
201         this.releaseManager = releaseManager;
202     }
203 
204     /**
205      * Gets the effective settings for this build.
206      *
207      * @return the effective settings for this build, never <code>null</code>
208      */
209     Settings getSettings() {
210         return settings;
211     }
212 
213     protected final File getBasedir() {
214         return basedir;
215     }
216 
217     /**
218      * Sets the base directory of the build.
219      *
220      * @param basedir the build's base directory, must not be <code>null</code>
221      */
222     public void setBasedir(File basedir) {
223         this.basedir = basedir;
224     }
225 
226     public void setPomFileName(String pomFileName) {
227         this.pomFileName = pomFileName;
228     }
229 
230     /**
231      * Only used for unit tests in which some required values of the project would be null.
232      */
233     protected MavenProject getProject() {
234         return this.project;
235     }
236 
237     /**
238      * Gets the list of projects in the build reactor.
239      *
240      * @return the list of reactor project, never <code>null</code>
241      */
242     public List<MavenProject> getReactorProjects() {
243         return reactorProjects;
244     }
245 
246     /**
247      * Add additional arguments.
248      *
249      * @param argument the argument to add, must not be <code>null</code>
250      */
251     protected void addArgument(String argument) {
252         if (arguments != null) {
253             arguments += " " + argument;
254         } else {
255             arguments = argument;
256         }
257     }
258 
259     private static Path getCommonBasedir(List<MavenProject> reactorProjects) {
260         Path basePath = reactorProjects.get(0).getBasedir().toPath();
261 
262         for (MavenProject reactorProject : reactorProjects) {
263             Path matchPath = reactorProject.getBasedir().toPath();
264             while (!basePath.startsWith(matchPath)) {
265                 matchPath = matchPath.getParent();
266             }
267             basePath = matchPath;
268         }
269 
270         return basePath;
271     }
272 }