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.cling.invoker.mvn.forked;
20  
21  import java.io.IOException;
22  import java.util.ArrayList;
23  import java.util.Collections;
24  import java.util.Map;
25  
26  import org.apache.maven.api.cli.Invoker;
27  import org.apache.maven.api.cli.InvokerException;
28  import org.apache.maven.api.cli.InvokerRequest;
29  import org.apache.maven.api.cli.mvn.MavenOptions;
30  import org.apache.maven.internal.impl.model.profile.Os;
31  
32  import static java.util.Objects.requireNonNull;
33  
34  /**
35   * Forked invoker implementation, that spawns a subprocess with Maven from the installation directory.
36   */
37  public class ForkedMavenInvoker implements Invoker {
38      @SuppressWarnings("MethodLength")
39      @Override
40      public int invoke(InvokerRequest invokerRequest) throws InvokerException {
41          requireNonNull(invokerRequest);
42          validate(invokerRequest);
43  
44          ArrayList<String> cmdAndArguments = new ArrayList<>();
45          cmdAndArguments.add(invokerRequest
46                  .installationDirectory()
47                  .resolve("bin")
48                  .resolve(
49                          Os.IS_WINDOWS
50                                  ? invokerRequest.parserRequest().command() + ".cmd"
51                                  : invokerRequest.parserRequest().command())
52                  .toString());
53  
54          MavenOptions mavenOptions = (MavenOptions) invokerRequest.options();
55          if (mavenOptions.userProperties().isPresent()) {
56              for (Map.Entry<String, String> entry :
57                      mavenOptions.userProperties().get().entrySet()) {
58                  cmdAndArguments.add("-D" + entry.getKey() + "=" + entry.getValue());
59              }
60          }
61          if (mavenOptions.showVersionAndExit().orElse(false)) {
62              cmdAndArguments.add("--version");
63          }
64          if (mavenOptions.showVersion().orElse(false)) {
65              cmdAndArguments.add("--show-version");
66          }
67          if (mavenOptions.quiet().orElse(false)) {
68              cmdAndArguments.add("--quiet");
69          }
70          if (mavenOptions.verbose().orElse(false)) {
71              cmdAndArguments.add("--verbose");
72          }
73          if (mavenOptions.showErrors().orElse(false)) {
74              cmdAndArguments.add("--errors");
75          }
76          if (mavenOptions.failOnSeverity().isPresent()) {
77              cmdAndArguments.add("--fail-on-severity");
78              cmdAndArguments.add(mavenOptions.failOnSeverity().get());
79          }
80          if (mavenOptions.nonInteractive().orElse(false)) {
81              cmdAndArguments.add("--non-interactive");
82          }
83          if (mavenOptions.forceInteractive().orElse(false)) {
84              cmdAndArguments.add("--force-interactive");
85          }
86          if (mavenOptions.altUserSettings().isPresent()) {
87              cmdAndArguments.add("--settings");
88              cmdAndArguments.add(mavenOptions.altUserSettings().get());
89          }
90          if (mavenOptions.altProjectSettings().isPresent()) {
91              cmdAndArguments.add("--project-settings");
92              cmdAndArguments.add(mavenOptions.altProjectSettings().get());
93          }
94          if (mavenOptions.altInstallationSettings().isPresent()) {
95              cmdAndArguments.add("--install-settings");
96              cmdAndArguments.add(mavenOptions.altInstallationSettings().get());
97          }
98          if (mavenOptions.altUserToolchains().isPresent()) {
99              cmdAndArguments.add("--toolchains");
100             cmdAndArguments.add(mavenOptions.altUserToolchains().get());
101         }
102         if (mavenOptions.altInstallationToolchains().isPresent()) {
103             cmdAndArguments.add("--install-toolchains");
104             cmdAndArguments.add(mavenOptions.altInstallationToolchains().get());
105         }
106         if (mavenOptions.logFile().isPresent()) {
107             cmdAndArguments.add("--log-file");
108             cmdAndArguments.add(mavenOptions.logFile().get());
109         }
110         if (mavenOptions.color().isPresent()) {
111             cmdAndArguments.add("--color");
112             cmdAndArguments.add(mavenOptions.color().get());
113         }
114         if (mavenOptions.help().orElse(false)) {
115             cmdAndArguments.add("--help");
116         }
117         if (mavenOptions.alternatePomFile().isPresent()) {
118             cmdAndArguments.add("--file");
119             cmdAndArguments.add(mavenOptions.alternatePomFile().get());
120         }
121         if (mavenOptions.offline().orElse(false)) {
122             cmdAndArguments.add("--offline");
123         }
124         if (mavenOptions.nonRecursive().orElse(false)) {
125             cmdAndArguments.add("--non-recursive");
126         }
127         if (mavenOptions.updateSnapshots().orElse(false)) {
128             cmdAndArguments.add("--update-snapshots");
129         }
130         if (mavenOptions.activatedProfiles().isPresent()) {
131             cmdAndArguments.add("--activate-profiles");
132             cmdAndArguments.add(
133                     String.join(",", mavenOptions.activatedProfiles().get()));
134         }
135         if (mavenOptions.suppressSnapshotUpdates().orElse(false)) {
136             cmdAndArguments.add("--no-snapshot-updates");
137         }
138         if (mavenOptions.strictChecksums().orElse(false)) {
139             cmdAndArguments.add("--strict-checksums");
140         }
141         if (mavenOptions.relaxedChecksums().orElse(false)) {
142             cmdAndArguments.add("--lax-checksums");
143         }
144         if (mavenOptions.failFast().orElse(false)) {
145             cmdAndArguments.add("--fail-fast");
146         }
147         if (mavenOptions.failAtEnd().orElse(false)) {
148             cmdAndArguments.add("--fail-at-end");
149         }
150         if (mavenOptions.failNever().orElse(false)) {
151             cmdAndArguments.add("--fail-never");
152         }
153         if (mavenOptions.resume().orElse(false)) {
154             cmdAndArguments.add("--resume");
155         }
156         if (mavenOptions.resumeFrom().isPresent()) {
157             cmdAndArguments.add("--resume-from");
158             cmdAndArguments.add(mavenOptions.resumeFrom().get());
159         }
160         if (mavenOptions.projects().isPresent()) {
161             cmdAndArguments.add("--projects");
162             cmdAndArguments.add(String.join(",", mavenOptions.projects().get()));
163         }
164         if (mavenOptions.alsoMake().orElse(false)) {
165             cmdAndArguments.add("--also-make");
166         }
167         if (mavenOptions.alsoMakeDependents().orElse(false)) {
168             cmdAndArguments.add("--also-make-dependents");
169         }
170         if (mavenOptions.threads().isPresent()) {
171             cmdAndArguments.add("--threads");
172             cmdAndArguments.add(mavenOptions.threads().get());
173         }
174         if (mavenOptions.builder().isPresent()) {
175             cmdAndArguments.add("--builder");
176             cmdAndArguments.add(mavenOptions.builder().get());
177         }
178         if (mavenOptions.noTransferProgress().orElse(false)) {
179             cmdAndArguments.add("--no-transfer-progress");
180         }
181         if (mavenOptions.cacheArtifactNotFound().isPresent()) {
182             cmdAndArguments.add("--cache-artifact-not-found");
183             cmdAndArguments.add(mavenOptions.cacheArtifactNotFound().get().toString());
184         }
185         if (mavenOptions.strictArtifactDescriptorPolicy().isPresent()) {
186             cmdAndArguments.add("--strict-artifact-descriptor-policy");
187             cmdAndArguments.add(
188                     mavenOptions.strictArtifactDescriptorPolicy().get().toString());
189         }
190         if (mavenOptions.ignoreTransitiveRepositories().isPresent()) {
191             cmdAndArguments.add("--ignore-transitive-repositories");
192         }
193 
194         // last the goals
195         cmdAndArguments.addAll(mavenOptions.goals().orElse(Collections.emptyList()));
196 
197         try {
198             ProcessBuilder pb = new ProcessBuilder()
199                     .directory(invokerRequest.cwd().toFile())
200                     .command(cmdAndArguments);
201 
202             if (invokerRequest.jvmArguments().isPresent()) {
203                 pb.environment()
204                         .put(
205                                 "MAVEN_OPTS",
206                                 String.join(" ", invokerRequest.jvmArguments().get()));
207             }
208 
209             return pb.start().waitFor();
210         } catch (IOException e) {
211             invokerRequest.logger().error("IO problem while executing command: " + cmdAndArguments, e);
212             return 127;
213         } catch (InterruptedException e) {
214             invokerRequest.logger().error("Interrupted while executing command: " + cmdAndArguments, e);
215             return 127;
216         }
217     }
218 
219     protected void validate(InvokerRequest invokerRequest) throws InvokerException {}
220 }