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.shared.release.phase;
20  
21  import java.io.File;
22  import java.util.List;
23  import java.util.Map;
24  
25  import org.apache.maven.project.MavenProject;
26  import org.apache.maven.shared.release.ReleaseExecutionException;
27  import org.apache.maven.shared.release.ReleaseResult;
28  import org.apache.maven.shared.release.config.ReleaseDescriptor;
29  import org.apache.maven.shared.release.env.ReleaseEnvironment;
30  import org.apache.maven.shared.release.exec.MavenExecutor;
31  import org.apache.maven.shared.release.exec.MavenExecutorException;
32  import org.codehaus.plexus.util.StringUtils;
33  
34  import static java.util.Objects.requireNonNull;
35  import static org.apache.maven.shared.utils.logging.MessageUtils.buffer;
36  
37  /**
38   * Abstract phase to run a Maven invocation on the project.
39   *
40   * @author <a href="mailto:brett@apache.org">Brett Porter</a>
41   */
42  public abstract class AbstractRunGoalsPhase extends AbstractReleasePhase {
43      /**
44       * Component to assist in executing Maven.
45       */
46      private final Map<String, MavenExecutor> mavenExecutors;
47  
48      protected AbstractRunGoalsPhase(Map<String, MavenExecutor> mavenExecutors) {
49          this.mavenExecutors = requireNonNull(mavenExecutors);
50      }
51  
52      protected ReleaseResult execute(
53              ReleaseDescriptor releaseDescriptor,
54              ReleaseEnvironment releaseEnvironment,
55              List<MavenProject> reactorProjects,
56              boolean logArguments)
57              throws ReleaseExecutionException {
58          return execute(
59                  releaseDescriptor,
60                  releaseEnvironment,
61                  new File(releaseDescriptor.getWorkingDirectory()),
62                  getAdditionalArguments(releaseDescriptor),
63                  logArguments);
64      }
65  
66      protected ReleaseResult execute(
67              ReleaseDescriptor releaseDescriptor,
68              ReleaseEnvironment releaseEnvironment,
69              File workingDirectory,
70              String additionalArguments,
71              boolean logArguments)
72              throws ReleaseExecutionException {
73          ReleaseResult result = new ReleaseResult();
74  
75          try {
76              String goals = getGoals(releaseDescriptor);
77              if (!(goals == null || goals.isEmpty())) {
78                  logInfo(result, "Executing goals '" + buffer().strong(goals) + "'...");
79                  if (logArguments) {
80                      // logging arguments may log secrets: should be activated only on dryRun
81                      logInfo(
82                              result,
83                              "    with additional arguments: "
84                                      + (additionalArguments == null ? "(none)" : additionalArguments));
85                  }
86  
87                  MavenExecutor mavenExecutor = mavenExecutors.get(releaseEnvironment.getMavenExecutorId());
88  
89                  if (mavenExecutor == null) {
90                      throw new ReleaseExecutionException(
91                              "Cannot find Maven executor with id: " + releaseEnvironment.getMavenExecutorId());
92                  }
93  
94                  File executionRoot;
95                  String pomFileName;
96                  if (releaseDescriptor.getPomFileName() != null) {
97                      File rootPom = new File(workingDirectory, releaseDescriptor.getPomFileName());
98                      executionRoot = rootPom.getParentFile();
99                      pomFileName = rootPom.getName();
100                 } else {
101                     executionRoot = workingDirectory;
102                     pomFileName = null;
103                 }
104 
105                 mavenExecutor.executeGoals(
106                         executionRoot,
107                         goals,
108                         releaseEnvironment,
109                         releaseDescriptor.isInteractive(),
110                         additionalArguments,
111                         pomFileName,
112                         result);
113             }
114         } catch (MavenExecutorException e) {
115             throw new ReleaseExecutionException(e.getMessage(), e);
116         }
117 
118         result.setResultCode(ReleaseResult.SUCCESS);
119 
120         return result;
121     }
122 
123     protected abstract String getGoals(ReleaseDescriptor releaseDescriptor);
124 
125     protected String getAdditionalArguments(ReleaseDescriptor releaseDescriptor) {
126         StringBuilder builder = new StringBuilder();
127 
128         if (releaseDescriptor.getAdditionalArguments() != null) {
129             builder.append(releaseDescriptor.getAdditionalArguments());
130         }
131 
132         if (!releaseDescriptor.getActivateProfiles().isEmpty()) {
133             builder.append(" -P ")
134                     .append(StringUtils.join(
135                             releaseDescriptor.getActivateProfiles().iterator(), ","));
136         }
137 
138         return builder.length() > 0 ? builder.toString().trim() : null;
139     }
140 
141     /**
142      * Determines the path of the working directory. By default, this is the
143      * checkout directory. For some SCMs, the project root directory is not the
144      * checkout directory itself, but a SCM-specific subdirectory.
145      *
146      * @param checkoutDirectory            The checkout directory as java.io.File
147      * @param relativePathProjectDirectory The relative path of the project directory within the checkout
148      *                                     directory or ""
149      * @return The working directory
150      */
151     protected File determineWorkingDirectory(File checkoutDirectory, String relativePathProjectDirectory) {
152         File workingDirectory = checkoutDirectory;
153 
154         if (relativePathProjectDirectory != null && !relativePathProjectDirectory.isEmpty()) {
155             workingDirectory = new File(checkoutDirectory, relativePathProjectDirectory);
156         }
157 
158         return workingDirectory;
159     }
160 }